#include <9pm/u.h> #include <9pm/libc.h> #include <9pm/ns.h> #include <9pm/thread.h> #include <9pm/threadimpl.h> void _threadputq(Tqueue *q, Thread *t) { Thread *x; Thread **l; lock(&q->lk); _threaddebug(DBGQUE, "Putq 0x%lux on 0x%lux, next == 0x%lux", (ulong)t, (ulong)q, (ulong)t->next); threadassert((ulong)t->next == (ulong)~0); t->next = nil; if (q->head == nil) { q->head = t; q->tail = t; } else { x = q->tail->next; if(x != nil){ _threaddebug(DBGQUE, "\tq->tail->next = 0x%lux", (ulong)x); _threaddebug(DBGQUE, "\tq=0x%lux q->tail=0x%lux q->tail->next=0x%lux", (ulong)q, (ulong)q->tail, (ulong)q->tail->next); _threaddebug(DBGQUE, "\tq=0x%lux q->head=0x%lux q->head->next=0x%lux", (ulong)q, (ulong)q->head, (ulong)q->head->next); l = &q->tail->next; _threaddebug(DBGQUE, "\tl=0x%lux *l=0x%lux\n", (ulong)l, (ulong)*l); _threaddebug(DBGQUE, "\tsp=0x%lux; stack is 0x%lux-0x%lux\n", (ulong)&l, (ulong)_threadgetthr()->stk, (ulong)_threadgetthr()->stk+_threadgetthr()->stksize); abort(); threadassert(x == nil); } q->tail->next = t; q->tail = t; } unlock(&q->lk); } Thread * _threadgetq(Tqueue *q) { Thread *t; lock(&q->lk); if ((t = q->head)) { q->head = q->head->next; t->next = (Thread *)~0; } unlock(&q->lk); _threaddebug(DBGQUE, "Getq 0x%lux from 0x%lux", (ulong)t, (ulong)q); return t; } Thread * _threadgetqbytag(Tqueue *q, ulong tag) { Thread *r, *pr, *w, *pw; w = pr = pw = nil; _threaddebug(DBGQUE, "Getqbytag 0x%lux", q); lock(&q->lk); for (r = q->head; r; r = r->next) { if (r->tag == tag) { w = r; pw = pr; if (r->proc == _threadgetproc()) { /* Locals or blocked remotes are best */ break; } } pr = r; } if (w) { if (pw) pw->next = w->next; else q->head = w->next; if (q->tail == w){ q->tail = pw; threadassert(pw == nil || pw->next == nil); } w->next = (Thread *)~0; } unlock(&q->lk); _threaddebug(DBGQUE, "Getqbytag 0x%lux from 0x%lux", w, q); return w; }