itlibthread: handle spurious _procsleep wakeups, fix $LIBTHREAD handling - plan9port - [fork] Plan 9 from user space Err mx1.adamsgaard.dk 70 hgit clone git://src.adamsgaard.dk/plan9port URL:git://src.adamsgaard.dk/plan9port mx1.adamsgaard.dk 70 1Log /src/plan9port/log.gph mx1.adamsgaard.dk 70 1Files /src/plan9port/files.gph mx1.adamsgaard.dk 70 1Refs /src/plan9port/refs.gph mx1.adamsgaard.dk 70 1README /src/plan9port/file/README.md.gph mx1.adamsgaard.dk 70 1LICENSE /src/plan9port/file/LICENSE.gph mx1.adamsgaard.dk 70 i--- Err mx1.adamsgaard.dk 70 1commit 162d0d5cd94fabab822ac66655be8957151cef99 /src/plan9port/commit/162d0d5cd94fabab822ac66655be8957151cef99.gph mx1.adamsgaard.dk 70 1parent baef953da253314657be9adea8f371bfbf4ba09e /src/plan9port/commit/baef953da253314657be9adea8f371bfbf4ba09e.gph mx1.adamsgaard.dk 70 hAuthor: Russ Cox URL:mailto:rsc@swtch.com mx1.adamsgaard.dk 70 iDate: Sun, 17 May 2020 22:31:38 -0400 Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 ilibthread: handle spurious _procsleep wakeups, fix $LIBTHREAD handling Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 iDiffstat: Err mx1.adamsgaard.dk 70 i M src/libthread/pthread.c | 4 +++- Err mx1.adamsgaard.dk 70 i M src/libthread/thread.c | 28 +++++++++++++++++++++++----- Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i2 files changed, 26 insertions(+), 6 deletions(-) Err mx1.adamsgaard.dk 70 i--- Err mx1.adamsgaard.dk 70 1diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c /src/plan9port/file/src/libthread/pthread.c.gph mx1.adamsgaard.dk 70 it@@ -50,13 +50,15 @@ _threadunlock(Lock *lk, ulong pc) Err mx1.adamsgaard.dk 70 i abort(); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i+/* note: _procsleep can have spurious wakeups, like pthread_cond_wait */ Err mx1.adamsgaard.dk 70 i void Err mx1.adamsgaard.dk 70 i _procsleep(_Procrendez *r) Err mx1.adamsgaard.dk 70 i { Err mx1.adamsgaard.dk 70 i /* r is protected by r->l, which we hold */ Err mx1.adamsgaard.dk 70 i pthread_cond_init(&r->cond, 0); Err mx1.adamsgaard.dk 70 i r->asleep = 1; Err mx1.adamsgaard.dk 70 i- pthread_cond_wait(&r->cond, &r->l->mutex); Err mx1.adamsgaard.dk 70 i+ if(pthread_cond_wait(&r->cond, &r->l->mutex) != 0) Err mx1.adamsgaard.dk 70 i+ sysfatal("pthread_cond_wait: %r"); Err mx1.adamsgaard.dk 70 i pthread_cond_destroy(&r->cond); Err mx1.adamsgaard.dk 70 i r->asleep = 0; Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 1diff --git a/src/libthread/thread.c b/src/libthread/thread.c /src/plan9port/file/src/libthread/thread.c.gph mx1.adamsgaard.dk 70 it@@ -54,9 +54,9 @@ _threaddebug(char *fmt, ...) Err mx1.adamsgaard.dk 70 i va_end(arg); Err mx1.adamsgaard.dk 70 i t = proc()->thread; Err mx1.adamsgaard.dk 70 i if(t) Err mx1.adamsgaard.dk 70 i- fprint(fd, "%d.%d: %s\n", getpid(), t->id, buf); Err mx1.adamsgaard.dk 70 i+ fprint(fd, "%p %d.%d: %s\n", proc(), getpid(), t->id, buf); Err mx1.adamsgaard.dk 70 i else Err mx1.adamsgaard.dk 70 i- fprint(fd, "%d._: %s\n", getpid(), buf); Err mx1.adamsgaard.dk 70 i+ fprint(fd, "%p %d._: %s\n", proc(), getpid(), buf); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i static _Thread* Err mx1.adamsgaard.dk 70 it@@ -219,20 +219,28 @@ proccreate(void (*fn)(void*), void *arg, uint stack) Err mx1.adamsgaard.dk 70 i static void Err mx1.adamsgaard.dk 70 i procswitch(Proc *p, _Thread *from, _Thread *to) Err mx1.adamsgaard.dk 70 i { Err mx1.adamsgaard.dk 70 i-// fprint(2, "procswitch %p %d %d\n", p, from?from->id:-1, to?to->id:-1); Err mx1.adamsgaard.dk 70 i+ _threaddebug("procswitch %p %d %d", p, from?from->id:-1, to?to->id:-1); Err mx1.adamsgaard.dk 70 i lock(&p->schedlock); Err mx1.adamsgaard.dk 70 i from->schedrend.l = &p->schedlock; Err mx1.adamsgaard.dk 70 i if(to) { Err mx1.adamsgaard.dk 70 i p->schedthread = to; Err mx1.adamsgaard.dk 70 i to->schedrend.l = &p->schedlock; Err mx1.adamsgaard.dk 70 i+ _threaddebug("procswitch wakeup %p %d", p, to->id); Err mx1.adamsgaard.dk 70 i _procwakeup(&to->schedrend); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i if(p->schedthread != from) { Err mx1.adamsgaard.dk 70 i if(from->exiting) { Err mx1.adamsgaard.dk 70 i unlock(&p->schedlock); Err mx1.adamsgaard.dk 70 i _threadpexit(); Err mx1.adamsgaard.dk 70 i+ _threaddebug("procswitch exit wakeup!!!\n"); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i- _procsleep(&from->schedrend); Err mx1.adamsgaard.dk 70 i+ while(p->schedthread != from) { Err mx1.adamsgaard.dk 70 i+ _threaddebug("procswitch sleep %p %d", p, from->id); Err mx1.adamsgaard.dk 70 i+ _procsleep(&from->schedrend); Err mx1.adamsgaard.dk 70 i+ _threaddebug("procswitch awake %p %d", p, from->id); Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ if(p->schedthread != from) Err mx1.adamsgaard.dk 70 i+ sysfatal("_procswitch %p %p oops", p->schedthread, from); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i unlock(&p->schedlock); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 it@@ -448,6 +456,7 @@ Top: Err mx1.adamsgaard.dk 70 i procswitch(p, p->thread0, t); Err mx1.adamsgaard.dk 70 i else Err mx1.adamsgaard.dk 70 i contextswitch(&p->schedcontext, &t->context); Err mx1.adamsgaard.dk 70 i+ _threaddebug("back in scheduler"); Err mx1.adamsgaard.dk 70 i /*print("back in scheduler\n"); */ Err mx1.adamsgaard.dk 70 i goto Top; Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 it@@ -589,6 +598,10 @@ threadqlock(QLock *l, int block, ulong pc) Err mx1.adamsgaard.dk 70 i if(l->owner == nil){ Err mx1.adamsgaard.dk 70 i l->owner = (*threadnow)(); Err mx1.adamsgaard.dk 70 i /*print("qlock %p @%#x by %p\n", l, pc, l->owner); */ Err mx1.adamsgaard.dk 70 i+ if(l->owner == nil) { Err mx1.adamsgaard.dk 70 i+ fprint(2, "%s: qlock uncontended owner=nil oops\n", argv0); Err mx1.adamsgaard.dk 70 i+ abort(); Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i unlock(&l->l); Err mx1.adamsgaard.dk 70 i return 1; Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 it@@ -613,6 +626,11 @@ threadqlock(QLock *l, int block, ulong pc) Err mx1.adamsgaard.dk 70 i argv0, pc, l->owner, (*threadnow)()); Err mx1.adamsgaard.dk 70 i abort(); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i+ if(l->owner == nil) { Err mx1.adamsgaard.dk 70 i+ fprint(2, "%s: qlock threadswitch owner=nil oops\n", argv0); Err mx1.adamsgaard.dk 70 i+ abort(); Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i /*print("qlock wakeup %p @%#x by %p\n", l, pc, (*threadnow)()); */ Err mx1.adamsgaard.dk 70 i return 1; Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 it@@ -818,7 +836,7 @@ main(int argc, char **argv) Err mx1.adamsgaard.dk 70 i // Easier to just run in pthread-per-thread mode. Err mx1.adamsgaard.dk 70 i pthreadperthread = 1; Err mx1.adamsgaard.dk 70 i #endif Err mx1.adamsgaard.dk 70 i- if(strstr(opts, "nodaemon") || getenv("NOLIBTHREADDAEMONIZE") == nil) Err mx1.adamsgaard.dk 70 i+ if(strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil) Err mx1.adamsgaard.dk 70 i _threadsetupdaemonize(); Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i threadargc = argc; Err mx1.adamsgaard.dk 70 .