Esempio n. 1
0
/*
 * Free the stack for the current thread
 */
void _st_stack_free(_st_stack_t *ts)
{
  if (!ts)
    return;

  /* Put the stack on the free list *///走这里
  ST_APPEND_LINK(&ts->links, _st_free_stacks.prev);
  _st_num_free_stacks++;
}
Esempio n. 2
0
void _st_add_sleep_q(st_thread_t *thread, st_utime_t timeout)
{
	st_utime_t sleep;
	st_clist_t *q;
	st_thread_t *t;

	/* sort onto global sleep queue */
	sleep = timeout;

	/* Check if we are longest timeout */
	if (timeout >= _ST_SLEEPQMAX) {
		ST_APPEND_LINK(&thread->links, &_ST_SLEEPQ);
		thread->sleep = timeout - _ST_SLEEPQMAX;
		_ST_SLEEPQMAX = timeout;
	}
	else {
		/* Sort thread into global sleep queue at appropriate point */
		q = _ST_SLEEPQ.next;

		/* Now scan the list for where to insert this entry */
		while (q != &_ST_SLEEPQ) {
			t = _ST_THREAD_PTR(q);
			if (sleep < t->sleep) {
				/* Found sleeper to insert in front of */
				break;
			}
			sleep -= t->sleep;
			q = q->next;
		}
		thread->sleep = sleep;
		ST_INSERT_BEFORE(&thread->links, q);

		/* Subtract our sleep time from the sleeper that follows us */
		ST_ASSERT(thread->links.next != &_ST_SLEEPQ);
		t = _ST_THREAD_PTR(thread->links.next);
		ST_ASSERT(_ST_THREAD_PTR(t->links.prev) == thread);
		t->sleep -= sleep;
	}

	thread->flags |= _ST_FL_ON_SLEEPQ;
}
Esempio n. 3
0
int st_mutex_lock(_st_mutex_t *lock)
{
  _st_thread_t *me = _ST_CURRENT_THREAD();

  if (me->flags & _ST_FL_INTERRUPT) {
    me->flags &= ~_ST_FL_INTERRUPT;
    errno = EINTR;
    return -1;
  }

  if (lock->owner == NULL) {
    /* Got the mutex */
    lock->owner = me;
    return 0;
  }

  if (lock->owner == me) {
    errno = EDEADLK;
    return -1;
  }

  /* Put caller thread on the mutex's wait queue */
  me->state = _ST_ST_LOCK_WAIT;
  ST_APPEND_LINK(&me->wait_links, &lock->wait_q);

  _ST_SWITCH_CONTEXT(me);

  ST_REMOVE_LINK(&me->wait_links);

  if ((me->flags & _ST_FL_INTERRUPT) && lock->owner != me) {
    me->flags &= ~_ST_FL_INTERRUPT;
    errno = EINTR;
    return -1;
  }

  return 0;
}
Esempio n. 4
0
int st_cond_timedwait(_st_cond_t *cvar, st_utime_t timeout)
{
  _st_thread_t *me = _ST_CURRENT_THREAD();
  int rv;

  if (me->flags & _ST_FL_INTERRUPT) {
    me->flags &= ~_ST_FL_INTERRUPT;
    errno = EINTR;
    return -1;
  }

  /* Put caller thread on the condition variable's wait queue */
  me->state = _ST_ST_COND_WAIT;
  ST_APPEND_LINK(&me->wait_links, &cvar->wait_q);

  if (timeout != ST_UTIME_NO_TIMEOUT)
    _ST_ADD_SLEEPQ(me, timeout);

  _ST_SWITCH_CONTEXT(me);

  ST_REMOVE_LINK(&me->wait_links);
  rv = 0;

  if (me->flags & _ST_FL_TIMEDOUT) {
    me->flags &= ~_ST_FL_TIMEDOUT;
    errno = ETIME;
    rv = -1;
  }
  if (me->flags & _ST_FL_INTERRUPT) {
    me->flags &= ~_ST_FL_INTERRUPT;
    errno = EINTR;
    rv = -1;
  }

  return rv;
}