From df970459f9b37386fbfd4b7f3646825c8029caa8 Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 26 Jun 2006 05:47:59 +0000 Subject: pin --- src/libthread/thread.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/libthread/thread.c') diff --git a/src/libthread/thread.c b/src/libthread/thread.c index acd56fa2..48dd3e18 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -12,6 +12,7 @@ static void addproc(Proc*); static void delproc(Proc*); static void addthread(_Threadlist*, _Thread*); static void delthread(_Threadlist*, _Thread*); +static int onlist(_Threadlist*, _Thread*); static void addthreadinproc(Proc*, _Thread*); static void delthreadinproc(Proc*, _Thread*); static void contextswitch(Context *from, Context *to); @@ -254,6 +255,32 @@ threadexits(char *msg) _threadswitch(); } +void +threadpin(void) +{ + Proc *p; + + p = proc(); + if(p->pinthread){ + fprint(2, "already pinning a thread - %p %p\n", p->pinthread, p->thread); + assert(0); + } + p->pinthread = p->thread; +} + +void +threadunpin(void) +{ + Proc *p; + + p = proc(); + if(p->pinthread != p->thread){ + fprint(2, "wrong pinthread - %p %p\n", p->pinthread, p->thread); + assert(0); + } + p->pinthread = nil; +} + static void contextswitch(Context *from, Context *to) { @@ -273,6 +300,14 @@ procscheduler(Proc *p) /* print("s %p\n", p); */ lock(&p->lock); for(;;){ + if((t = p->pinthread) != nil){ + while(!onlist(&p->runqueue, t)){ + p->runrend.l = &p->lock; + _threaddebug("scheduler sleep (pin)"); + _procsleep(&p->runrend); + _threaddebug("scheduler wake (pin)"); + } + }else while((t = p->runqueue.head) == nil){ if(p->nthread == 0) goto Out; @@ -291,6 +326,9 @@ procscheduler(Proc *p) _procsleep(&p->runrend); _threaddebug("scheduler wake"); } + if(p->pinthread && p->pinthread != t) + fprint(2, "p->pinthread %p t %p\n", p->pinthread, t); + assert(p->pinthread == nil || p->pinthread == t); delthread(&p->runqueue, t); unlock(&p->lock); p->thread = t; @@ -652,6 +690,8 @@ main(int argc, char **argv) _rsleep = threadrsleep; _rwakeup = threadrwakeup; _notejmpbuf = threadnotejmp; + _pin = threadpin; + _unpin = threadunpin; _pthreadinit(); p = procalloc(); @@ -697,6 +737,18 @@ delthread(_Threadlist *l, _Thread *t) l->tail = t->prev; } +/* inefficient but rarely used */ +static int +onlist(_Threadlist *l, _Thread *t) +{ + _Thread *tt; + + for(tt = l->head; tt; tt=tt->next) + if(tt == t) + return 1; + return 0; +} + static void addthreadinproc(Proc *p, _Thread *t) { -- cgit v1.2.3