void chpl_sync_markAndSignalEmpty(chpl_sync_aux_t *s) // and unlock { PROFILE_INCR(profile_sync_markAndSignalEmpty, 1); qthread_syncvar_fill(&(s->signal_empty)); s->is_full = 0; chpl_sync_unlock(s); }
void chpl_sync_markAndSignalFull(chpl_sync_aux_t *s) // and unlock { PROFILE_INCR(profile_sync_markAndSignalFull, 1); qthread_syncvar_fill(&(s->signal_full)); s->is_full = 1; chpl_sync_unlock(s); }
// Sync variables void chpl_sync_lock(chpl_sync_aux_t *s) { aligned_t l; PROFILE_INCR(profile_sync_lock, 1); l = qthread_incr(&s->lockers_in, 1); while (l != s->lockers_out) SPINLOCK_BODY(); }
void chpl_task_yield(void) { PROFILE_INCR(profile_task_yield,1); if (qthread_shep() == NO_SHEPHERD) { sched_yield(); } else { qthread_yield(); } }
void chpl_comm_barrier(const char *msg) { qthread_debug(CHAPEL_CALLS, "[%d] begin: %s\n", chpl_localeID, msg); PROFILE_INCR(profile_comm_barrier,1); spr_locale_barrier(); qthread_debug(CHAPEL_CALLS, "[%d] end: %s\n", chpl_localeID, msg); }
void chpl_sync_initAux(chpl_sync_aux_t *s) { PROFILE_INCR(profile_sync_initAux, 1); s->lockers_in = 0; s->lockers_out = 0; s->is_full = 0; s->signal_empty = SYNCVAR_EMPTY_INITIALIZER; s->signal_full = SYNCVAR_EMPTY_INITIALIZER; }
chpl_bool chpl_sync_isFull(void *val_ptr, chpl_sync_aux_t *s, chpl_bool simple_sync_var) { PROFILE_INCR(profile_sync_isFull, 1); if(simple_sync_var) { return qthread_syncvar_status(&(s->signal_full)); } else { return s->is_full; } }
// // fast (non-forking) fork (i.e., run in handler) // // TODO: implement fast fork in progress thread void chpl_comm_fork_fast(int locale, chpl_fn_int_t fid, void *arg, int32_t arg_size, int32_t arg_tid) { PROFILE_INCR(profile_comm_fork_fast,1); PROFILE_BIN_INCR(profile_comm_fork_fast_size,arg_size); qthread_debug(CHAPEL_CALLS, "[%d] begin locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size); qthread_debug(CHAPEL_BEHAVIOR, "[%d] (fast) forking fn %d with arg-size %d\n", chpl_localeID, fid, arg_size); chpl_comm_fork(locale, fid, arg, arg_size, arg_tid); qthread_debug(CHAPEL_CALLS, "[%d] end locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size); }
// // non-blocking fork // void chpl_comm_fork_nb(int locale, chpl_fn_int_t fid, void *arg, int32_t arg_size, int32_t arg_tid) { PROFILE_INCR(profile_comm_fork_nb,1); PROFILE_BIN_INCR(profile_comm_fork_nb_size,arg_size); qthread_debug(CHAPEL_CALLS, "[%d] begin locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size); qthread_debug(CHAPEL_BEHAVIOR, "[%d] (non-blocking) forking fn %d with arg-size %d\n", chpl_localeID, fid, arg_size); spawn(locale, fid, arg, arg_size, arg_tid, NULL); qthread_debug(CHAPEL_CALLS, "[%d] end locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size); }
void chpl_sync_waitEmptyAndLock(chpl_sync_aux_t *s, int32_t lineno, chpl_string filename) { PROFILE_INCR(profile_sync_waitEmptyAndLock, 1); if (blockreport) { about_to_block(lineno, filename); } chpl_sync_lock(s); while (s->is_full != 0) { chpl_sync_unlock(s); qthread_syncvar_readFE(NULL, &(s->signal_empty)); chpl_sync_lock(s); } }
// // remote fork should launch a thread on locale that runs function f // passing it arg where the size of arg is stored in arg_size // notes: // multiple forks to the same locale should be handled concurrently // void chpl_comm_fork(int locale, chpl_fn_int_t fid, void *arg, int32_t arg_size, int32_t arg_tid) { aligned_t ret; PROFILE_INCR(profile_comm_fork,1); PROFILE_BIN_INCR(profile_comm_fork_size,arg_size); qthread_debug(CHAPEL_CALLS, "[%d] begin locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size); qthread_debug(CHAPEL_BEHAVIOR, "[%d] (blocking) forking fn %d with arg-size %d\n", chpl_localeID, fid, arg_size); qthread_empty(&ret); spawn(locale, fid, arg, arg_size, arg_tid, &ret); qthread_readFF(NULL, &ret); qthread_debug(CHAPEL_CALLS, "[%d] end locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size); }
// // get 'size' bytes of remote data at 'raddr' on locale 'locale' to // local data at 'addr' // notes: // address is arbitrary // size and locale are part of p // void chpl_comm_get(void *addr, int32_t locale, void* raddr, int32_t elemSize, int32_t typeIndex, int32_t len, int ln, chpl_string fn) { uint32_t const size = elemSize *len; PROFILE_INCR(profile_comm_get,1); PROFILE_BIN_INCR(profile_comm_get_msg_size,elemSize); qthread_debug(CHAPEL_CALLS, "[%d] begin addr=%p, locale=%d, raddr=%p, elemSize=%d, len=%d\n", chpl_localeID, addr, locale, raddr, elemSize, len); qthread_debug(CHAPEL_BEHAVIOR, "[%d] getting from (%d,%p) to %p of size %d\n", chpl_localeID, locale, raddr, addr, size); if (chpl_localeID == locale) { memcpy(addr, raddr, size); } else { int const rc = spr_get(addr, locale, raddr, size); assert(SPR_OK == rc); } qthread_debug(CHAPEL_CALLS, "[%d] end addr=%p, locale=%d, raddr=%p, elemSize=%d, len=%d\n", chpl_localeID, addr, locale, raddr, elemSize, len); }
void chpl_task_startMovedTask(chpl_fn_p fp, void *arg, c_sublocid_t subloc, chpl_taskID_t id, chpl_bool serial_state) { assert(subloc != c_sublocid_none); assert(id == chpl_nullTaskID); chpl_qthread_wrapper_args_t wrapper_args = {fp, arg, NULL, 0, canCountRunningTasks, {subloc, serial_state}}; PROFILE_INCR(profile_task_startMovedTask,1); 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_freeTaskList(chpl_task_list_p task_list) { PROFILE_INCR(profile_task_freeTaskList,1); }
void chpl_task_executeTasksInList(chpl_task_list_p task_list) { PROFILE_INCR(profile_task_executeTasksInList,1); }
void chpl_sync_destroyAux(chpl_sync_aux_t *s) { PROFILE_INCR(profile_sync_destroyAux, 1); }
void chpl_task_yield(void) { PROFILE_INCR(profile_task_yield,1); qthread_yield(); }
// Returns '(unsigned int)-1' if called outside of the tasking layer. chpl_taskID_t chpl_task_getId(void) { PROFILE_INCR(profile_task_getId,1); return (chpl_taskID_t)qthread_id(); }
size_t chpl_task_getCallStackSize(void) { PROFILE_INCR(profile_task_getCallStackSize,1); return qthread_readstate(STACK_SIZE); }
void chpl_sync_unlock(chpl_sync_aux_t *s) { PROFILE_INCR(profile_sync_unlock, 1); qthread_incr(&s->lockers_out, 1); }