void chpl_task_stdModulesInitialized(void) { // // The task table is implemented in Chapel code in the modules, so // we can't use it, and thus can't support task reporting on ^C or // deadlock, until the other modules on which it depends have been // initialized and the supporting code here is set up. In this // function we're guaranteed that is true, because it is called only // after all the standard module initialization is complete. // // // Register this main task in the task table. // if (taskreport) { thread_private_data_t* tp = chpl_thread_getPrivateData(); chpldev_taskTable_add(tp->ptask->bundle.id, tp->ptask->bundle.lineno, tp->ptask->bundle.filename, (uint64_t) (intptr_t) tp->ptask); chpldev_taskTable_set_active(tp->ptask->bundle.id); chpl_thread_mutexInit(&taskTable_lock); } // // Now we can do task reporting if the user requested it. // do_taskReport = taskreport; }
// create a task from the given function pointer and arguments // and append it to the end of the task pool // assumes threading_lock has already been acquired! static inline task_pool_p add_to_task_pool(chpl_fn_p fp, void* a, chpl_bool is_executeOn, chpl_task_prvDataImpl_t chpl_data, task_pool_p* p_task_list_head, chpl_bool is_begin_stmt, int lineno, int32_t filename) { task_pool_p ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t), CHPL_RT_MD_TASK_POOL_DESC, 0, 0); ptask->id = get_next_task_id(); ptask->fun = fp; ptask->arg = a; ptask->is_executeOn = is_executeOn; ptask->chpl_data = chpl_data; ptask->filename = filename; ptask->lineno = lineno; ptask->p_list_head = NULL; ptask->next = NULL; enqueue_task(ptask, p_task_list_head); chpl_task_do_callbacks(chpl_task_cb_event_kind_create, ptask->filename, ptask->lineno, ptask->id, ptask->is_executeOn); if (do_taskReport) { chpl_thread_mutexLock(&taskTable_lock); chpldev_taskTable_add(ptask->id, ptask->lineno, ptask->filename, (uint64_t) (intptr_t) ptask); chpl_thread_mutexUnlock(&taskTable_lock); } // // If we now have more tasks than threads to run them on (taking // into account that the current parent of a structured parallel // construct can run at least one of that construct's children), // try to start another thread. // if (queued_task_cnt > idle_thread_cnt && (p_task_list_head == NULL || ptask->list_next != NULL || is_begin_stmt)) { maybe_add_thread(); } return ptask; }
// create a task from the given function pointer and arguments // and append it to the end of the task pool // assumes threading_lock has already been acquired! static inline task_pool_p add_to_task_pool(chpl_fn_int_t fid, chpl_fn_p fp, chpl_task_bundle_t* a, size_t a_size, chpl_bool serial_state, chpl_bool countRunningTasks, chpl_bool is_executeOn, task_pool_p* p_task_list_head, chpl_bool is_begin_stmt, int lineno, int32_t filename) { size_t payload_size; task_pool_p ptask; chpl_task_prvDataImpl_t pv; memset(&pv, 0, sizeof(pv)); assert(a_size >= sizeof(chpl_task_bundle_t)); payload_size = a_size - sizeof(chpl_task_bundle_t); ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t) + payload_size, CHPL_RT_MD_TASK_ARG_AND_POOL_DESC, lineno, filename); memcpy(&ptask->bundle, a, a_size); ptask->p_list_head = NULL; ptask->list_next = NULL; ptask->list_prev = NULL; ptask->next = NULL; ptask->prev = NULL; ptask->chpl_data = pv; ptask->bundle.serial_state = serial_state; ptask->bundle.countRunning = countRunningTasks; ptask->bundle.is_executeOn = is_executeOn; ptask->bundle.lineno = lineno; ptask->bundle.filename = filename; ptask->bundle.requestedSubloc = c_sublocid_any_val; ptask->bundle.requested_fid = fid; ptask->bundle.requested_fn = fp; ptask->bundle.id = get_next_task_id(); enqueue_task(ptask, p_task_list_head); chpl_task_do_callbacks(chpl_task_cb_event_kind_create, ptask->bundle.requested_fid, ptask->bundle.filename, ptask->bundle.lineno, ptask->bundle.id, ptask->bundle.is_executeOn); if (do_taskReport) { chpl_thread_mutexLock(&taskTable_lock); chpldev_taskTable_add(ptask->bundle.id, ptask->bundle.lineno, ptask->bundle.filename, (uint64_t) (intptr_t) ptask); chpl_thread_mutexUnlock(&taskTable_lock); } // // If we now have more tasks than threads to run them on (taking // into account that the current parent of a structured parallel // construct can run at least one of that construct's children), // try to start another thread. // if (queued_task_cnt > idle_thread_cnt && (p_task_list_head == NULL || ptask->list_next != NULL || is_begin_stmt)) { maybe_add_thread(); } return ptask; }