[pypy-svn] r45337 - in pypy/dist/pypy/module/thread: . test

fijal at codespeak.net fijal at codespeak.net
Wed Jul 25 22:40:23 CEST 2007


Author: fijal
Date: Wed Jul 25 22:40:23 2007
New Revision: 45337

Added:
   pypy/dist/pypy/module/thread/ll_thread.py   (contents, props changed)
   pypy/dist/pypy/module/thread/test/test_ll_thread.py   (contents, props changed)
Log:
(intermediate) Try another approach approach at threads - implement
rffi version of locking


Added: pypy/dist/pypy/module/thread/ll_thread.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/thread/ll_thread.py	Wed Jul 25 22:40:23 2007
@@ -0,0 +1,65 @@
+
+from pypy.rpython.lltypesystem import rffi
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem.rffi import platform
+from pypy.rpython.extfunc import genericcallable
+from pypy.module.thread.os_thread import Bootstrapper
+from pypy.translator.tool.cbuild import cache_c_module
+import thread, py
+
+
+class ThreadError(Exception):
+    def __init__(self, msg):
+        self.msg = msg
+
+class Lock(object):
+    """ Container for low-level implementation
+    of a lock object
+    """
+    def __init__(self, ll_lock):
+        self._lock = ll_lock
+
+includes = ['unistd.h', 'thread.h']
+
+def setup_thread_so():
+    from pypy.tool.autopath import pypydir
+    pypydir = py.path.local(pypydir)
+    srcdir = pypydir.join('translator', 'c', 'src')
+    modname = '_thread'
+    files = [srcdir.join('thread.c')]
+    cache_c_module(files, modname, include_dirs=[str(srcdir)])
+    return str(pypydir.join('_cache', modname)) + '.so'
+libraries = [setup_thread_so()]
+
+def llexternal(name, args, result):
+    return rffi.llexternal(name, args, result, includes=includes,
+                           libraries=libraries)
+
+c_thread_start = llexternal('RPyThreadStart', [lltype.FuncType([rffi.VOIDP],
+                            rffi.VOIDP)], rffi.INT)
+
+TLOCKP = rffi.COpaque('struct RPyOpaque_ThreadLock', includes=includes)
+
+c_thread_lock_init = llexternal('RPyThreadLockInit', [TLOCKP], lltype.Void)
+c_thread_acuirelock = llexternal('RPyThreadAcquireLock', [TLOCKP, rffi.INT],
+                                 rffi.INT)
+c_thread_releaselock = llexternal('RPyThreadReleaseLock', [TLOCKP], lltype.Void)
+
+def ll_allocate_lock():
+    ll_lock = lltype.malloc(TLOCKP.TO, flavor='raw')
+    res = c_thread_lock_init(ll_lock)
+    if res == -1:
+        raise ThreadError("out of resources")
+    return Lock(ll_lock)
+
+def ll_acquire_lock(lock, waitflag):
+    return c_thread_acuirelock(lock._lock, waitflag)
+
+def ll_release_lock(lock):
+    try:
+        if ll_acquire_lock(lock, 0):
+            raise ThreadError("bad lock")
+    finally:
+        c_thread_releaselock(lock._lock)
+
+    

Added: pypy/dist/pypy/module/thread/test/test_ll_thread.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/thread/test/test_ll_thread.py	Wed Jul 25 22:40:23 2007
@@ -0,0 +1,16 @@
+
+from pypy.module.thread.ll_thread import *
+import py
+
+def test_lock():
+    l = ll_allocate_lock()
+    ok1 = ll_acquire_lock(l, 1)
+    ok2 = ll_acquire_lock(l, 0)
+    ll_release_lock(l)
+    ok3 = ll_acquire_lock(l, 0)
+    res = ok1 and not ok2 and ok3
+    assert res == 1
+
+def test_thread_error():
+    l = ll_allocate_lock()
+    py.test.raises(ThreadError, ll_release_lock, l)



More information about the Pypy-commit mailing list