Ejemplo n.º 1
0
void co_exit(void)
{
	cothread_ctx *tctx = co_get_thread_ctx();

	co_exit_to((coroutine_t) tctx->co_curr->restarget);
}
Ejemplo n.º 2
0
void co_exit(void) {

	co_exit_to((coroutine_t) co_curr->restarget);
}
Ejemplo n.º 3
0
void
gsoc_finish_current_task()
{
  if (!_workers[_thread_id].current_task->cutoff)
    {
      __sync_sub_and_fetch(&_num_team_tasks, 1);

      if (_workers[_thread_id].current_task->creator)
        {
          if (_workers[_thread_id].current_task->creator->num_children <= 2)
            {
              /* If there are only two children, it is possible that
                 both of them finishes almost at the same time.
                 If it happens, parent of them would be waken up by both of them.
                 So in order to save consistensy, creator->num_children should be locked
                 when there are only two children. */
              pthread_mutex_lock(&_workers[_thread_id].current_task->creator->lock);
              --_workers[_thread_id].current_task->creator->num_children;
              if (_workers[_thread_id].current_task->creator->num_children == 0
                  && _workers[_thread_id].current_task->creator->waiting)
                {
                  /* Tell parent task that all of us children finished our work
                     then parent resume its work using our result. */
                  _workers[_thread_id].current_task->creator->waiting = false;
                  pthread_mutex_unlock(&_workers[_thread_id].current_task->creator->lock);
                  gsoc_taskqueue_push(_workers[_thread_id].taskq, _workers[_thread_id].current_task->creator);
                }
              else
                pthread_mutex_unlock(&_workers[_thread_id].current_task->creator->lock);
            }
          else
            {
              __sync_sub_and_fetch(&_workers[_thread_id].current_task->creator->num_children, 1);
              if (_workers[_thread_id].current_task->creator->num_children == 0
                  && _workers[_thread_id].current_task->creator->waiting)
                {
                  /* Tell parent task that all of us children finished our work
                     then parent resume its work using our result. */
                  _workers[_thread_id].current_task->creator->waiting = false;
                  gsoc_taskqueue_push(_workers[_thread_id].taskq, _workers[_thread_id].current_task->creator);
                }
            }
        }
      /* ここをco_call(scheduler)にすると,current_taskの実行は今後ない.
         つまり,co_runnerを最後まで実行できないので,メモリリークになる */
      /* co_exit_to(scheduler)だと,確かにメモリリークは観測されない. */
      co_exit_to(_workers[_thread_id].scheduler_task, _thread_id);
    }
  else if (_workers[_thread_id].current_task->cutoff
           && _workers[_thread_id].current_task->depth == _gsoc_cutoff_depth + 1)
    {
      /* When the root cutoff task exits */
      __sync_sub_and_fetch(&_num_team_tasks, 1);
      _workers[_thread_id].current_task->cutoff = false;

      if (_workers[_thread_id].current_task->creator)
        {
          if (_workers[_thread_id].current_task->creator->num_children <= 2)
            {
              /* If there are only two children, it is possible that
                 both of them finishes almost at the same time.
                 If it happens, parent of them would be waken up by both of them.
                 So in order to save consistensy, creator->num_children should be locked
                 when there are only two children. */
              pthread_mutex_lock(&_workers[_thread_id].current_task->creator->lock);
              --_workers[_thread_id].current_task->creator->num_children;
              if (_workers[_thread_id].current_task->creator->num_children == 0
                  && _workers[_thread_id].current_task->creator->waiting)
                {
                  /* Tell parent task that all of us children finished our work
                     then parent resume its work using our result. */
                  _workers[_thread_id].current_task->creator->waiting = false;
                  pthread_mutex_unlock(&_workers[_thread_id].current_task->creator->lock);
                  gsoc_taskqueue_push(_workers[_thread_id].taskq, _workers[_thread_id].current_task->creator);
                }
              else
                pthread_mutex_unlock(&_workers[_thread_id].current_task->creator->lock);
            }
          else
            {
              __sync_sub_and_fetch(&_workers[_thread_id].current_task->creator->num_children, 1);
              if (_workers[_thread_id].current_task->creator->num_children == 0
                  && _workers[_thread_id].current_task->creator->waiting)
                {
                  /* Tell parent task that all of us children finished our work
                     then parent resume its work using our result. */
                  _workers[_thread_id].current_task->creator->waiting = false;
                  gsoc_taskqueue_push(_workers[_thread_id].taskq, _workers[_thread_id].current_task->creator);
                }
            }
        }
    }
  /* Cutoff task does nothing here */
}
Ejemplo n.º 4
0
void
co_exit(void *data)
{
    co_exit_to(co_current->resumeto, data);
}