Пример #1
0
/* Fetch next ready thread. */
struct thread *
thread_fetch (struct lib_globals *zg, struct thread *fetch)
{
  struct thread_master *m = zg->master;
  int num;
  struct thread *thread;
  struct thread *next;
  pal_sock_set_t readfd;
  pal_sock_set_t writefd;
  pal_sock_set_t exceptfd;
  struct pal_timeval timer_now;
  struct pal_timeval timer_val;
  struct pal_timeval *timer_wait;
  struct pal_timeval timer_nowait;
  int i;

#ifdef RTOS_DEFAULT_WAIT_TIME
  /* 1 sec might not be optimized */
  timer_nowait.tv_sec = 1;
  timer_nowait.tv_usec = 0;
#else
  timer_nowait.tv_sec = 0;
  timer_nowait.tv_usec = 0;
#endif /* RTOS_DEFAULT_WAIT_TIME */

  /* Set the global VR context to PVR. */
  zg->vr_in_cxt = ipi_vr_get_privileged(zg);

  while (1)
    {
      /* Pending read is exception. */
      if ((thread = thread_trim_head (&m->read_pend)) != NULL)
        return thread_run (m, thread, fetch);

      /* Check ready queue.  */
      if ((thread = thread_trim_head (&m->queue_high)) != NULL)
        return thread_run (m, thread, fetch);

      if ((thread = thread_trim_head (&m->queue_middle)) != NULL)
        return thread_run (m, thread, fetch);

      if ((thread = thread_trim_head (&m->queue_low)) != NULL)
        return thread_run (m, thread, fetch);

      /* Check all of available events.  */

      /* Check events.  */
      while ((thread = thread_trim_head (&m->event)) != NULL)
        thread_enqueue_high (m, thread);

      /* Check timer.  */
      pal_time_tzcurrent (&timer_now, NULL);

      for (i = 0; i < THREAD_TIMER_SLOT; i++)
        for (thread = m->timer[i].head; thread; thread = next)
          {
            next = thread->next;
            if (timeval_cmp (timer_now, thread->u.sands) >= 0)
              {
                thread_list_delete (&m->timer[i], thread);
                thread_enqueue_middle (m, thread);
              }
#ifndef TIMER_NO_SORT
            else
              break;
#endif /* TIMER_NO_SORT */
          }

      /* Structure copy.  */
      readfd = m->readfd;
      writefd = m->writefd;
      exceptfd = m->exceptfd;

      /* Check any thing to be execute.  */
      if (m->queue_high.head || m->queue_middle.head || m->queue_low.head)
        timer_wait = &timer_nowait;
      else
        timer_wait = thread_timer_wait (m, &timer_val);

      /* First check for sockets.  Return immediately.  */
      num = pal_sock_select (m->max_fd + 1, &readfd, &writefd, &exceptfd,
                             timer_wait);

      /* Error handling.  */
      if (num < 0)
        {
          if (errno == EINTR)
            continue;
          return NULL;
        }

      /* File descriptor is readable/writable.  */
      if (num > 0)
        {
          /* High priority read thead. */
          thread_process_fd (m, &m->read_high, &readfd, &m->readfd);

          /* Normal priority read thead. */
          thread_process_fd (m, &m->read, &readfd, &m->readfd);

          /* Write thead. */
          thread_process_fd (m, &m->write, &writefd, &m->writefd);
        }

      /* Low priority events. */
      if ((thread = thread_trim_head (&m->event_low)) != NULL)
        thread_enqueue_low (m, thread);
    }
}
Пример #2
0
/* Fetch next ready thread. */
struct thread *
thread_fetch_return (struct thread_master *master, struct thread *fetch)
{
  struct thread_master *m = master;
  int num;
  struct thread *thread;
  struct thread *next;
  fd_set readfd;
  fd_set writefd;
  fd_set exceptfd;
  struct pal_timeval timer_now;
  struct pal_timeval timer_val;
  struct pal_timeval *timer_wait;
  struct pal_timeval timer_nowait;
  int i;


  timer_nowait.tv_sec = 0;
  timer_nowait.tv_usec = 0;


      /* Pending read is exception. */
      if ((thread = thread_trim_head (&m->read_pend)) != NULL)
		return thread_run (m, thread, fetch);

      /* Check ready queue.  */
      if ((thread = thread_trim_head (&m->queue_high)) != NULL)
		return thread_run (m, thread, fetch);

      if ((thread = thread_trim_head (&m->queue_middle)) != NULL)
	return thread_run (m, thread, fetch);

      if ((thread = thread_trim_head (&m->queue_low)) != NULL)
	return thread_run (m, thread, fetch);

      /* Check all of available events.  */
      /* Check events.  */
      while ((thread = thread_trim_head (&m->event)) != NULL)
	thread_enqueue_high (m, thread);

      /* Check timer.  */
      pal_time_tzcurrent (&timer_now, NULL);

      for (i = 0; i < THREAD_TIMER_SLOT; i++)
	for (thread = m->timer[i].head; thread; thread = next)
	  {
	    next = thread->next;
	    if (timeval_cmp (timer_now, thread->u.sands) >= 0)
	      {
		thread_list_delete (&m->timer[i], thread);
		thread_enqueue_middle (m, thread);
	      }
#ifndef TIMER_NO_SORT
	    else
	      break;
#endif /* TIMER_NO_SORT */
	  }

    /* Structure copy.  */
      readfd = m->readfd;
      writefd = m->writefd;
      exceptfd = m->exceptfd;

      /* Check any thing to be execute.  */
      if (m->queue_high.head || m->queue_middle.head || m->queue_low.head)
	timer_wait = &timer_nowait;
      else
	timer_wait = thread_timer_wait (m, &timer_val);

	timer_wait = &timer_nowait;
        /* First check for sockets.  Return immediately.  */
      num = select (m->max_fd + 1, &readfd, &writefd, &exceptfd,
			     timer_wait);



      /* Error handling.  */
      if (num < 0)
	{
	  return NULL;
	}


      /* File descriptor is readable/writable.  */
      if (num > 0)
	{
	  /* High priority read thead. */
	  thread_process_fd (m, &m->read_high, &readfd, &m->readfd);

	  /* Normal priority read thead. */
	  thread_process_fd (m, &m->read, &readfd, &m->readfd);

	  /* Write thead. */
	  thread_process_fd (m, &m->write, &writefd, &m->writefd);
	}



      /* Low priority events. */
      if ((thread = thread_trim_head (&m->event_low)) != NULL)
        thread_enqueue_low (m, thread);

	return NULL;
}