예제 #1
0
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);
    }
}
예제 #2
0
static inline void spawn(int locale, chpl_fn_int_t fid, void *arg, 
                                int32_t arg_size, int32_t arg_tid, aligned_t *ret)
{
    qthread_debug(CHAPEL_CALLS, "[%d] begin: locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size);

        spawn_wrapper_args_t *wargs;
    size_t const wargs_size = sizeof(spawn_wrapper_args_t) + arg_size;

    wargs = (spawn_wrapper_args_t *)chpl_mem_allocMany(1, wargs_size, CHPL_RT_MD_COMM_FORK_SEND_INFO, 0, 0);
        wargs->serial_state = chpl_task_getSerial();
    wargs->fid = fid;
    wargs->arg_size = arg_size;
    memcpy(&(wargs->arg), arg, arg_size);

    if (chpl_localeID == locale) {
        int const rc = qthread_fork_copyargs(spawn_wrapper, wargs, wargs_size, ret);
        assert(QTHREAD_SUCCESS == rc);
    } else {
        int const rc = qthread_fork_remote(spawn_wrapper, wargs, ret, locale, wargs_size);
        assert(SPR_OK == rc);
    }

    chpl_mem_free(wargs, 0, NULL);

    qthread_debug(CHAPEL_CALLS, "[%d] end: locale=%d, fid=%d, arg_size=%d\n", chpl_localeID, locale, fid, arg_size);
}
예제 #3
0
//
// Call a function in a task.
//
void chpl_task_taskCallFTable(chpl_fn_int_t fid,          // function to call
                              //void* arg,              // function arg
                              chpl_task_bundle_t* arg,// function arg
                              size_t arg_size,        // length of arg
                              c_sublocid_t subloc,       // desired sublocale
                              int lineno,                // line at which function begins
                              int32_t filename) {           // name of file containing function
  enter_();
  if (chpl_task_getSerial()) {
    chpl_ftable[fid](arg);
  } else {
    myth_chpl_create(/* serial_state = */ false,
                     /* is_executeOn = */ false,
                     lineno, filename, 
                     subloc, fid, get_next_task_id(), arg, arg_size);
  }
  return_from_();
}
예제 #4
0
//
// Launch a task that is the logical continuation of some other task,
// but on a different locale.  This is used to invoke the body of an
// "on" statement.
//
void chpl_task_startMovedTask(chpl_fn_int_t fid,          // function to call
                              chpl_fn_p fp,
                              //void* arg,              // function arg
                              chpl_task_bundle_t* arg,// function arg
                              size_t arg_size, // length of arg in bytes
                              c_sublocid_t subloc,       // desired sublocale
                              chpl_taskID_t id,      // task identifier
                              chpl_bool serial_state) {         // serial state
  enter_();
  if (chpl_task_getSerial()) {
    chpl_ftable[fid](arg);
  } else {
    myth_chpl_create(/* serial_state = */ false,
                     /* is_executeOn = */ true,
                     0, CHPL_FILE_IDX_UNKNOWN, 
                     subloc, fid, id, arg, arg_size);
  }
  return_from_();
}
예제 #5
0
//
// Task list processing.  These are called by the compiler-emitted
// code for all parallel constructs.  addToTaskList() is called for
// each task and builds a list of all of them.  processTaskList()
// actually adds the tasks to the task pool.  executeTasksInList()
// makes sure all the tasks have at least started.  freeTaskList()
// just reclaims space associated with the list.
//
void chpl_task_addToTaskList(
         chpl_fn_int_t fid,      // function to call for task
         //void* arg,              // argument to the function
         chpl_task_bundle_t* arg, size_t arg_size,
         c_sublocid_t subloc,       // desired sublocale
         void** p_task_list_void,             // task list
         c_nodeid_t task_list_locale,         // locale (node) where task list resides
         chpl_bool is_begin_stmt,          // is begin{} stmt?  (vs. cobegin or coforall)
         int lineno,                // line at which function begins
         int32_t filename) { // name of file containing function
  enter_();
  if (chpl_task_getSerial()) {
    chpl_ftable[fid](arg);
  } else {
    myth_chpl_create(/* serial_state = */ false,
                     /* is_executeOn = */ false,
                     lineno, filename, 
                     subloc, fid, get_next_task_id(), arg, arg_size);
  }
  return_from_();
}
예제 #6
0
void chpl_task_executeTasksInList(void** p_task_list_void) {
  task_pool_p* p_task_list_head = (task_pool_p*) p_task_list_void;
  task_pool_p curr_ptask;
  task_pool_p child_ptask;

  //
  // If we're serial, all the tasks have already been executed.
  //
  if (chpl_task_getSerial())
    return;

  curr_ptask = get_current_ptask();

  while (*p_task_list_head != NULL) {
    chpl_fn_p task_to_run_fun = NULL;

    // begin critical section
    chpl_thread_mutexLock(&threading_lock);

    if ((child_ptask = *p_task_list_head) != NULL) {
      task_to_run_fun = child_ptask->fun;
      dequeue_task(child_ptask);
    }

    // end critical section
    chpl_thread_mutexUnlock(&threading_lock);

    if (task_to_run_fun == NULL)
      continue;

    set_current_ptask(child_ptask);

    // begin critical section
    chpl_thread_mutexLock(&extra_task_lock);

    extra_task_cnt++;

    // end critical section
    chpl_thread_mutexUnlock(&extra_task_lock);

    if (do_taskReport) {
      chpl_thread_mutexLock(&taskTable_lock);
      chpldev_taskTable_set_suspended(curr_ptask->id);
      chpldev_taskTable_set_active(child_ptask->id);
      chpl_thread_mutexUnlock(&taskTable_lock);
    }

    if (blockreport)
      initializeLockReportForThread();

    chpl_task_do_callbacks(chpl_task_cb_event_kind_begin,
                           child_ptask->filename,
                           child_ptask->lineno,
                           child_ptask->id,
                           child_ptask->is_executeOn);

    (*task_to_run_fun)(child_ptask->arg);

    chpl_task_do_callbacks(chpl_task_cb_event_kind_end,
                           child_ptask->filename,
                           child_ptask->lineno,
                           child_ptask->id,
                           child_ptask->is_executeOn);

    if (do_taskReport) {
      chpl_thread_mutexLock(&taskTable_lock);
      chpldev_taskTable_set_active(curr_ptask->id);
      chpldev_taskTable_remove(child_ptask->id);
      chpl_thread_mutexUnlock(&taskTable_lock);
    }

    // begin critical section
    chpl_thread_mutexLock(&extra_task_lock);

    extra_task_cnt--;

    // end critical section
    chpl_thread_mutexUnlock(&extra_task_lock);

    set_current_ptask(curr_ptask);
    chpl_mem_free(child_ptask, 0, 0);

  }
}
예제 #7
0
    chpl_thread_setPrivateData(tp);

    (*comm_task_fn)(arg);
}


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,
                             c_string filename) {
    chpl_task_prvDataImpl_t chpl_data = {
        .prvdata = { .serial_state = chpl_task_getSerial() }
    };

    assert(subloc == 0 || subloc == c_sublocid_any);

    if (task_list_locale == chpl_nodeID) {
        chpl_task_list_p ltask;

        ltask = (chpl_task_list_p) chpl_mem_alloc(sizeof(struct chpl_task_list),
                CHPL_RT_MD_TASK_LIST_DESC,
                0, 0);
        ltask->filename = filename;
        ltask->lineno   = lineno;
        ltask->fun      = chpl_ftable[fid];
        ltask->arg      = arg;
        ltask->ptask    = NULL;