in source/windows/thread.c [228:339]
int aws_thread_launch(
struct aws_thread *thread,
void (*func)(void *arg),
void *arg,
const struct aws_thread_options *options) {
SIZE_T stack_size = 0;
if (options && options->stack_size > 0) {
stack_size = (SIZE_T)options->stack_size;
}
bool is_managed_thread = options != NULL && options->join_strategy == AWS_TJS_MANAGED;
if (is_managed_thread) {
thread->detach_state = AWS_THREAD_MANAGED;
}
struct thread_wrapper *thread_wrapper =
(struct thread_wrapper *)aws_mem_calloc(thread->allocator, 1, sizeof(struct thread_wrapper));
thread_wrapper->allocator = thread->allocator;
thread_wrapper->arg = arg;
thread_wrapper->func = func;
thread_wrapper->thread_copy = *thread;
/*
* Increment the count prior to spawning the thread. Decrement back if the create failed.
*/
if (is_managed_thread) {
aws_thread_increment_unjoined_count();
}
thread->thread_handle =
CreateThread(0, stack_size, thread_wrapper_fn, (LPVOID)thread_wrapper, 0, &thread->thread_id);
if (!thread->thread_handle) {
aws_thread_decrement_unjoined_count();
return aws_raise_error(AWS_ERROR_THREAD_INSUFFICIENT_RESOURCE);
}
if (options && options->cpu_id >= 0) {
AWS_LOGF_INFO(
AWS_LS_COMMON_THREAD,
"id=%p: cpu affinity of cpu_id %" PRIi32 " was specified, attempting to honor the value.",
(void *)thread,
options->cpu_id);
uint16_t group = 0;
uint8_t proc_num = 0;
s_get_group_and_cpu_id(options->cpu_id, &group, &proc_num);
GROUP_AFFINITY group_afinity;
AWS_ZERO_STRUCT(group_afinity);
group_afinity.Group = (WORD)group;
group_afinity.Mask = (KAFFINITY)((uint64_t)1 << proc_num);
AWS_LOGF_DEBUG(
AWS_LS_COMMON_THREAD,
"id=%p: computed mask %" PRIx64 " on group %" PRIu16 ".",
(void *)thread,
(uint64_t)group_afinity.Mask,
(uint16_t)group_afinity.Group);
/* Check for functions that don't exist on ancient Windows */
aws_thread_call_once(&s_check_functions_once, s_check_thread_ideal_processor_function, NULL);
if (!s_SetThreadGroupAffinity || !s_SetThreadIdealProcessorEx) {
goto no_thread_affinity;
}
BOOL set_group_val = s_SetThreadGroupAffinity(thread->thread_handle, &group_afinity, NULL);
AWS_LOGF_DEBUG(
AWS_LS_COMMON_THREAD,
"id=%p: SetThreadGroupAffinity() result %" PRIi8 ".",
(void *)thread,
(int8_t)set_group_val);
if (set_group_val) {
PROCESSOR_NUMBER processor_number;
AWS_ZERO_STRUCT(processor_number);
processor_number.Group = (WORD)group;
processor_number.Number = proc_num;
BOOL set_processor_val = s_SetThreadIdealProcessorEx(thread->thread_handle, &processor_number, NULL);
AWS_LOGF_DEBUG(
AWS_LS_COMMON_THREAD,
"id=%p: SetThreadIdealProcessorEx() result %" PRIi8 ".",
(void *)thread,
(int8_t)set_processor_val);
if (!set_processor_val) {
AWS_LOGF_WARN(
AWS_LS_COMMON_THREAD,
"id=%p: SetThreadIdealProcessorEx() failed with %" PRIx32 ".",
(void *)thread,
(uint32_t)GetLastError());
}
} else {
AWS_LOGF_WARN(
AWS_LS_COMMON_THREAD,
"id=%p: SetThreadGroupAffinity() failed with %" PRIx32 ".",
(void *)thread,
(uint32_t)GetLastError());
}
}
no_thread_affinity:
/*
* Managed threads need to stay unjoinable from an external perspective. We'll handle it after thread function
* completion.
*/
if (is_managed_thread) {
aws_thread_clean_up(thread);
} else {
thread->detach_state = AWS_THREAD_JOINABLE;
}
return AWS_OP_SUCCESS;
}