summaryrefslogtreecommitdiffstats
path: root/src/libthread/sched.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-12-06 18:05:27 +0000
committerrsc <devnull@localhost>2003-12-06 18:05:27 +0000
commite97ceade5e1bba5787e39429384336fa37797906 (patch)
tree1353f5aa99b04e9c030ecc89cd7b526cb814090d /src/libthread/sched.c
parentc715a6127a46b8090591972b5c4bb04dfabbca8b (diff)
downloadplan9port-e97ceade5e1bba5787e39429384336fa37797906.tar.gz
plan9port-e97ceade5e1bba5787e39429384336fa37797906.zip
various tweaks.
Diffstat (limited to 'src/libthread/sched.c')
-rw-r--r--src/libthread/sched.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/libthread/sched.c b/src/libthread/sched.c
index 293e3306..d6af1c7c 100644
--- a/src/libthread/sched.c
+++ b/src/libthread/sched.c
@@ -93,12 +93,21 @@ runthread(Proc *p)
Thread *t;
Tqueue *q;
- if(p->nthreads==0)
+ if(p->nthreads==0 || (p->nthreads==1 && p->idle))
return nil;
q = &p->ready;
lock(&p->readylock);
if(q->head == nil){
q->asleep = 1;
+ if(p->idle){
+ if(p->idle->state != Ready){
+ fprint(2, "everyone is asleep\n");
+ exits("everyone is asleep");
+ }
+ unlock(&p->readylock);
+ return p->idle;
+ }
+
_threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads);
unlock(&p->readylock);
while(rendezvous((ulong)q, 0) == ~0){
@@ -167,6 +176,9 @@ _threadready(Thread *t)
{
Tqueue *q;
+ if(t == t->proc->idle)
+ return;
+
assert(t->state == Ready);
_threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id);
q = &t->proc->ready;
@@ -191,6 +203,25 @@ _threadready(Thread *t)
}
void
+_threadidle(void)
+{
+ Tqueue *q;
+ Thread *t;
+ Proc *p;
+
+ p = _threadgetproc();
+ q = &p->ready;
+ lock(&p->readylock);
+ assert(q->head);
+ t = q->head;
+ q->head = t->next;
+ if(q->tail == t)
+ q->tail = nil;
+ p->idle = t;
+ unlock(&p->readylock);
+}
+
+void
yield(void)
{
_sched();