[pypy-svn] r56132 - in pypy/branch/async-del/pypy/module/thread: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Jun 27 19:17:51 CEST 2008
Author: arigo
Date: Fri Jun 27 19:17:51 2008
New Revision: 56132
Modified:
pypy/branch/async-del/pypy/module/thread/__init__.py
pypy/branch/async-del/pypy/module/thread/gil.py
pypy/branch/async-del/pypy/module/thread/test/test_gil.py
pypy/branch/async-del/pypy/module/thread/threadlocals.py
Log:
Some progress in the thread module.
Modified: pypy/branch/async-del/pypy/module/thread/__init__.py
==============================================================================
--- pypy/branch/async-del/pypy/module/thread/__init__.py (original)
+++ pypy/branch/async-del/pypy/module/thread/__init__.py Fri Jun 27 19:17:51 2008
@@ -30,4 +30,5 @@
MixedModule.__init__(self, space, *args)
prev = space.threadlocals.getvalue()
space.threadlocals = gil.GILThreadLocals()
+ space.threadlocals.initialize(space)
space.threadlocals.setvalue(prev)
Modified: pypy/branch/async-del/pypy/module/thread/gil.py
==============================================================================
--- pypy/branch/async-del/pypy/module/thread/gil.py (original)
+++ pypy/branch/async-del/pypy/module/thread/gil.py Fri Jun 27 19:17:51 2008
@@ -9,7 +9,7 @@
from pypy.module.thread import ll_thread as thread
from pypy.module.thread.error import wrap_thread_error
-from pypy.interpreter.miscutils import Action
+from pypy.interpreter.executioncontext import PeriodicAsyncAction
from pypy.module.thread.threadlocals import OSThreadLocals
from pypy.rlib.objectmodel import invoke_around_extcall
from pypy.rlib.rposix import get_errno, set_errno
@@ -18,6 +18,10 @@
"""A version of OSThreadLocals that enforces a GIL."""
ll_GIL = thread.null_ll_lock
+ def initialize(self, space):
+ # add the GIL-releasing callback as an action on the space
+ space.actionflag.register_action(GILReleaseAction(space))
+
def setup_threads(self, space):
"""Enable threads in the object space, if they haven't already been."""
if not self.ll_GIL:
@@ -27,8 +31,6 @@
raise wrap_thread_error(space, "can't allocate GIL")
thread.acquire_NOAUTO(self.ll_GIL, True)
self.enter_thread(space) # setup the main thread
- # add the GIL-releasing callback as an action on the space
- space.pending_actions.append(GILReleaseAction(self))
result = True
else:
result = False # already set up
@@ -47,25 +49,19 @@
return result
def yield_thread(self):
- """Notification that the current thread is between two bytecodes:
- release the GIL for a little while."""
- # Other threads can run between the release() and the acquire()
- # implicit in the following external function call (which has
- # otherwise no effect).
- thread.yield_thread()
+ thread.yield_thread() # explicitly release the gil (used by test_gil)
-class GILReleaseAction(Action):
- """An action called when the current thread is between two bytecodes
- (so that it's a good time to yield some time to other threads).
+class GILReleaseAction(PeriodicAsyncAction):
+ """An action called every sys.checkinterval bytecodes. It releases
+ the GIL to give some other thread a chance to run.
"""
- repeat = True
- def __init__(self, threadlocals):
- self.threadlocals = threadlocals
-
- def perform(self):
- self.threadlocals.yield_thread()
+ def perform(self, executioncontext):
+ # Other threads can run between the release() and the acquire()
+ # implicit in the following external function call (which has
+ # otherwise no effect).
+ thread.yield_thread()
class SpaceState:
@@ -86,6 +82,7 @@
actionflag.set(flag)
spacestate = SpaceState()
+spacestate._freeze_()
# Fragile code below. We have to preserve the C-level errno manually...
Modified: pypy/branch/async-del/pypy/module/thread/test/test_gil.py
==============================================================================
--- pypy/branch/async-del/pypy/module/thread/test/test_gil.py (original)
+++ pypy/branch/async-del/pypy/module/thread/test/test_gil.py Fri Jun 27 19:17:51 2008
@@ -8,9 +8,17 @@
class FakeEC(object):
pass
+class FakeActionFlag(object):
+ def register_action(self, action):
+ pass
+ def get(self):
+ return 0
+ def set(self, x):
+ pass
+
class FakeSpace(object):
def __init__(self):
- self.pending_actions = []
+ self.actionflag = FakeActionFlag()
def _freeze_(self):
return True
def getexecutioncontext(self):
Modified: pypy/branch/async-del/pypy/module/thread/threadlocals.py
==============================================================================
--- pypy/branch/async-del/pypy/module/thread/threadlocals.py (original)
+++ pypy/branch/async-del/pypy/module/thread/threadlocals.py Fri Jun 27 19:17:51 2008
@@ -7,6 +7,7 @@
os_thread.bootstrap()."""
def __init__(self):
+ print 'FRESH NEW THREADLOCALS'
self._valuedict = {} # {thread_ident: ExecutionContext()}
self._mainthreadident = 0
self._mostrecentkey = 0 # fast minicaching for the common case
@@ -15,16 +16,20 @@
def getvalue(self):
ident = thread.get_ident()
if ident == self._mostrecentkey:
- return self._mostrecentvalue
+ result = self._mostrecentvalue
+ print '(cached)',
else:
value = self._valuedict.get(ident, None)
# slow path: update the minicache
self._mostrecentkey = ident
self._mostrecentvalue = value
- return value
+ result = value
+ print '%d => %r' % (ident, result)
+ return result
def setvalue(self, value):
ident = thread.get_ident()
+ print 'SET %d => %r' % (ident, value)
if value is not None:
if len(self._valuedict) == 0:
self._mainthreadident = ident
@@ -37,6 +42,7 @@
# update the minicache to prevent it from containing an outdated value
self._mostrecentkey = ident
self._mostrecentvalue = value
+ print self._valuedict
def getmainthreadvalue(self):
ident = self._mainthreadident
@@ -45,21 +51,19 @@
def enter_thread(self, space):
"Notification that the current thread is just starting."
ec = space.getexecutioncontext()
+ print 'ENTER_THREAD', thread.get_ident(), ec
ec.thread_exit_funcs = []
def leave_thread(self, space):
"Notification that the current thread is about to stop."
try:
ec = space.getexecutioncontext()
+ print 'LEAVE_THREAD', thread.get_ident(), ec
while ec.thread_exit_funcs:
exit_func, w_obj = ec.thread_exit_funcs.pop()
exit_func(w_obj)
finally:
- ident = thread.get_ident()
- try:
- del self._valuedict[ident]
- except KeyError:
- pass
+ self.setvalue(None)
def atthreadexit(self, space, exit_func, w_obj):
ec = space.getexecutioncontext()
More information about the Pypy-commit
mailing list