aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-07-09 11:41:14 -0400
committerRuss Cox <rsc@swtch.com>2008-07-09 11:41:14 -0400
commitfaf1fb6c7e14e95e54865b660db7501ed390ea9e (patch)
tree3bc641f198f13f19b194040786d100f707a9af7e /src/libthread
parentf35a04866f298aa4b0fa6846da0c0187751ce9b2 (diff)
downloadplan9port-faf1fb6c7e14e95e54865b660db7501ed390ea9e.tar.gz
plan9port-faf1fb6c7e14e95e54865b660db7501ed390ea9e.tar.bz2
plan9port-faf1fb6c7e14e95e54865b660db7501ed390ea9e.zip
libthread: abort on single-threaded lock contention
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/thread.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/libthread/thread.c b/src/libthread/thread.c
index 4e3e473c..78c538ac 100644
--- a/src/libthread/thread.c
+++ b/src/libthread/thread.c
@@ -463,6 +463,12 @@ needstack(int n)
}
}
+static int
+singlethreaded(void)
+{
+ return threadnproc == 1 && _threadprocs->nthread == 1;
+}
+
/*
* locking
*/
@@ -481,6 +487,12 @@ threadqlock(QLock *l, int block, ulong pc)
unlock(&l->l);
return 0;
}
+
+ if(singlethreaded()){
+ fprint(2, "qlock deadlock\n");
+ abort();
+ }
+
/*print("qsleep %p @%#x by %p\n", l, pc, (*threadnow)()); */
addthread(&l->waiting, (*threadnow)());
unlock(&l->l);
@@ -537,6 +549,10 @@ threadrlock(RWLock *l, int block, ulong pc)
unlock(&l->l);
return 0;
}
+ if(singlethreaded()){
+ fprint(2, "rlock deadlock\n");
+ abort();
+ }
addthread(&l->rwaiting, (*threadnow)());
unlock(&l->l);
_threadswitch();
@@ -558,6 +574,10 @@ threadwlock(RWLock *l, int block, ulong pc)
unlock(&l->l);
return 0;
}
+ if(singlethreaded()){
+ fprint(2, "wlock deadlock\n");
+ abort();
+ }
addthread(&l->wwaiting, (*threadnow)());
unlock(&l->l);
_threadswitch();
@@ -613,6 +633,10 @@ threadwunlock(RWLock *l, ulong pc)
static void
threadrsleep(Rendez *r, ulong pc)
{
+ if(singlethreaded()){
+ fprint(2, "rsleep deadlock\n");
+ abort();
+ }
addthread(&r->waiting, proc()->thread);
qunlock(r->l);
_threadswitch();