void chpl_task_addToTaskList(chpl_fn_int_t fid, void *arg, c_sublocid_t subloc, chpl_task_list_p *task_list, int32_t task_list_locale, chpl_bool is_begin_stmt, int lineno, chpl_string filename) { qthread_shepherd_id_t const here_shep_id = qthread_shep(); chpl_bool serial_state = chpl_task_getSerial(); chpl_qthread_wrapper_args_t wrapper_args = {chpl_ftable[fid], arg, filename, lineno, false, {subloc, serial_state}}; assert(subloc != c_sublocid_none); PROFILE_INCR(profile_task_addToTaskList,1); if (serial_state) { syncvar_t ret = SYNCVAR_STATIC_EMPTY_INITIALIZER; qthread_fork_syncvar_copyargs_to(chapel_wrapper, &wrapper_args, sizeof(chpl_qthread_wrapper_args_t), &ret, here_shep_id); qthread_syncvar_readFF(NULL, &ret); } else if (subloc == c_sublocid_any) { qthread_fork_copyargs(chapel_wrapper, &wrapper_args, sizeof(chpl_qthread_wrapper_args_t), NULL); } else { qthread_fork_copyargs_to(chapel_wrapper, &wrapper_args, sizeof(chpl_qthread_wrapper_args_t), NULL, (qthread_shepherd_id_t) subloc); } }
void chpl_task_addToTaskList(chpl_fn_int_t fid, void *arg, c_sublocid_t subLoc, chpl_task_list_p *task_list, int32_t task_list_locale, chpl_bool is_begin_stmt, int lineno, chpl_string filename) { qthread_shepherd_id_t const here_shep_id = qthread_shep(); chpl_task_private_data_t *parent_chpl_data = chpl_task_getPrivateData(); chpl_bool serial_state = parent_chpl_data->serial_state; chapel_wrapper_args_t wrapper_args = {chpl_ftable[fid], arg, filename, lineno, *parent_chpl_data}; PROFILE_INCR(profile_task_addToTaskList,1); if (serial_state) { syncvar_t ret = SYNCVAR_STATIC_EMPTY_INITIALIZER; qthread_fork_syncvar_copyargs_to(chapel_wrapper, &wrapper_args, sizeof(chapel_wrapper_args_t), &ret, here_shep_id); qthread_syncvar_readFF(NULL, &ret); } else if (subLoc == c_sublocid_any) { qthread_fork_syncvar_copyargs(chapel_wrapper, &wrapper_args, sizeof(chapel_wrapper_args_t), NULL); } else { if (subLoc == c_sublocid_curr) subLoc = (c_sublocid_t) here_shep_id; qthread_fork_syncvar_copyargs_to(chapel_wrapper, &wrapper_args, sizeof(chapel_wrapper_args_t), NULL, (qthread_shepherd_id_t) subLoc); } }
// Start the main task. // // Warning: this method is not called within a Qthread task context. Do // not use methods that require task context (e.g., task-local storage). void chpl_task_callMain(void (*chpl_main)(void)) { const chpl_bool initial_serial_state = false; const c_localeid_t initial_locale_id = default_locale_id; const chapel_wrapper_args_t wrapper_args = {chpl_main, NULL, NULL, 0, {initial_serial_state, initial_locale_id, NULL, chpl_malloc, chpl_calloc, chpl_realloc, chpl_free}}; qthread_debug(CHAPEL_CALLS, "[%d] begin chpl_task_callMain()\n", chpl_localeID); default_serial_state = initial_serial_state; #ifdef QTHREAD_MULTINODE qthread_debug(CHAPEL_BEHAVIOR, "[%d] calling spr_unify\n", chpl_localeID); int const rc = spr_unify(); assert(SPR_OK == rc); #endif /* QTHREAD_MULTINODE */ qthread_fork_syncvar(chapel_wrapper, &wrapper_args, &exit_ret); qthread_syncvar_readFF(NULL, &exit_ret); qthread_debug(CHAPEL_BEHAVIOR, "[%d] main task finished\n", chpl_localeID); qthread_debug(CHAPEL_CALLS, "[%d] end chpl_task_callMain()\n", chpl_localeID); }
static void *initializer(void *junk) { qthread_initialize(); MACHINE_FENCE; chpl_qthread_done_initializing = 1; qthread_syncvar_readFF(NULL, &canexit); qthread_finalize(); MACHINE_FENCE; done_finalizing = 1; return NULL; }
static void *initializer(void *junk) { qthread_initialize(); (void) pthread_mutex_lock(&done_init_final_mux); // implicit memory fence chpl_qthread_done_initializing = 1; (void) pthread_mutex_unlock(&done_init_final_mux); qthread_syncvar_readFF(NULL, &canexit); qthread_finalize(); (void) pthread_mutex_lock(&done_init_final_mux); // implicit memory fence done_finalizing = 1; (void) pthread_mutex_unlock(&done_init_final_mux); return NULL; }
// Start the main task. // // Warning: this method is not called within a Qthread task context. Do // not use methods that require task context (e.g., task-local storage). void chpl_task_callMain(void (*chpl_main)(void)) { const chpl_qthread_wrapper_args_t wrapper_args = {chpl_main, NULL, NULL, 0, false, {c_sublocid_any_val, false}}; qthread_debug(CHAPEL_CALLS, "[%d] begin chpl_task_callMain()\n", chpl_localeID); #ifdef QTHREAD_MULTINODE qthread_debug(CHAPEL_BEHAVIOR, "[%d] calling spr_unify\n", chpl_localeID); int const rc = spr_unify(); assert(SPR_OK == rc); #endif /* QTHREAD_MULTINODE */ qthread_fork_syncvar(chapel_wrapper, &wrapper_args, &exit_ret); qthread_syncvar_readFF(NULL, &exit_ret); qthread_debug(CHAPEL_BEHAVIOR, "[%d] main task finished\n", chpl_localeID); qthread_debug(CHAPEL_CALLS, "[%d] end chpl_task_callMain()\n", chpl_localeID); }
int main(int argc, char *argv[]) { aligned_t *t[2]; uint64_t x_value; uint64_t pairs; assert(qthread_initialize() == 0); pairs = qthread_num_shepherds() * 6; CHECK_VERBOSE(); NUMARG(iterations, "ITERATIONS"); NUMARG(pairs, "PAIRS"); t[0] = calloc(pairs, sizeof(aligned_t)); t[1] = calloc(pairs, sizeof(aligned_t)); iprintf("%i threads...\n", qthread_num_shepherds()); iprintf("Initial value of x: %lu\n", (unsigned long)x.u.w); qthread_syncvar_empty(&id); qthread_syncvar_writeF_const(&id, 1); iprintf("id = 0x%lx\n", (unsigned long)id.u.w); { uint64_t tmp = 0; qthread_syncvar_readFF(&tmp, &id); assert(tmp == 1); } iprintf("x's status is: %s (want full (and nowait))\n", qthread_syncvar_status(&x) ? "full" : "empty"); assert(qthread_syncvar_status(&x) == 1); qthread_syncvar_readFE(NULL, &x); iprintf("x's status became: %s (want empty (and nowait))\n", qthread_syncvar_status(&x) ? "full" : "empty"); assert(qthread_syncvar_status(&x) == 0); for (unsigned int i = 0; i < pairs; ++i) { qthread_fork(consumer, (void *)(uintptr_t)i, &(t[0][i])); } for (unsigned int i = 0; i < pairs; ++i) { qthread_fork(producer, (void *)(uintptr_t)(i + pairs), &(t[1][i])); } for (unsigned int i = 0; i < pairs; ++i) { qthread_readFF(NULL, &(t[0][i])); qthread_readFF(NULL, &(t[1][i])); } iprintf("shouldn't be blocking on x (current status: %s)\n", qthread_syncvar_status(&x) ? "full" : "empty"); qthread_syncvar_fill(&x); iprintf("shouldn't be blocking on x (current status: %s)\n", qthread_syncvar_status(&x) ? "full" : "empty"); qthread_syncvar_readFF(&x_value, &x); assert(qthread_syncvar_status(&x) == 1); free(t[0]); free(t[1]); if (x_value == iterations - 1) { iprintf("Success! x==%lu\n", (unsigned long)x_value); return 0; } else { fprintf(stderr, "Final value of x=%lu, expected %lu\n", (unsigned long)x_value, (unsigned long)(iterations - 1)); return -1; } }