[pypy-commit] pypy default: Performance: avoid releasing the GIL around thread.lock.release(),
arigo
noreply at buildbot.pypy.org
Wed Feb 18 12:34:13 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r75975:b190e63c3c3c
Date: 2015-02-18 11:41 +0100
http://bitbucket.org/pypy/pypy/changeset/b190e63c3c3c/
Log: Performance: avoid releasing the GIL around thread.lock.release(),
as well as around uncontended thread.lock.acquire().
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -59,16 +59,18 @@
rffi.INT,
releasegil=True) # release the GIL
c_thread_releaselock = llexternal('RPyThreadReleaseLock', [TLOCKP], lltype.Void,
- releasegil=True) # release the GIL
+ _nowrapper=True) # *don't* release the GIL
# another set of functions, this time in versions that don't cause the
-# GIL to be released. To use to handle the GIL lock itself.
+# GIL to be released. Used to be there to handle the GIL lock itself,
+# but that was changed (see rgil.py). Now here for performance only.
c_thread_acquirelock_NOAUTO = llexternal('RPyThreadAcquireLock',
[TLOCKP, rffi.INT], rffi.INT,
_nowrapper=True)
-c_thread_releaselock_NOAUTO = llexternal('RPyThreadReleaseLock',
- [TLOCKP], lltype.Void,
- _nowrapper=True)
+c_thread_acquirelock_timed_NOAUTO = llexternal('RPyThreadAcquireLockTimed',
+ [TLOCKP, rffi.LONGLONG, rffi.INT],
+ rffi.INT, _nowrapper=True)
+c_thread_releaselock_NOAUTO = c_thread_releaselock
def allocate_lock():
@@ -131,9 +133,21 @@
self._lock = ll_lock
def acquire(self, flag):
- res = c_thread_acquirelock(self._lock, int(flag))
+ # fast-path: try to acquire the lock without releasing the GIL
+ res = c_thread_acquirelock_timed_NOAUTO(
+ self._lock,
+ rffi.cast(rffi.LONGLONG, 0),
+ rffi.cast(rffi.INT, 0))
res = rffi.cast(lltype.Signed, res)
- return bool(res)
+ if not flag:
+ # acquire(False): return a boolean that says if it worked
+ return res != 0
+ else:
+ # acquire(True): if res == 0, we must invoke the slow-path
+ # releasing the GIL. This is done with conditional_call() to
+ # avoid JIT branches.
+ jit.conditional_call(res == 0, c_thread_acquirelock, self._lock, 1)
+ return True
def acquire_timed(self, timeout):
"""Timeout is in microseconds. Returns 0 in case of failure,
More information about the pypy-commit
mailing list