// 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); }
int main(int argc, char *argv[]) { aligned_t tmp, ret = 0; int retval; long foobar = 1234567890; qthread_f funcs[2] = { returner, NULL }; CHECK_VERBOSE(); retval = spr_init(SPR_SPMD, funcs); if (retval != SPR_OK) { fprintf(stderr, "(%03d) spr_init returned %d\n", 0, retval); return -1; } my_id = spr_locale_id(); world_size = spr_num_locales(); iprintf("(%03d) Rank %d of %d is alive\n", my_id, my_id, world_size); spr_unify(); if (my_id != 0) { return -2; } int target = (world_size > 1) ? 1 : 0; retval = qthread_fork_remote(returner, &foobar, &ret, target, sizeof(long)); if (retval != 0) { fprintf(stderr, "(%03d) fork_remote returned %d\n", my_id, retval); return -3; } retval = qthread_readFE(&tmp, &ret); iprintf("(%03d) returner returned %ld\n", my_id, (long)tmp); if (retval != 0) { fprintf(stderr, "(%03d) readFE returned %d (%d)\n", my_id, retval, (int)tmp); return -4; } spr_fini(); return (tmp == foobar) ? 0 : 5; }
// 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); }
// // Do exit processing that has to occur before the tasking layer is // shut down. "The "all" parameter is true for normal, collective // program termination, and false for that done by a single locale // due to error or a user program halt or exit. // // Note: Chapel's program termination is not yet fully thought out. // void chpl_comm_pre_task_exit(int all) { qthread_debug(CHAPEL_CALLS, "[%d] begin all=%d\n", chpl_localeID, all); if (all) { if (0 != chpl_localeID) { qthread_debug(CHAPEL_BEHAVIOR, "[%d] calling spr_unify()\n", chpl_localeID); int const rc = spr_unify(); assert(SPR_OK == rc); } else { qthread_debug(CHAPEL_BEHAVIOR, "[%d] initiating locale shutdown\n", chpl_localeID); } } #ifdef CHAPEL_PROFILE profile_print(); #endif /* CHAPEL_PROFILE */ qthread_debug(CHAPEL_BEHAVIOR, "[%d] locale shutting down\n", chpl_localeID); qthread_debug(CHAPEL_CALLS, "[%d] end all=%d\n", chpl_localeID, all); }