[pypy-svn] r45485 - in pypy/dist/pypy/module/thread: . test
fijal at codespeak.net
fijal at codespeak.net
Sat Aug 4 17:03:27 CEST 2007
Author: fijal
Date: Sat Aug 4 17:03:26 2007
New Revision: 45485
Modified:
pypy/dist/pypy/module/thread/ll_thread.py
pypy/dist/pypy/module/thread/test/test_ll_thread.py
Log:
Intermediate checkin, some support for thread.start_new_thread
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 Sat Aug 4 17:03:26 2007
@@ -5,8 +5,16 @@
from pypy.rpython.extfunc import genericcallable
from pypy.module.thread.os_thread import Bootstrapper
from pypy.translator.tool.cbuild import cache_c_module
+from pypy.rpython.annlowlevel import cast_instance_to_base_ptr,\
+ cast_base_ptr_to_instance
import thread, py
-
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.annotation import model as annmodel
+from pypy.rpython.lltypesystem.lltype import typeOf
+
+class BaseBootstrapper:
+ def bootstrap(self):
+ pass
class ThreadError(Exception):
def __init__(self, msg):
@@ -35,8 +43,9 @@
return rffi.llexternal(name, args, result, includes=includes,
libraries=libraries)
-c_thread_start = llexternal('RPyThreadStart', [lltype.FuncType([rffi.VOIDP],
- rffi.VOIDP)], rffi.INT)
+CALLBACK = lltype.FuncType([rffi.VOIDP], rffi.VOIDP)
+c_thread_start = llexternal('RPyThreadStart', [CALLBACK, rffi.VOIDP], rffi.INT)
+c_thread_get_ident = llexternal('RPyThreadGetIdent', [], lltype.Void)
TLOCKP = rffi.COpaque('struct RPyOpaque_ThreadLock', includes=includes)
@@ -62,4 +71,46 @@
finally:
c_thread_releaselock(lock._lock)
-
+def ll_start_new_thread(l_func, arg):
+ l_arg = cast_instance_to_base_ptr(arg)
+ ident = c_thread_start(l_func, l_arg)
+ if ident == -1:
+ raise ThreadError("can't start new thread")
+ return ident
+
+class LLStartNewThread(ExtRegistryEntry):
+ _about_ = ll_start_new_thread
+
+ def compute_result_annotation(self, s_func, s_arg):
+ bookkeeper = self.bookkeeper
+ assert s_func.is_constant(), "Cannot call ll_start_new_thread with non-constant function"
+ s_result = bookkeeper.emulate_pbc_call(bookkeeper.position_key,
+ s_func, [s_arg])
+ assert annmodel.s_None.contains(s_result), (
+ """thread.start_new_thread(f, arg): f() should return None""")
+ return annmodel.SomeInteger()
+
+ def compute_annotation_bk(self, bookkeeper):
+ return annmodel.SomePBC([bookkeeper.getdesc(self.instance)])
+
+ def specialize_call(self, hop):
+ rtyper = hop.rtyper
+ bookkeeper = rtyper.annotator.bookkeeper
+ _callable = hop.args_s[0].const
+ args_r = [rtyper.getrepr(s_arg) for s_arg in hop.args_s]
+ ll_arg = args_r[1].lowleveltype
+ _type = lltype.FuncType([ll_arg], lltype.Void)
+ funcptr = lltype.functionptr(_type, _callable.func_name,
+ _callable=_callable)
+ r_result = rtyper.getrepr(hop.s_result)
+ ll_result = r_result.lowleveltype
+ args_s = [bookkeeper.immutablevalue(i) for i in [funcptr, ll_arg]]
+ obj = rtyper.getannmixlevel().delayedfunction(
+ ll_start_new_thread, args_s, annmodel.SomeInteger())
+ vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
+ hop.exception_is_here()
+ return hop.genop('direct_call', vlist, r_result)
+
+# a simple wrapper, not to expose C functions (is this really necessary?)
+def ll_get_ident():
+ return c_thread_get_ident()
Modified: pypy/dist/pypy/module/thread/test/test_ll_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/test/test_ll_thread.py (original)
+++ pypy/dist/pypy/module/thread/test/test_ll_thread.py Sat Aug 4 17:03:26 2007
@@ -1,5 +1,6 @@
from pypy.module.thread.ll_thread import *
+from pypy.translator.c.test.test_genc import compile
import py
def test_lock():
@@ -14,3 +15,26 @@
def test_thread_error():
l = ll_allocate_lock()
py.test.raises(ThreadError, ll_release_lock, l)
+
+def test_thread_init_new():
+ """ This test works only after translation
+ """
+ py.test.skip("does not work")
+ import time
+ import thread
+
+ class X(BaseBootstrapper):
+ def __init__(self):
+ self.top = []
+
+ def bootstrap(self):
+ self.top.append(1)
+
+ def f():
+ x = X()
+ ll_start_new_thread(X.bootstrap, x)
+ time.sleep(.3)
+ return len(x.top)
+
+ fn = compile(f, [])
+ assert fn() == 1
More information about the Pypy-commit
mailing list