[pypy-svn] r54893 - in pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk: . test
tverwaes at codespeak.net
tverwaes at codespeak.net
Sun May 18 17:22:45 CEST 2008
Author: tverwaes
Date: Sun May 18 17:22:45 2008
New Revision: 54893
Modified:
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/error.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_wrapper.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/wrapper.py
Log:
(cfbolz, tverwaes) add suspend, signal, highest_priority_process and wait. Add
way to signal fatal and wrapper errors with messages
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/error.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/error.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/error.py Sun May 18 17:22:45 2008
@@ -15,3 +15,10 @@
class WrappingError(PrimitiveFailedError):
pass
+class WrapperException(SmalltalkException):
+ def __init__(self, msg):
+ self.msg = msg
+
+class FatalError(SmalltalkException):
+ def __init__(self, msg):
+ self.msg = msg
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_wrapper.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_wrapper.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_wrapper.py Sun May 18 17:22:45 2008
@@ -3,6 +3,7 @@
from pypy.lang.smalltalk import model
from pypy.lang.smalltalk import objtable, utility
from pypy.lang.smalltalk import interpreter
+from pypy.lang.smalltalk.error import WrapperException, FatalError
def test_simpleread():
w_o = model.W_PointersObject(None, 2)
@@ -11,8 +12,8 @@
assert w.read(0) == "hello"
w.write(1, "b")
assert w.read(1) == "b"
- py.test.raises(IndexError, "w.read(2)")
- py.test.raises(IndexError, "w.write(2, \"test\")")
+ py.test.raises(WrapperException, "w.read(2)")
+ py.test.raises(WrapperException, "w.write(2, \"test\")")
def test_accessor_generators():
w_o = model.W_PointersObject(None, 1)
@@ -102,7 +103,11 @@
scheduler.write(0, priority_list.w_self)
return scheduler
-
+def new_semaphore(excess_signals=0):
+ w_semaphore = model.W_PointersObject(None, 3)
+ semaphore = wrapper.SemaphoreWrapper(w_semaphore)
+ semaphore.store_excess_signals(utility.wrap_int(excess_signals))
+ return semaphore
class TestScheduler(object):
def setup_method(self, meth):
@@ -120,12 +125,9 @@
assert process_list.first_link() is process_list.last_link()
assert process_list.first_link() is process.w_self
- def old_new_process_consistency(self, process, old_process, interp,
+ def new_process_consistency(self, process, old_process, interp,
old_active_context, new_active_context):
scheduler = wrapper.scheduler()
- assert old_process.suspended_context() is old_active_context
- priority_list = scheduler.get_process_list(old_process.priority())
- assert priority_list.first_link() is old_process.w_self
assert interp.w_active_context() is new_active_context
assert scheduler.active_process() is process.w_self
priority_list = wrapper.scheduler().get_process_list(process.priority())
@@ -134,35 +136,64 @@
# The caller of activate is responsible
assert priority_list.first_link() is process.w_self
- def test_activate(self):
+ def old_process_consistency(self, old_process, old_process_context):
+ assert old_process.suspended_context() is old_process_context
+ priority_list = wrapper.scheduler().get_process_list(old_process.priority())
+ assert priority_list.first_link() is old_process.w_self
+
+ def make_processes(self, sleepingpriority, runningpriority,
+ sleepingcontext, runningcontext):
interp = interpreter.Interpreter()
scheduler = wrapper.scheduler()
- process = new_process(priority=2, w_suspended_context=objtable.w_false)
- process.put_to_sleep()
- old_process = new_process(priority=3)
- scheduler.store_active_process(old_process.w_self)
- interp.store_w_active_context(objtable.w_true)
- process.activate(interp)
+ sleeping = new_process(priority=sleepingpriority,
+ w_suspended_context=sleepingcontext)
+ sleeping.put_to_sleep()
+ running = new_process(priority=runningpriority)
+ scheduler.store_active_process(running.w_self)
+ interp.store_w_active_context(runningcontext)
+
+ return interp, sleeping, running
+
- self.old_new_process_consistency(process, old_process, interp,
+ def test_activate(self):
+ interp, process, old_process = self.make_processes(4, 2, objtable.w_false, objtable.w_true)
+ process.activate(interp)
+ self.new_process_consistency(process, old_process, interp,
objtable.w_true, objtable.w_false)
def test_resume(self):
- interp = interpreter.Interpreter()
- scheduler = wrapper.scheduler()
- process = new_process(priority=4, w_suspended_context=objtable.w_false)
- process.put_to_sleep()
- old_process = new_process(priority=2)
- scheduler.store_active_process(old_process.w_self)
- interp.store_w_active_context(objtable.w_true)
-
+ interp, process, old_process = self.make_processes(4, 2, objtable.w_false, objtable.w_true)
process.resume(interp)
- self.old_new_process_consistency(process, old_process, interp,
+ self.new_process_consistency(process, old_process, interp,
objtable.w_true, objtable.w_false)
+ self.old_process_consistency(old_process, objtable.w_true)
# Does not reactivate old_process because lower priority
old_process.resume(interp)
- self.old_new_process_consistency(process, old_process, interp,
+ self.new_process_consistency(process, old_process, interp,
objtable.w_true, objtable.w_false)
+ self.old_process_consistency(old_process, objtable.w_true)
-
+ def test_semaphore_excess_signal(self):
+ semaphore = new_semaphore()
+
+ semaphore.signal(None)
+ assert utility.unwrap_int(semaphore.excess_signals()) == 1
+
+ def test_highest_priority(self):
+ py.test.raises(FatalError, wrapper.scheduler().highest_priority_process)
+ interp, process, old_process = self.make_processes(4, 2, objtable.w_false, objtable.w_true)
+ process.put_to_sleep()
+ old_process.put_to_sleep()
+ highest = wrapper.scheduler().highest_priority_process()
+ assert highest is process.w_self
+ highest = wrapper.scheduler().highest_priority_process()
+ assert highest is old_process.w_self
+ py.test.raises(FatalError, wrapper.scheduler().highest_priority_process)
+
+ def test_semaphore_wait(self):
+ semaphore = new_semaphore()
+ interp, process, old_process = self.make_processes(4, 2, objtable.w_false, objtable.w_true)
+ semaphore.wait(interp)
+ assert semaphore.first_link() is old_process.w_self
+ assert wrapper.scheduler().active_process() is process.w_self
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/wrapper.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/wrapper.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/wrapper.py Sun May 18 17:22:45 2008
@@ -1,24 +1,24 @@
from pypy.lang.smalltalk import model
-from pypy.lang.smalltalk import utility
+from pypy.lang.smalltalk import utility, objtable
+from pypy.lang.smalltalk.error import FatalError, WrapperException
class Wrapper(object):
def __init__(self, w_self):
- assert isinstance(w_self, model.W_PointersObject)
+ if not isinstance(w_self, model.W_PointersObject):
+ raise WrapperException("Unexpected instance given to wrapper")
self.w_self = w_self
def read(self, index0):
try:
return self.w_self._vars[index0]
except IndexError:
- # XXX nicer errormessage
- raise
+ raise WrapperException("Unexpected instance layout. Too small")
def write(self, index0, w_new):
try:
self.w_self._vars[index0] = w_new
except IndexError:
- # XXX nicer errormessage
- raise
+ raise WrapperException("Unexpected instance layout. Too small")
def make_getter(index0):
def getter(self):
@@ -53,24 +53,32 @@
def activate(self, interp):
from pypy.lang.smalltalk import objtable
sched = scheduler()
- w_old_process = sched.active_process()
sched.store_active_process(self.w_self)
- old_process = ProcessWrapper(w_old_process)
- old_process.store_suspended_context(interp.w_active_context())
- old_process.put_to_sleep()
interp.store_w_active_context(self.suspended_context())
self.store_suspended_context(objtable.w_nil)
+ def deactivate(self, interp):
+ self.put_to_sleep()
+ self.store_suspended_context(interp.w_active_context())
+
def resume(self, interp):
sched = scheduler()
active_process = ProcessWrapper(sched.active_process())
active_priority = active_process.priority()
priority = self.priority()
if priority > active_priority:
+ active_process.deactivate(interp)
self.activate(interp)
else:
self.put_to_sleep()
+ def is_active_process(self):
+ return self.w_self is scheduler().active_process()
+
+ def suspend(self, interp):
+ assert self.is_active_process()
+ assert self.my_list() is objtable.w_nil
+ ProcessWrapper(scheduler().highest_priority_process()).activate(interp)
class LinkedListWrapper(Wrapper):
first_link, store_first_link = make_getter_setter(0)
@@ -117,6 +125,18 @@
lists = self.priority_list()
return ProcessListWrapper(Wrapper(lists).read(priority))
+ def highest_priority_process(self):
+ w_lists = self.priority_list()
+ # Asserts as W_PointersObject
+ lists = Wrapper(w_lists)
+
+ for i in range(len(w_lists._vars) -1, -1, -1):
+ process_list = ProcessListWrapper(lists.read(i))
+ if not process_list.is_empty_list():
+ return process_list.remove_first_link_of_list()
+
+ raise FatalError("Scheduler could not find a runnable process")
+
def scheduler():
from pypy.lang.smalltalk import objtable
w_association = objtable.objtable["w_schedulerassociationpointer"]
@@ -127,7 +147,7 @@
class SemaphoreWrapper(LinkedListWrapper):
- excess_signals, store_excess_signals = make_getter_setter(0)
+ excess_signals, store_excess_signals = make_getter_setter(2)
def signal(self, interp):
if self.is_empty_list():
@@ -135,13 +155,14 @@
w_value = utility.wrap_int(utility.unwrap_int(w_value) + 1)
self.store_excess_signals(w_value)
else:
- self.resume(self.remove_first_link_of_list(), interp)
+ self.remove_first_link_of_list().resume(interp)
- def wait(self, w_process, interp):
+ def wait(self, interp):
excess = utility.unwrap_int(self.excess_signals())
+ w_process = scheduler().active_process()
if excess > 0:
w_excess = utility.wrap_int(excess - 1)
self.store_excess_signals(w_excess)
else:
self.add_last_link(w_process)
- ProcessWrapper(w_process).put_to_sleep()
+ ProcessWrapper(w_process).suspend(interp)
More information about the Pypy-commit
mailing list