diff --git a/mtapi_c/include/embb/mtapi/c/mtapi.h b/mtapi_c/include/embb/mtapi/c/mtapi.h index 0de84bb..f007db7 100644 --- a/mtapi_c/include/embb/mtapi/c/mtapi.h +++ b/mtapi_c/include/embb/mtapi/c/mtapi.h @@ -552,8 +552,9 @@ enum mtapi_node_attributes_enum { the node */ MTAPI_NODE_MAX_ACTIONS_PER_JOB, /**< maximum number of actions in a job allowed by the node */ - MTAPI_NODE_MAX_PRIORITIES /**< maximum number of priorities + MTAPI_NODE_MAX_PRIORITIES, /**< maximum number of priorities allowed by the node */ + MTAPI_NODE_REUSE_MAIN_THREAD /**< reuse main thread as worker */ }; /** size of the \a MTAPI_NODE_CORE_AFFINITY attribute */ #define MTAPI_NODE_CORE_AFFINITY_SIZE sizeof(embb_core_set_t) @@ -577,6 +578,8 @@ enum mtapi_node_attributes_enum { #define MTAPI_NODE_MAX_ACTIONS_PER_JOB_SIZE sizeof(mtapi_uint_t) /** size of the \a MTAPI_NODE_MAX_PRIORITIES attribute */ #define MTAPI_NODE_MAX_PRIORITIES_SIZE sizeof(mtapi_uint_t) +/** size of the \a MTAPI_NODE_REUSE_MAIN_THREAD attribute */ +#define MTAPI_NODE_REUSE_MAIN_THREAD_SIZE sizeof(mtapi_boolean_t) /* example attribute value */ #define MTAPI_NODE_TYPE_SMP 1 @@ -688,6 +691,8 @@ struct mtapi_node_attributes_struct { mtapi_uint_t max_actions_per_job; /**< stores MTAPI_NODE_MAX_ACTIONS_PER_JOB */ mtapi_uint_t max_priorities; /**< stores MTAPI_NODE_MAX_PRIORITIES */ + mtapi_boolean_t reuse_main_thread; /**< stores + MTAPI_NODE_REUSE_MAIN_THREAD */ }; /** diff --git a/mtapi_c/src/embb_mtapi_thread_context_t.c b/mtapi_c/src/embb_mtapi_thread_context_t.c index 25ac8f3..e791824 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t.c +++ b/mtapi_c/src/embb_mtapi_thread_context_t.c @@ -54,6 +54,7 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize_with_node_worker_and_core( that->core_num = core_num; that->priorities = node->attributes.max_priorities; that->is_initialized = MTAPI_FALSE; + that->is_main_thread = (worker_index == 0) ? node->attributes.reuse_main_thread : MTAPI_FALSE; embb_atomic_store_int(&that->run, 0); that->queue = (embb_mtapi_task_queue_t**)embb_mtapi_alloc_allocate( @@ -121,17 +122,29 @@ mtapi_boolean_t embb_mtapi_thread_context_start( embb_core_set_add(&core_set, that->core_num); /* create thread */ - err = embb_thread_create(&that->thread, &core_set, worker_func, that); - if (EMBB_SUCCESS != err) { - embb_mtapi_log_error( - "embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not " - "create thread %d on core %d\n", that->worker_index, that->core_num); - return MTAPI_FALSE; - } - - /* wait for worker to come up */ - while (0 == embb_atomic_load_int(&that->run)) { - embb_thread_yield(); + if (that->is_main_thread) { + /* reuse main thread */ + that->thread = embb_thread_current(); + err = embb_tss_create(&that->tss_id); + if (EMBB_SUCCESS != err) { + /* report error to scheduler */ + embb_atomic_store_int(&that->run, -1); + return MTAPI_FALSE; + } + embb_tss_set(&(that->tss_id), that); + embb_atomic_store_int(&that->run, 1); + } else { + err = embb_thread_create(&that->thread, &core_set, worker_func, that); + if (EMBB_SUCCESS != err) { + embb_mtapi_log_error( + "embb_mtapi_ThreadContext_initializeWithNodeAndCoreNumber() could not " + "create thread %d on core %d\n", that->worker_index, that->core_num); + return MTAPI_FALSE; + } + /* wait for worker to come up */ + while (0 == embb_atomic_load_int(&that->run)) { + embb_thread_yield(); + } } if (0 < embb_atomic_load_int(&that->run)) { @@ -146,7 +159,9 @@ void embb_mtapi_thread_context_stop(embb_mtapi_thread_context_t* that) { if (0 < embb_atomic_load_int(&that->run)) { embb_atomic_store_int(&that->run, 0); embb_condition_notify_one(&that->work_available); - embb_thread_join(&(that->thread), &result); + if (MTAPI_FALSE == that->is_main_thread) { + embb_thread_join(&(that->thread), &result); + } } } @@ -158,6 +173,9 @@ void embb_mtapi_thread_context_finalize(embb_mtapi_thread_context_t* that) { embb_mtapi_log_trace("embb_mtapi_thread_context_finalize() called\n"); if (that->is_initialized) { + if (that->is_main_thread) { + embb_tss_delete(&that->tss_id); + } embb_condition_destroy(&that->work_available); embb_mutex_destroy(&that->work_available_mutex); } diff --git a/mtapi_c/src/embb_mtapi_thread_context_t.h b/mtapi_c/src/embb_mtapi_thread_context_t.h index 165a91e..a2ba731 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t.h +++ b/mtapi_c/src/embb_mtapi_thread_context_t.h @@ -68,6 +68,7 @@ struct embb_mtapi_thread_context_struct { embb_atomic_int run; mtapi_status_t status; mtapi_boolean_t is_initialized; + mtapi_boolean_t is_main_thread; }; #include diff --git a/mtapi_c/src/mtapi_node_attributes_t.c b/mtapi_c/src/mtapi_node_attributes_t.c index 18ed2c5..791bc37 100644 --- a/mtapi_c/src/mtapi_node_attributes_t.c +++ b/mtapi_c/src/mtapi_node_attributes_t.c @@ -52,6 +52,7 @@ void mtapi_nodeattr_init( 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; embb_core_set_init(&attributes->core_affinity, 1); attributes->num_cores = embb_core_set_count(&attributes->core_affinity); @@ -143,6 +144,11 @@ void mtapi_nodeattr_set( &attributes->max_priorities, attribute, attribute_size); break; + case MTAPI_NODE_REUSE_MAIN_THREAD: + local_status = embb_mtapi_attr_set_mtapi_boolean_t( + &attributes->reuse_main_thread, attribute, attribute_size); + break; + default: /* attribute unknown */ local_status = MTAPI_ERR_ATTR_NUM;