Exemple #1
0
void alarmSchedule(Alarm_t *alarm, uint32_t milliseconds)
{
    // we want to avoid inserting local variables in the global alarm list
    // (but this warning, not an error, because the user function may never return)
    WARN_ON(isStackAddress(alarm));

    // PRINTF("alarmSchedule %p, ms=%lu\n", alarm, milliseconds);
    alarm->jiffies = (uint32_t)getJiffies() + milliseconds;

    // locking is required, because both kernel and user threads can be using this function
    Handle_t h;
    ATOMIC_START(h);

    // unschedule the alarm, if it was already scheduled
    SLIST_REMOVE_SAFE(&alarmListHead, alarm, Alarm_s, chain);

    // insert it in appropriate position
    Alarm_t **prev = &SLIST_FIRST(&alarmListHead);
    Alarm_t *a = *prev;
    while (a && timeAfter32(alarm->jiffies, a->jiffies)) {
        prev = &SLIST_NEXT(a, chain);
        a = *prev;
    }
    SLIST_INSERT(prev, alarm, chain);

#if USE_THREADS
    // always reschedule alarm processing in case some alarm was added
    // that might need to be processed before end of current kernel sleep time
    processFlags.bits.alarmsProcess = true;
    // and make sure the kernel thread is awake and ready to deal with it
    threadWakeup(KERNEL_THREAD_INDEX, THREAD_READY);
#endif

    ATOMIC_END(h);
}
Exemple #2
0
int
vtSleep(VtRendez *q)
{
	Thread *s, *t, *tt;
	VtLock *p;

	p = q->lk;
	lock(&p->lk);
	s = *vtRock;
	/*
	 * venti currently contains code that assume locks can be passed between threads :-(
	 * assert(p->writer != s);
	 */
	assert(p->writer != nil);
	assert(p->readers == 0);
	t = p->qfirst;
	if(t == nil) {
		p->writer = nil;
	} else if(t->state == QueuingW) {
		p->qfirst = t->next;
		p->writer = t;
		threadWakeup(t);
	} else {
		p->writer = nil;
		while(t != nil && t->state == QueuingR) {
			tt = t;
			t = t->next;
			p->readers++;
			threadWakeup(tt);
		}
	}

	if(q->wfirst == nil)
		q->wfirst = s;
	else
		q->wlast->next = s;
	q->wlast = s;
	s->next = nil;
	unlock(&p->lk);

	threadSleep(s);
	assert(p->writer == s);
	return 1;
}
Exemple #3
0
void
vtUnlock(VtLock *p)
{
	Thread *t, *tt;

	lock(&p->lk);
	/*
	 * venti currently has code that assumes lock can be passed between threads :-)
 	 * assert(p->writer == *vtRock);
	 */
 	assert(p->writer != nil);
	assert(p->readers == 0);
	t = p->qfirst;
	if(t == nil) {
		p->writer = nil;
		unlock(&p->lk);
		return;
	}
	if(t->state == QueuingW) {
		p->qfirst = t->next;
		p->writer = t;
		unlock(&p->lk);

		threadWakeup(t);
		return;
	}

	p->writer = nil;
	while(t != nil && t->state == QueuingR) {
		tt = t;
		t = t->next;
		p->readers++;

		threadWakeup(tt);
	}
	p->qfirst = t;
	unlock(&p->lk);
}
Exemple #4
0
void
vtRUnlock(VtLock *p)
{
	Thread *t;

	lock(&p->lk);
	assert(p->writer == nil && p->readers > 0);
	p->readers--;
	t = p->qfirst;
	if(p->readers > 0 || t == nil) {
		unlock(&p->lk);
		return;
	}
	assert(t->state == QueuingW);

	p->qfirst = t->next;
	p->writer = t;
	unlock(&p->lk);

	threadWakeup(t);
}