[pypy-svn] r47049 - in pypy/dist/pypy: module/thread rpython/lltypesystem

arigo at codespeak.net arigo at codespeak.net
Sun Sep 30 22:14:31 CEST 2007


Author: arigo
Date: Sun Sep 30 22:14:29 2007
New Revision: 47049

Modified:
   pypy/dist/pypy/module/thread/ll_thread.py
   pypy/dist/pypy/rpython/lltypesystem/rffi.py
Log:
Make an explicit flag 'threadsafe' to know if we can release the GIL
around an external function call or not.  The default is normally True
but see also the comment.


Modified: pypy/dist/pypy/module/thread/ll_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/ll_thread.py	(original)
+++ pypy/dist/pypy/module/thread/ll_thread.py	Sun Sep 30 22:14:29 2007
@@ -47,13 +47,13 @@
 # GIL to be released.  To use to handle the GIL lock itself.
 c_thread_acquirelock_NOAUTO = llexternal('RPyThreadAcquireLock',
                                          [TLOCKP, rffi.INT], rffi.INT,
-                                         sandboxsafe=True)
+                                         threadsafe=False)
 c_thread_releaselock_NOAUTO = llexternal('RPyThreadReleaseLock',
                                          [TLOCKP], lltype.Void,
-                                         sandboxsafe=True)
+                                         threadsafe=False)
 c_thread_fused_releaseacquirelock_NOAUTO = llexternal(
      'RPyThreadFusedReleaseAcquireLock', [TLOCKP], lltype.Void,
-                                         sandboxsafe=True)
+                                         threadsafe=False)
 
 def allocate_lock():
     ll_lock = lltype.malloc(TLOCKP.TO, flavor='raw')

Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py	Sun Sep 30 22:14:29 2007
@@ -28,7 +28,8 @@
 
 def llexternal(name, args, result, _callable=None, sources=[], includes=[],
                libraries=[], include_dirs=[], sandboxsafe=False,
-               canraise=False, _nowrapper=False, calling_conv='c'):
+               canraise=False, _nowrapper=False, calling_conv='c',
+               threadsafe='auto'):
     """Build an external function that will invoke the C function 'name'
     with the given 'args' types and 'result' type.
 
@@ -37,6 +38,12 @@
     CCHARP argument is expected, and the C function receives a 'const char*'
     pointing to a read-only null-terminated character of arrays, as usual
     for C.
+
+    threadsafe: whether it's ok to release the GIL around the call.
+                Default is yes, unless sandboxsafe is set, in which case
+                we consider that the function is really short-running and
+                don't bother releasing the GIL.  An explicit True or False
+                overrides this logic.
     """
     ext_type = lltype.FuncType(args, result)
     if _callable is None:
@@ -56,7 +63,16 @@
     if _nowrapper:
         return funcptr
 
-    invoke_around_handlers = not sandboxsafe
+    if threadsafe in (False, True):
+        # invoke the around-handlers, which release the GIL, if and only if
+        # the C function is thread-safe.
+        invoke_around_handlers = threadsafe
+    else:
+        # default case:
+        # invoke the around-handlers only for "not too small" external calls;
+        # sandboxsafe is a hint for "too-small-ness" (e.g. math functions).
+        invoke_around_handlers = not sandboxsafe
+
     unrolling_arg_tps = unrolling_iterable(enumerate(args))
     def wrapper(*args):
         # XXX the next line is a workaround for the annotation bug



More information about the Pypy-commit mailing list