void embb_core_set_init(embb_core_set_t* core_set, int initializer) { assert(core_set != NULL); assert(embb_core_count_available() < 64 && "Core sets are only supported up to 64 processors!"); /* Cache windows processor grouping information */ if (processor_info.group_count == 0) { /* Set relation group */ LOGICAL_PROCESSOR_RELATIONSHIP rel = (LOGICAL_PROCESSOR_RELATIONSHIP)4; /* Assume only one element of SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX is returned to the buffer. */ SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX buffer; /* The length is that of the buffer */ DWORD length = sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX); BOOL status = GetLogicalProcessorInformationEx(rel, &buffer, &length); assert(status == TRUE); EMBB_UNUSED_IN_RELEASE(status); processor_info.group_count = buffer.Group.ActiveGroupCount; for (unsigned short i = 0; i < processor_info.group_count; i++) { processor_info.processor_counts[i] = (unsigned short)(buffer.Group.GroupInfo[i].ActiveProcessorCount); } } if (initializer == 0) { embb_bitset_clear_all(&core_set->rep); } else { embb_bitset_set_n(&core_set->rep, embb_core_count_available()); } }
void embb_core_set_init(embb_core_set_t* core_set, int initializer) { assert(core_set != NULL); assert(embb_core_count_available() < 64 && "Core sets are only supported up to 64 processors!"); if (initializer == 0) { embb_bitset_clear_all(&core_set->rep); } else { embb_bitset_set_n(&core_set->rep, embb_core_count_available()); } }
void mtapi_nodeattr_init( MTAPI_OUT mtapi_node_attributes_t* attributes, MTAPI_OUT mtapi_status_t* status) { mtapi_status_t local_status = MTAPI_ERR_UNKNOWN; embb_mtapi_log_trace("mtapi_nodeattr_init() called\n"); if (MTAPI_NULL != attributes) { attributes->max_tasks = MTAPI_NODE_MAX_TASKS_DEFAULT; attributes->type = MTAPI_NODE_TYPE_SMP; attributes->max_actions = MTAPI_NODE_MAX_ACTIONS_DEFAULT; attributes->max_groups = MTAPI_NODE_MAX_GROUPS_DEFAULT; attributes->max_queues = MTAPI_NODE_MAX_QUEUES_DEFAULT; attributes->queue_limit = MTAPI_NODE_QUEUE_LIMIT_DEFAULT; attributes->max_jobs = MTAPI_NODE_MAX_JOBS_DEFAULT; attributes->max_actions_per_job = MTAPI_NODE_MAX_ACTIONS_PER_JOB_DEFAULT; attributes->max_priorities = MTAPI_NODE_MAX_PRIORITIES_DEFAULT; attributes->reuse_main_thread = MTAPI_FALSE; attributes->worker_priorities = NULL; embb_core_set_init(&attributes->core_affinity, 1); attributes->num_cores = embb_core_set_count(&attributes->core_affinity); assert(embb_core_set_count(&attributes->core_affinity) == embb_core_count_available()); local_status = MTAPI_SUCCESS; } else { local_status = MTAPI_ERR_PARAMETER; } mtapi_status_set(status, local_status); }
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, embb_thread_start_t func, void* arg) { pthread_attr_t attr; /* Used to set thread affinities */ int status = pthread_attr_init(&attr); if (status != 0) return EMBB_ERROR; if (core_set != NULL) { #if defined(EMBB_PLATFORM_HAS_GLIB_CPU) || \ defined(EMBB_PLATFORM_HAS_HEADER_CPUSET) assert(embb_core_count_available() < CPU_SETSIZE && "Core sets are only supported up to CPU_SETSIZE processors!"); #ifdef EMBB_PLATFORM_HAS_GLIB_CPU cpu_set_t cpuset; #else cpuset_t cpuset; #endif CPU_ZERO(&cpuset); /* Disable all processors */ for (unsigned int i = 0; i < embb_core_count_available(); i++) { if (embb_core_set_contains(core_set, i)) { CPU_SET(i, &cpuset); } } status = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset); if (status != 0) return EMBB_ERROR; #else embb_log_write("base_c", EMBB_LOG_LEVEL_WARNING, "Could not set thread " "affinity, since no implementation available!\n"); #endif } /* Dynamic allocation of thread arguments. Freed on call of join. */ thread->embb_internal_arg = (embb_internal_thread_arg_t*) embb_alloc(sizeof(embb_internal_thread_arg_t)); thread->embb_internal_arg->func = func; thread->embb_internal_arg->arg = arg; status = pthread_create( &(thread->embb_internal_handle), /* pthread handle */ &attr, /* additional attributes, e.g., affinities */ embb_internal_thread_start, /* thread start function */ (void*)(thread->embb_internal_arg)); /* arguments to thread start func. */ if (status != 0) return EMBB_ERROR; status = pthread_attr_destroy(&attr); if (status != 0) return EMBB_ERROR; return EMBB_SUCCESS; }
unsigned int* embb_max_number_thread_indices() { int compare_to = 0; if (embb_atomic_load_int(&embb_max_number_thread_indices_flag) != 2) { if (embb_atomic_compare_and_swap_int( &embb_max_number_thread_indices_flag, &compare_to, 1)) { embb_max_number_thread_indices_max = (int)(embb_core_count_available() * 2); embb_atomic_store_int(&embb_max_number_thread_indices_flag, 2); } while (embb_atomic_load_int(&embb_max_number_thread_indices_flag) != 2) {} } return (unsigned int*) &embb_max_number_thread_indices_max; }
int embb_thread_create(embb_thread_t* thread, const embb_core_set_t* core_set, embb_thread_start_t func, void *arg) { assert(thread != NULL); thread->embb_internal_arg = (embb_internal_thread_arg_t*) embb_alloc(sizeof(embb_internal_thread_arg_t)); if (thread->embb_internal_arg == NULL) return EMBB_NOMEM; thread->embb_internal_arg->func = func; thread->embb_internal_arg->arg = arg; thread->embb_internal_handle = CreateThread( 0, /* no security */ 0, /* default stack size */ embb_internal_thread_start, /* entry function */ (LPVOID)thread->embb_internal_arg, /* parameters */ 0, /* no creation arguments */ 0); /* no system thread ID */ if (thread->embb_internal_handle == NULL) { return EMBB_ERROR; } if (core_set != NULL) { /* Set thread affinity, if a core set is given */ DWORD_PTR core_mask = 0; DWORD bit_mask = 1; assert(embb_core_count_available() < 64); for (unsigned int i = 0; i < embb_core_count_available(); i++) { if (embb_core_set_contains(core_set, i)) { core_mask |= bit_mask; } bit_mask <<= 1; } if (SetThreadAffinityMask(thread->embb_internal_handle, core_mask) == (DWORD_PTR)NULL) { return EMBB_ERROR; } } return EMBB_SUCCESS; }
int embb_core_set_contains(const embb_core_set_t* core_set, unsigned int core_number) { assert(core_set != NULL); assert(core_number < embb_core_count_available()); return (int)(embb_bitset_is_set(&core_set->rep, core_number)); }
void embb_core_set_remove(embb_core_set_t* core_set, unsigned int core_number) { assert(core_set != NULL); assert(core_number < embb_core_count_available()); embb_bitset_clear(&core_set->rep, core_number); }