Exemplo n.º 1
0
/* Return remain time in second. */
u_int32_t thread_timer_remain_second (struct thread *thread)
{
  struct pal_timeval timer_now;

  if (thread == NULL)
    return 0;

  pal_time_tzcurrent (&timer_now, NULL);

  if (thread->u.sands.tv_sec - timer_now.tv_sec > 0)
    return thread->u.sands.tv_sec - timer_now.tv_sec;
  else
    return 0;
}
Exemplo n.º 2
0
/* Pick up smallest timer.  */
struct pal_timeval *
thread_timer_wait (struct thread_master *m, struct pal_timeval *timer_val)
{
  struct pal_timeval timer_now;
  struct pal_timeval timer_min;
  struct pal_timeval *timer_wait;
  struct thread *thread;
  int i;

  timer_wait = NULL;

  for (i = 0; i < THREAD_TIMER_SLOT; i++)
    if ((thread = m->timer[i].head) != NULL)
      {
        if (! timer_wait)
          timer_wait = &thread->u.sands;
        else if (timeval_cmp (thread->u.sands, *timer_wait) < 0)
          timer_wait = &thread->u.sands;
      }

  if (timer_wait)
    {
      timer_min = *timer_wait;

      pal_time_tzcurrent (&timer_now, NULL);
      timer_min = timeval_subtract (timer_min, timer_now);

      if (timer_min.tv_sec < 0)
        {
          timer_min.tv_sec = 0;
          timer_min.tv_usec = 10;
        }

      *timer_val = timer_min;
      return timer_val;
    }
  return NULL;
}
Exemplo n.º 3
0
/* Add timer event thread. */
struct thread *
thread_add_timer_timeval (struct lib_globals *zg,
                          int (*func) (struct thread *), void *arg,
                          struct pal_timeval timer)
{
  struct thread_master *m = zg->master;
  struct pal_timeval timer_now;
  struct thread *thread;

  pal_assert (m != NULL);

  thread = thread_get (zg, THREAD_TIMER, func, arg);
  if (thread == NULL)
    return NULL;

  /* Do we need jitter here? */
  pal_time_tzcurrent (&timer_now, NULL);
  timer_now.tv_sec += timer.tv_sec;
  timer_now.tv_usec += timer.tv_usec;
  while (timer_now.tv_usec >= TV_USEC_PER_SEC)
    {
      timer_now.tv_sec++;
      timer_now.tv_usec -= TV_USEC_PER_SEC;
    }

  /* Correct negative value.  */
  if (timer_now.tv_sec < 0)
    timer_now.tv_sec = PAL_TIME_MAX_TV_SEC;
  if (timer_now.tv_usec < 0)
    timer_now.tv_usec = PAL_TIME_MAX_TV_USEC;

  thread->u.sands = timer_now;

  /* Common process.  */
  thread_add_timer_common (m, thread);

  return thread;
}
Exemplo n.º 4
0
/* Add timer event thread. */
struct thread *
thread_add_timer (struct lib_globals *zg,
                 int (*func) (struct thread *),
                 void *arg, long timer)
{
  struct thread_master *m = zg->master;
  struct pal_timeval timer_now;
  struct thread *thread;

  pal_assert (m != NULL);
  thread = thread_get (zg, THREAD_TIMER, func, arg);
  if (thread == NULL)
    return NULL;

  pal_time_tzcurrent (&timer_now, NULL);
  timer_now.tv_sec += timer;
  thread->u.sands = timer_now;

  /* Common process.  */
  thread_add_timer_common (m, thread);

  return thread;
}
Exemplo n.º 5
0
/* Add timer event thread. */
struct thread *
thread_add_timer (struct thread_master *master,
                 int (*func) (struct thread *), void *arg, long timer)
{
  struct thread_master *m = master;
  struct pal_timeval timer_now;
  struct thread *thread;

  assert (m != NULL);
  thread = thread_get (m, THREAD_TIMER, func, arg);
  if (thread == NULL)
    return NULL;

  /* Do we need jitter here? */
  pal_time_tzcurrent (&timer_now, NULL);
  timer_now.tv_sec += timer;
  thread->u.sands = timer_now;

  /* Common process.  */
  thread_add_timer_common (m, thread);

  return thread;
}
Exemplo n.º 6
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);
    }
}
Exemplo n.º 7
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;
}