From 098bdf4ef5082cccfa0909aae55948fc4f0a094b Mon Sep 17 00:00:00 2001 From: jasonzzzzzzz <53132593+jasonzzzzzzz@users.noreply.github.com> Date: Thu, 7 Nov 2019 12:46:02 -0500 Subject: [PATCH 1/3] avoid sleeping-relted deadlock (Issue #231) Previous ThreadFini() lacks control of SLEEPING threads in finish(). This change helps many-thread simulation to completion; Otherwise, it deadlocks when running TailBench Apps with only 2-4 threads. --- src/scheduler.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/scheduler.h b/src/scheduler.h index 451b2a78..c4c16a68 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -243,6 +243,35 @@ class Scheduler : public GlobAlloc, public Callee { futex_lock(&schedLock); } + //############################################################### + //jz: consider sleep threads for avoiding deadlocks + if (th->state == SLEEPING) { + info("[G %d] finish function ----- jz: ----- \n ################################ \n detected sleeping thread when called finish, pid %d, tid %d, gid %d, sleepQueue size: %lu", gid, pid, tid, gid, sleepQueue.size()); + printState(); + sleepQueue.remove(th); + th->state = BLOCKED; + info("[G %d] finish function ----- jz: ----- \n ################################ \n wakeup SLEEPING thread and is converted to be BLOCKED, pid %d, tid %d, gid %d, sleepQueue size: %lu \n ################################ \n", gid, pid, tid, gid, sleepQueue.size()); + printState(); + + assert(th->state == BLOCKED); + + ContextInfo* ctx = schedThread(th); + if (ctx) { + schedule(th, ctx); + zinfo->cores[ctx->cid]->join(); + //////info("[G %d] join function ----- jz: ----- do join: a BLOCKED thread scheduled to be a RUNNING thread, pid %d, tid %d, gid %d", gid, pid, tid, gid); + //////printState(); + bar.join(ctx->cid, &schedLock); //releases lock + } else { + th->state = QUEUED; + runQueue.push_back(th); + waitForContext(th); //releases lock, might join + ////info("[G %d] join function ----- jz: ----- do join: a BLOCKED thread scheduled to be a QUEUE thread, waiting for a avaliable context, pid %d, tid %d, gid %d", gid, pid, tid, gid); + ////printState(); + } + } + //################################################################# + //dsm: Added this check; the normal sequence is leave, finish, but with fastFwd you never know if (th->state == RUNNING) { warn("RUNNING thread %d (cid %d) called finish(), trying leave() first", tid, th->cid); From 78a200e87ee2b2a09488e96d482d9c6331406013 Mon Sep 17 00:00:00 2001 From: jasonzzzzzzz <53132593+jasonzzzzzzz@users.noreply.github.com> Date: Thu, 12 Dec 2019 22:08:59 -0500 Subject: [PATCH 2/3] Update scheduler.h --- src/scheduler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scheduler.h b/src/scheduler.h index c4c16a68..cfa3ee0e 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -246,7 +246,7 @@ class Scheduler : public GlobAlloc, public Callee { //############################################################### //jz: consider sleep threads for avoiding deadlocks if (th->state == SLEEPING) { - info("[G %d] finish function ----- jz: ----- \n ################################ \n detected sleeping thread when called finish, pid %d, tid %d, gid %d, sleepQueue size: %lu", gid, pid, tid, gid, sleepQueue.size()); + /// info("[G %d] finish function ----- jz: ----- \n ################################ \n detected sleeping thread when called finish, pid %d, tid %d, gid %d, sleepQueue size: %lu", gid, pid, tid, gid, sleepQueue.size()); printState(); sleepQueue.remove(th); th->state = BLOCKED; From 6f616af0387c4993a75504aff2f17d01abd6e871 Mon Sep 17 00:00:00 2001 From: jasonzzzzzzz <53132593+jasonzzzzzzz@users.noreply.github.com> Date: Thu, 12 Dec 2019 22:13:59 -0500 Subject: [PATCH 3/3] Update scheduler.h --- src/scheduler.h | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/scheduler.h b/src/scheduler.h index cfa3ee0e..5c81164a 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -243,34 +243,11 @@ class Scheduler : public GlobAlloc, public Callee { futex_lock(&schedLock); } - //############################################################### - //jz: consider sleep threads for avoiding deadlocks + // jz: wake up sleeping threads to avoid deadlock if (th->state == SLEEPING) { - /// info("[G %d] finish function ----- jz: ----- \n ################################ \n detected sleeping thread when called finish, pid %d, tid %d, gid %d, sleepQueue size: %lu", gid, pid, tid, gid, sleepQueue.size()); - printState(); sleepQueue.remove(th); th->state = BLOCKED; - info("[G %d] finish function ----- jz: ----- \n ################################ \n wakeup SLEEPING thread and is converted to be BLOCKED, pid %d, tid %d, gid %d, sleepQueue size: %lu \n ################################ \n", gid, pid, tid, gid, sleepQueue.size()); - printState(); - - assert(th->state == BLOCKED); - - ContextInfo* ctx = schedThread(th); - if (ctx) { - schedule(th, ctx); - zinfo->cores[ctx->cid]->join(); - //////info("[G %d] join function ----- jz: ----- do join: a BLOCKED thread scheduled to be a RUNNING thread, pid %d, tid %d, gid %d", gid, pid, tid, gid); - //////printState(); - bar.join(ctx->cid, &schedLock); //releases lock - } else { - th->state = QUEUED; - runQueue.push_back(th); - waitForContext(th); //releases lock, might join - ////info("[G %d] join function ----- jz: ----- do join: a BLOCKED thread scheduled to be a QUEUE thread, waiting for a avaliable context, pid %d, tid %d, gid %d", gid, pid, tid, gid); - ////printState(); - } } - //################################################################# //dsm: Added this check; the normal sequence is leave, finish, but with fastFwd you never know if (th->state == RUNNING) {