コード例 #1
0
ファイル: tasks-fifo.c プロジェクト: ct-clmsn/chapel
static void comm_task_wrapper(void* arg) {
  thread_private_data_t* tp;

  tp = (thread_private_data_t*) chpl_mem_alloc(sizeof(thread_private_data_t),
                                               CHPL_RT_MD_THREAD_PRV_DATA,
                                               0, 0);

  tp->ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t),
                                           CHPL_RT_MD_TASK_POOL_DESC,
                                           0, 0);
  tp->ptask->id           = get_next_task_id();
  tp->ptask->fun          = comm_task_fn;
  tp->ptask->arg          = arg;
  tp->ptask->is_executeOn = false;
  tp->ptask->filename     = CHPL_FILE_IDX_COMM_TASK;
  tp->ptask->lineno       = 0;
  tp->ptask->p_list_head  = NULL;
  tp->ptask->next         = NULL;

  //
  // The comm (polling) task shouldn't really need this information.
  //
  tp->ptask->chpl_data.prvdata.serial_state = true;

  tp->lockRprt = NULL;

  chpl_thread_setPrivateData(tp);

  (*comm_task_fn)(arg);
}
コード例 #2
0
ファイル: tasks-fifo.c プロジェクト: jcazzie/chapel
static void comm_task_wrapper(void* arg) {
  thread_private_data_t* tp;

  tp = (thread_private_data_t*) chpl_mem_alloc(sizeof(thread_private_data_t),
                                               CHPL_RT_MD_THREAD_PRV_DATA,
                                               0, 0);

  tp->ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t),
                                           CHPL_RT_MD_TASK_POOL_DESC,
                                           0, 0);
  tp->lockRprt            = NULL;

  tp->ptask->p_list_head  = NULL;
  tp->ptask->list_next    = NULL;
  tp->ptask->list_prev    = NULL;
  tp->ptask->next         = NULL;
  tp->ptask->prev         = NULL;

  tp->ptask->bundle.serial_state    = false;
  tp->ptask->bundle.countRunning    = false;
  tp->ptask->bundle.is_executeOn    = false;
  tp->ptask->bundle.lineno          = 0;
  tp->ptask->bundle.filename        = CHPL_FILE_IDX_COMM_TASK;
  tp->ptask->bundle.requestedSubloc = c_sublocid_any_val;
  tp->ptask->bundle.requested_fid   = FID_NONE;
  tp->ptask->bundle.requested_fn    = NULL;
  tp->ptask->bundle.id              = get_next_task_id();

  chpl_thread_setPrivateData(tp);

  (*comm_task_fn)(arg);
}
コード例 #3
0
ファイル: tasks-fifo.c プロジェクト: ct-clmsn/chapel
static void setup_main_thread_private_data(void)
{
  thread_private_data_t* tp;

  tp = (thread_private_data_t*) chpl_mem_alloc(sizeof(thread_private_data_t),
                                               CHPL_RT_MD_THREAD_PRV_DATA,
                                               0, 0);

  tp->ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t),
                                           CHPL_RT_MD_TASK_POOL_DESC,
                                           0, 0);
  tp->ptask->id           = get_next_task_id();
  tp->ptask->fun          = NULL;
  tp->ptask->arg          = NULL;
  tp->ptask->is_executeOn = false;
  tp->ptask->filename     = CHPL_FILE_IDX_MAIN_PROGRAM;
  tp->ptask->lineno       = 0;
  tp->ptask->p_list_head  = NULL;
  tp->ptask->next         = NULL;
  tp->lockRprt            = NULL;

  // Set up task-private data for locale (architectural) support.
  tp->ptask->chpl_data.prvdata.serial_state = true;     // Set to false in chpl_task_callMain().

  chpl_thread_setPrivateData(tp);
}
コード例 #4
0
ファイル: tasks-fifo.c プロジェクト: jcazzie/chapel
static void setup_main_thread_private_data(void)
{
  thread_private_data_t* tp;

  tp = (thread_private_data_t*) chpl_mem_alloc(sizeof(thread_private_data_t),
                                               CHPL_RT_MD_THREAD_PRV_DATA,
                                               0, 0);

  tp->ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t),
                                           CHPL_RT_MD_TASK_POOL_DESC,
                                           0, 0);
  tp->lockRprt            = NULL;

  tp->ptask->p_list_head  = NULL;
  tp->ptask->list_next    = NULL;
  tp->ptask->list_prev    = NULL;
  tp->ptask->next         = NULL;
  tp->ptask->prev         = NULL;

  // serial_state starts out true; it is set to false in chpl_std_module_init().
  tp->ptask->bundle.serial_state    = true;
  tp->ptask->bundle.countRunning    = false;
  tp->ptask->bundle.is_executeOn    = false;
  tp->ptask->bundle.lineno          = 0;
  tp->ptask->bundle.filename        = CHPL_FILE_IDX_MAIN_PROGRAM;
  tp->ptask->bundle.requestedSubloc = c_sublocid_any_val;
  tp->ptask->bundle.requested_fid   = FID_NONE;
  tp->ptask->bundle.requested_fn    = NULL;
  tp->ptask->bundle.id              = get_next_task_id();


  chpl_thread_setPrivateData(tp);
}
コード例 #5
0
ファイル: tasks-fifo.c プロジェクト: ct-clmsn/chapel
//
// When a thread is destroyed it calls this ending function.
//
static void thread_end(void)
{
  thread_private_data_t* tp;

  tp = (thread_private_data_t*) chpl_thread_getPrivateData();
  if (tp != NULL) {
    if (tp->lockRprt != NULL) {
      chpl_mem_free(tp->lockRprt, 0, 0);
      tp->lockRprt = NULL;
    }
    chpl_mem_free(tp, 0, 0);
    chpl_thread_setPrivateData(NULL);
  }
}
コード例 #6
0
ファイル: tasks-fifo.c プロジェクト: bollu/chapel
static void setup_main_thread_private_data(void)
{
  thread_private_data_t* tp;

  tp = (thread_private_data_t*) chpl_mem_calloc(1, sizeof(thread_private_data_t),
                                                CHPL_RT_MD_THREAD_PRV_DATA,
                                                0, 0);

  tp->ptask = (task_pool_p) chpl_mem_calloc(1, sizeof(task_pool_t),
                                            CHPL_RT_MD_TASK_POOL_DESC,
                                            0, 0);

  tp->ptask->bundle.is_executeOn    = false;
  tp->ptask->bundle.lineno          = 0;
  tp->ptask->bundle.filename        = CHPL_FILE_IDX_MAIN_PROGRAM;
  tp->ptask->bundle.requestedSubloc = c_sublocid_any_val;
  tp->ptask->bundle.requested_fid   = FID_NONE;
  tp->ptask->bundle.requested_fn    = NULL;
  tp->ptask->bundle.id              = get_next_task_id();

  chpl_thread_setPrivateData(tp);
}
コード例 #7
0
ファイル: tasks-fifo.c プロジェクト: ct-clmsn/chapel
//
// When we create a thread it runs this wrapper function, which just
// executes tasks out of the pool as they become available.
//
static void
thread_begin(void* ptask_void) {
  task_pool_p ptask;
  thread_private_data_t *tp;

  tp = (thread_private_data_t*) chpl_mem_alloc(sizeof(thread_private_data_t),
                                               CHPL_RT_MD_THREAD_PRV_DATA,
                                               0, 0);
  chpl_thread_setPrivateData(tp);

  tp->lockRprt = NULL;
  if (blockreport)
    initializeLockReportForThread();

  while (true) {
    //
    // wait for a task to be present in the task pool
    //

    // In revision 22137, we investigated whether it was beneficial to
    // implement this while loop in a hybrid style, where depending on
    // the number of tasks available, idle threads would either yield or
    // wait on a condition variable to waken them.  Through analysis, we
    // realized this could potential create a case where a thread would
    // become stranded, waiting for a condition signal that would never
    // come.  A potential solution to this was to keep a count of threads
    // that were waiting on the signal, but since there was a performance
    // impact from keeping it as a hybrid as opposed to merely yielding,
    // it was decided that we would return to the simple yield case.
    while (!task_pool_head) {
      if (set_block_loc(0, CHPL_FILE_IDX_IDLE_TASK)) {
        // all other tasks appear to be blocked
        struct timeval deadline, now;
        gettimeofday(&deadline, NULL);
        deadline.tv_sec += 1;
        do {
          chpl_thread_yield();
          if (!task_pool_head)
            gettimeofday(&now, NULL);
        } while (!task_pool_head
                 && (now.tv_sec < deadline.tv_sec
                     || (now.tv_sec == deadline.tv_sec
                         && now.tv_usec < deadline.tv_usec)));
        if (!task_pool_head) {
          check_for_deadlock();
        }
      }
      else {
        do {
          chpl_thread_yield();
        } while (!task_pool_head);
      }

      unset_block_loc();
    }
 
    //
    // Just now the pool had at least one task in it.  Lock and see if
    // there's something still there.
    //
    chpl_thread_mutexLock(&threading_lock);
    if (!task_pool_head) {
      chpl_thread_mutexUnlock(&threading_lock);
      continue;
    }

    //
    // We've found a task to run.
    //

    if (blockreport)
      progress_cnt++;

    //
    // start new task; increment running count and remove task from pool
    // also add to task to task-table (structure in ChapelRuntime that keeps
    // track of currently running tasks for task-reports on deadlock or
    // Ctrl+C).
    //
    ptask = task_pool_head;
    idle_thread_cnt--;
    running_task_cnt++;

    dequeue_task(ptask);

    // end critical section
    chpl_thread_mutexUnlock(&threading_lock);

    tp->ptask = ptask;

    if (do_taskReport) {
      chpl_thread_mutexLock(&taskTable_lock);
      chpldev_taskTable_set_active(ptask->id);
      chpl_thread_mutexUnlock(&taskTable_lock);
    }

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

    (*ptask->fun)(ptask->arg);

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

    if (do_taskReport) {
      chpl_thread_mutexLock(&taskTable_lock);
      chpldev_taskTable_remove(ptask->id);
      chpl_thread_mutexUnlock(&taskTable_lock);
    }

    tp->ptask = NULL;
    chpl_mem_free(ptask, 0, 0);

    // begin critical section
    chpl_thread_mutexLock(&threading_lock);

    //
    // finished task; decrement running count and increment idle count
    //
    assert(running_task_cnt > 0);
    running_task_cnt--;
    idle_thread_cnt++;

    // end critical section
    chpl_thread_mutexUnlock(&threading_lock);
  }
}
コード例 #8
0
ファイル: tasks-fifo.c プロジェクト: RobChrystie/chapel
void chpl_task_init(void) {
  chpl_thread_mutexInit(&threading_lock);
  chpl_thread_mutexInit(&extra_task_lock);
  chpl_thread_mutexInit(&task_id_lock);
  chpl_thread_mutexInit(&task_list_lock);
  queued_task_cnt = 0;
  running_task_cnt = 1;                     // only main task running
  blocked_thread_cnt = 0;
  idle_thread_cnt = 0;
  extra_task_cnt = 0;
  task_pool_head = task_pool_tail = NULL;

  chpl_thread_init(thread_begin, thread_end);

  //
  // Set main thread private data, so that things that require access
  // to it, like chpl_task_getID() and chpl_task_setSerial(), can be
  // called early (notably during standard module initialization).
  //
  // This needs to be done after the threading layer initialization,
  // because it's based on thread layer capabilities, but before we
  // install the signal handlers, because when those are invoked they
  // may use the thread private data.
  //
  {
    thread_private_data_t* tp;

    tp = (thread_private_data_t*) chpl_mem_alloc(sizeof(thread_private_data_t),
                                                 CHPL_RT_MD_THREAD_PRV_DATA,
                                                 0, 0);

    tp->ptask = (task_pool_p) chpl_mem_alloc(sizeof(task_pool_t),
                                             CHPL_RT_MD_TASK_POOL_DESC,
                                             0, 0);
    tp->ptask->id           = get_next_task_id();
    tp->ptask->fun          = NULL;
    tp->ptask->arg          = NULL;
    tp->ptask->is_executeOn = false;
    tp->ptask->filename     = CHPL_FILE_IDX_MAIN_PROGRAM;
    tp->ptask->lineno       = 0;
    tp->ptask->p_list_head  = NULL;
    tp->ptask->next         = NULL;
    tp->lockRprt            = NULL;

    // Set up task-private data for locale (architectural) support.
    tp->ptask->chpl_data.prvdata.serial_state = true;     // Set to false in chpl_task_callMain().

    chpl_thread_setPrivateData(tp);
  }

  if (blockreport) {
    progress_cnt = 0;
    chpl_thread_mutexInit(&block_report_lock);
    initializeLockReportForThread();
  }

  if (blockreport || taskreport) {
    signal(SIGINT, SIGINT_handler);
  }

  initialized = true;
}