void thread_func(void *arg) { thread_arg_t *t_arg = (thread_arg_t *)arg; ABT_thread_yield(); ABT_mutex_lock(t_arg->mutex); g_counter++; ABT_mutex_unlock(t_arg->mutex); ABT_test_printf(1, "[TH%d] increased\n", t_arg->id); ABT_thread_yield(); }
/* Function to compute Fibonacci numbers */ void fibonacci_task(void *arguments) { int n, result; task_args *a1, *a2, *parent, *temp; ABT_task t1, t2; task_args *args = (task_args *)arguments; n = args->n; parent = args->parent; /* checking for base cases */ if (n <= 2) { args->result = 1; result = 1; int flag = 1; while (flag && parent != NULL) { ABT_mutex_lock(parent->mutex); parent->result += result; if (result == parent->result) flag = 0; ABT_mutex_unlock(parent->mutex); result = parent->result; temp = parent->parent; if (flag && temp) { ABT_mutex_free(&parent->mutex); free(parent); } parent = temp; } ABT_mutex_free(&args->mutex); if (args->parent) { free(args); } } else { a1 = (task_args *)malloc(sizeof(task_args)); a1->n = n - 1; a1->result = 0; ABT_mutex_create(&a1->mutex); a1->parent = args; ABT_task_create(g_pool, fibonacci_task, a1, &t1); a2 = (task_args *)malloc(sizeof(task_args)); a2->n = n - 2; a2->result = 0; ABT_mutex_create(&a2->mutex); a2->parent = args; ABT_task_create(g_pool, fibonacci_task, a2, &t2); } }
/* Daemon ULT for processing RPC replies */ void rdb_recvd(void *arg) { struct rdb *db = arg; D_DEBUG(DB_MD, DF_DB": recvd starting\n", DP_DB(db)); for (;;) { struct rdb_raft_rpc *rrpc = NULL; bool stop; ABT_mutex_lock(db->d_mutex); for (;;) { stop = db->d_stop; if (!d_list_empty(&db->d_replies)) { rrpc = d_list_entry(db->d_replies.next, struct rdb_raft_rpc, drc_entry); d_list_del_init(&rrpc->drc_entry); break; } if (stop) break; ABT_cond_wait(db->d_replies_cv, db->d_mutex); } ABT_mutex_unlock(db->d_mutex); if (rrpc == NULL) { D_ASSERT(stop); /* The queue is empty and we are asked to stop. */ break; } /* * The queue has pending replies. If we are asked to stop, skip * the processing but still free the RPCs until the queue * become empty. */ if (!stop) rdb_raft_process_reply(db, rrpc->drc_rpc); rdb_raft_free_request(db, rrpc->drc_rpc); rdb_free_raft_rpc(rrpc); ABT_thread_yield(); }
void rt1_finalize(void) { int i; while (rt1_data->num_xstreams > 0) { ABT_thread_yield(); } for (i = 0; i < rt1_data->max_xstreams; i++) { assert(rt1_data->xstreams[i] == ABT_XSTREAM_NULL); } /* Delete registered callbacks */ ABT_event_del_callback(ABT_EVENT_STOP_XSTREAM, rt1_data->stop_cb_id); ABT_event_del_callback(ABT_EVENT_ADD_XSTREAM, rt1_data->add_cb_id); ABT_mutex_lock(rt1_data->mutex); ABT_mutex_free(&rt1_data->mutex); ABT_barrier_free(&rt1_data->bar); free(rt1_data->xstreams); free(rt1_data->app_data); free(rt1_data); rt1_data = NULL; }
void rt1_launcher(void *arg) { int idx = (int)(intptr_t)arg; ABT_thread cur_thread; ABT_pool cur_pool; ABT_sched_config config; ABT_sched sched; size_t size; double t_start, t_end; ABT_sched_config_var cv_event_freq = { .idx = 0, .type = ABT_SCHED_CONFIG_INT }; ABT_sched_config_var cv_idx = { .idx = 1, .type = ABT_SCHED_CONFIG_INT }; ABT_sched_def sched_def = { .type = ABT_SCHED_TYPE_ULT, .init = sched_init, .run = sched_run, .free = sched_free, .get_migr_pool = NULL }; /* Create a scheduler */ ABT_sched_config_create(&config, cv_event_freq, 10, cv_idx, idx, ABT_sched_config_var_end); ABT_sched_create(&sched_def, 1, &rt1_data->pool, config, &sched); /* Push the scheduler to the current pool */ ABT_thread_self(&cur_thread); ABT_thread_get_last_pool(cur_thread, &cur_pool); ABT_pool_add_sched(cur_pool, sched); /* Free */ ABT_sched_config_free(&config); t_start = ABT_get_wtime(); while (1) { rt1_app(idx); ABT_pool_get_total_size(cur_pool, &size); if (size == 0) { ABT_sched_free(&sched); int rank; ABT_xstream_self_rank(&rank); printf("ES%d: finished\n", rank); ABT_mutex_lock(rt1_data->mutex); rt1_data->xstreams[rank] = ABT_XSTREAM_NULL; rt1_data->num_xstreams--; ABT_mutex_unlock(rt1_data->mutex); break; } t_end = ABT_get_wtime(); if ((t_end - t_start) > g_timeout) { ABT_sched_finish(sched); } } } static void rt1_app(int eid) { int i, num_comps; size_t size; ABT_thread cur_thread; ABT_pool cur_pool; ABT_thread_self(&cur_thread); ABT_thread_get_last_pool(cur_thread, &cur_pool); if (eid == 0) ABT_event_prof_start(); num_comps = rt1_data->num_comps; for (i = 0; i < num_comps * 2; i += 2) { ABT_thread_create(rt1_data->pool, rt1_app_compute, (void *)(intptr_t)(eid * num_comps * 2 + i), ABT_THREAD_ATTR_NULL, NULL); ABT_task_create(rt1_data->pool, rt1_app_compute, (void *)(intptr_t)(eid * num_comps * 2 + i + 1), NULL); } do { ABT_thread_yield(); /* If the size of cur_pool is zero, it means the stacked scheduler has * been terminated because of the shrinking event. */ ABT_pool_get_total_size(cur_pool, &size); if (size == 0) break; ABT_pool_get_total_size(rt1_data->pool, &size); } while (size > 0); if (eid == 0) { ABT_event_prof_stop(); int cnt = __atomic_exchange_n(&rt1_data->cnt, 0, __ATOMIC_SEQ_CST); double local_work = (double)(cnt * rt1_data->num_iters); ABT_event_prof_publish("ops", local_work, local_work); } } static void rt1_app_compute(void *arg) { int pos = (int)(intptr_t)arg; int i; rt1_data->app_data[pos] = 0; for (i = 0; i < rt1_data->num_iters; i++) { rt1_data->app_data[pos] += sin((double)pos); } __atomic_fetch_add(&rt1_data->cnt, 1, __ATOMIC_SEQ_CST); }
GLT_func_prefix void glt_mutex_lock(GLT_mutex mutex) { CHECK(ABT_mutex_lock(mutex),ABT_SUCCESS); }