From c4be0050f7e985784dd6032b8735ffb55740d7ca Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Fri, 10 Dec 2010 23:04:46 -0800 Subject: [PATCH] Release the jwack token when doing a synchronous lock wait. Although we were deadlock-free before, under some circumstances we'd end up holding a perfectly good token while in sync wait; that would reduce our parallelism for no good reason. So give back our tokens before waiting for anybody else. --- builder.py | 10 +++++++++- jwack.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/builder.py b/builder.py index 416120f..8f34c59 100644 --- a/builder.py +++ b/builder.py @@ -273,10 +273,18 @@ def main(targets, shouldbuildfunc): fid,t = locked.pop(0) lock = state.Lock(fid) lock.trylock() - if not lock.owned: + while not lock.owned: if vars.DEBUG_LOCKS: warn('%s (WAITING)\n' % _nice(t)) + # this sequence looks a little silly, but the idea is to + # give up our personal token while we wait for the lock to + # be released; but we should never run get_token() while + # holding a lock, or we could cause deadlocks. + jwack.release_mine() lock.waitlock() + lock.unlock() + jwack.get_token(t) + lock.trylock() assert(lock.owned) if vars.DEBUG_LOCKS: log('%s (...unlocked!)\n' % _nice(t)) diff --git a/jwack.py b/jwack.py index 797b3bd..267d18d 100644 --- a/jwack.py +++ b/jwack.py @@ -24,6 +24,13 @@ def _release(n): _mytokens = 1 +def release_mine(): + global _mytokens + assert(_mytokens >= 1) + os.write(_fds[1], 't') + _mytokens -= 1 + + def _timeout(sig, frame): pass @@ -161,9 +168,12 @@ def running(): def wait_all(): _debug("wait_all\n") while running(): + while _mytokens >= 1: + release_mine() _debug("wait_all: wait()\n") wait(want_token=0) _debug("wait_all: empty list\n") + get_token('self') # get my token back if _toplevel: bb = '' while 1: