We now check the lock before releasing our jwack token.
That way, if everything is locked, we can determine that with a single token, reducing context switches. But mostly this is good because the code is simpler.
This commit is contained in:
parent
c10875d7d7
commit
116e7e5f13
2 changed files with 42 additions and 33 deletions
20
jwack.py
20
jwack.py
|
|
@ -105,10 +105,10 @@ def wait(want_token):
|
|||
|
||||
def get_token(reason):
|
||||
global _mytokens
|
||||
setup(1)
|
||||
while 1:
|
||||
if _mytokens >= 1:
|
||||
_debug('(%r) used my own token...\n' % reason)
|
||||
_mytokens -= 1
|
||||
return
|
||||
_debug('(%r) waiting for tokens...\n' % reason)
|
||||
wait(want_token=1)
|
||||
|
|
@ -118,6 +118,7 @@ def get_token(reason):
|
|||
raise Exception('unexpected EOF on token read')
|
||||
if b:
|
||||
break
|
||||
_mytokens += 1
|
||||
_debug('(%r) got a token (%r).\n' % (reason, b))
|
||||
|
||||
|
||||
|
|
@ -171,24 +172,29 @@ class Job:
|
|||
return 'Job(%s,%d)' % (self.name, self.pid)
|
||||
|
||||
|
||||
def start_job(reason, jobfunc, donefunc):
|
||||
setup(1)
|
||||
def start_job(reason, lock, jobfunc, donefunc):
|
||||
global _mytokens
|
||||
assert(lock.owned)
|
||||
get_token(reason)
|
||||
assert(_mytokens >= 1)
|
||||
_mytokens -= 1
|
||||
r,w = os.pipe()
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
# child
|
||||
os.close(r)
|
||||
rv = 201
|
||||
try:
|
||||
try:
|
||||
jobfunc()
|
||||
os._exit(0)
|
||||
except Exception, e:
|
||||
rv = jobfunc() or 0
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
lock.unlock()
|
||||
finally:
|
||||
os._exit(201)
|
||||
os._exit(rv)
|
||||
# else we're the parent process
|
||||
lock.owned = False # child owns it now
|
||||
os.close(w)
|
||||
pd = Job(reason, pid, donefunc)
|
||||
_waitfds[r] = pd
|
||||
|
|
|
|||
55
redo.py
55
redo.py
|
|
@ -140,22 +140,14 @@ def _build(t):
|
|||
|
||||
|
||||
def build(t):
|
||||
lock = state.Lock(t)
|
||||
lock.trylock()
|
||||
if not lock.owned:
|
||||
log('%s (locked...)\n' % relpath(t, vars.STARTDIR))
|
||||
os._exit(199)
|
||||
try:
|
||||
try:
|
||||
return _build(t)
|
||||
except BuildError, e:
|
||||
err('%s\n' % e)
|
||||
finally:
|
||||
lock.unlock()
|
||||
os._exit(1)
|
||||
return _build(t)
|
||||
except BuildError, e:
|
||||
err('%s\n' % e)
|
||||
return 1
|
||||
|
||||
|
||||
def main():
|
||||
def main(targets, buildfunc):
|
||||
retcode = [0] # a list so that it can be reassigned from done()
|
||||
if vars.SHUFFLE:
|
||||
random.shuffle(targets)
|
||||
|
|
@ -169,30 +161,41 @@ def main():
|
|||
err('%s: exit code was %r\n' % (t, rv))
|
||||
retcode[0] = 1
|
||||
|
||||
for t in targets:
|
||||
for i in range(len(targets)):
|
||||
t = targets[i]
|
||||
if os.path.exists('%s/all.do' % t):
|
||||
# t is a directory, but it has a default target
|
||||
t = '%s/all' % t
|
||||
tt = t
|
||||
jwack.start_job(t, lambda: build(t), lambda t,rv: done(t,rv))
|
||||
targets[i] = '%s/all' % t
|
||||
|
||||
for t in targets:
|
||||
jwack.get_token(t)
|
||||
lock = state.Lock(t)
|
||||
lock.trylock()
|
||||
if not lock.owned:
|
||||
log('%s (locked...)\n' % relpath(t, vars.STARTDIR))
|
||||
locked.append(t)
|
||||
else:
|
||||
jwack.start_job(t, lock,
|
||||
lambda: buildfunc(t), lambda t,rv: done(t,rv))
|
||||
|
||||
while locked or jwack.running():
|
||||
jwack.wait_all()
|
||||
if locked:
|
||||
t = locked.pop(0)
|
||||
l = state.Lock(t)
|
||||
while not l.owned:
|
||||
l.wait()
|
||||
l.trylock()
|
||||
assert(l.owned)
|
||||
lock = state.Lock(t)
|
||||
while not lock.owned:
|
||||
lock.wait()
|
||||
lock.trylock()
|
||||
assert(lock.owned)
|
||||
relp = relpath(t, vars.STARTDIR)
|
||||
log('%s (...unlocked!)\n' % relp)
|
||||
if state.stamped(t) == None:
|
||||
err('%s: failed in another thread\n' % relp)
|
||||
retcode[0] = 2
|
||||
l.unlock()
|
||||
lock.unlock()
|
||||
else:
|
||||
l.unlock() # build() reacquires it
|
||||
jwack.start_job(t, lambda: build(t), lambda t,rv: done(t,rv))
|
||||
jwack.start_job(t, lock,
|
||||
lambda: buildfunc(t), lambda t,rv: done(t,rv))
|
||||
return retcode[0]
|
||||
|
||||
|
||||
|
|
@ -210,7 +213,7 @@ try:
|
|||
err('invalid --jobs value: %r\n' % opt.jobs)
|
||||
jwack.setup(j)
|
||||
try:
|
||||
retcode = main()
|
||||
retcode = main(targets, build)
|
||||
finally:
|
||||
jwack.force_return_tokens()
|
||||
if retcode:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue