<s> import py <EOL> import os <EOL> from pypy . rpython . lltypesystem . llmemory import NULL <EOL> from pypy . rlib . rstack import yield_current_frame_to_caller <EOL> from pypy . translator . tool import cbuild <EOL> from pypy . translator . c import gc <EOL> from pypy . translator . c . test import test_stackless <EOL> loops = <NUM_LIT:1> <EOL> def debug ( s ) : <EOL> os . write ( <NUM_LIT:2> , "<STR_LIT>" % s ) <EOL> class Globals : <EOL> def __init__ ( self ) : <EOL> pass <EOL> globals = Globals ( ) <EOL> globals . count = <NUM_LIT:0> <EOL> class ThreadLocals ( object ) : <EOL> pass <EOL> threadlocals = ThreadLocals ( ) <EOL> class Resumable ( object ) : <EOL> def __init__ ( self ) : <EOL> self . alive = False <EOL> def start ( self ) : <EOL> self . resumable = self . _start ( ) <EOL> def _start ( self ) : <EOL> threadlocals . cc = yield_current_frame_to_caller ( ) <EOL> self . fn ( ) <EOL> return threadlocals . cc <EOL> def suspend ( self ) : <EOL> threadlocals . cc = threadlocals . cc . switch ( ) <EOL> def resume ( self ) : <EOL> self . resumable = self . resumable . switch ( ) <EOL> self . alive = self . resumable is not None <EOL> def fn ( self ) : <EOL> pass <EOL> class Tasklet ( Resumable ) : <EOL> def __init__ ( self ) : <EOL> Resumable . __init__ ( self ) <EOL> self . blocked = <NUM_LIT:0> <EOL> self . remove = False <EOL> def start ( self ) : <EOL> Resumable . start ( self ) <EOL> scheduler . add_tasklet ( self ) <EOL> def run ( self ) : <EOL> Resumable . start ( self ) <EOL> scheduler . run_immediately ( self ) <EOL> def suspend_and_remove ( self , remove ) : <EOL> self . remove = remove <EOL> self . suspend ( ) <EOL> def resume ( self ) : <EOL> assert not self . remove <EOL> Resumable . resume ( self ) <EOL> return self . alive and not self . remove <EOL> class Channel : <EOL> def __init__ ( self ) : <EOL> self . queue = [ ] <EOL> self . balance = <NUM_LIT:0> <EOL> def send ( self , value ) : <EOL> self . balance += <NUM_LIT:1> <EOL> if self . balance <= <NUM_LIT:0> : <EOL> t = self . queue . pop ( <NUM_LIT:0> ) <EOL> t . data = value <EOL> t . blocked = <NUM_LIT:0> <EOL> t . remove = False <EOL> scheduler . run_immediately ( t ) <EOL> scheduler . schedule ( ) <EOL> t = getcurrent ( ) <EOL> assert t . blocked == <NUM_LIT:0> <EOL> else : <EOL> t = getcurrent ( ) <EOL> assert isinstance ( t , Tasklet ) <EOL> t . data = value <EOL> self . queue . append ( t ) <EOL> t . blocked = <NUM_LIT:1> <EOL> schedule_remove ( ) <EOL> assert t == getcurrent ( ) <EOL> assert t . blocked == <NUM_LIT:0> <EOL> def receive ( self ) : <EOL> self . balance -= <NUM_LIT:1> <EOL> if self . balance >= <NUM_LIT:0> : <EOL> t = self . queue . pop ( <NUM_LIT:0> ) <EOL> t . blocked = <NUM_LIT:0> <EOL> t . remove = False <EOL> data = t . data <EOL> scheduler . add_tasklet ( t ) <EOL> return data <EOL> else : <EOL> t = getcurrent ( ) <EOL> assert isinstance ( t , Tasklet ) <EOL> self . queue . append ( t ) <EOL> t . blocked = - <NUM_LIT:1> <EOL> schedule_remove ( ) <EOL> assert t == getcurrent ( ) <EOL> assert t . blocked == <NUM_LIT:0> <EOL> return t . data <EOL> class Scheduler ( object ) : <EOL> def __init__ ( self ) : <EOL> self . runnables = [ ] <EOL> self . current_tasklet = None <EOL> self . immediately_schedule = None <EOL> def add_tasklet ( self , tasklet ) : <EOL> self . runnables . append ( tasklet ) <EOL> def run_immediately ( self , tasklet ) : <EOL> self . immediately_schedule = tasklet <EOL> def run ( self ) : <EOL> while self . runnables : <EOL> runnables = self . runnables <EOL> self . runnables = [ ] <EOL> count = <NUM_LIT:0> <EOL> for t in runnables : <EOL> assert self . current_tasklet is None <EOL> self . current_tasklet = t <EOL> if t . resume ( ) : <EOL> self . runnables . append ( self . current_tasklet ) <EOL> self . current_tasklet = None <EOL> count += <NUM_LIT:1> <EOL> if self . immediately_schedule : <EOL> self . runnables = [ self . immediately_schedule ] + runnables [ count : ] + self . runnables <EOL> self . immediately_schedule = None <EOL> break <EOL> def schedule ( self , remove = False ) : <EOL> assert self . current_tasklet is not None <EOL> self . current_tasklet . suspend_and_remove ( remove ) <EOL> scheduler = Scheduler ( ) <EOL> def schedule ( ) : <EOL> scheduler . schedule ( ) <EOL> def schedule_remove ( ) : <EOL> scheduler . schedule ( remove = True ) <EOL> def run ( ) : <EOL> scheduler . run ( ) <EOL> def getcurrent ( ) : <EOL> return scheduler . current_tasklet <EOL> class TestTasklets ( test_stackless . StacklessTest ) : <EOL> backendopt = True <EOL> def test_simplex ( self ) : <EOL> class Tasklet1 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> schedule ( ) <EOL> def f ( ) : <EOL> for ii in range ( loops ) : <EOL> Tasklet1 ( ) . start ( ) <EOL> run ( ) <EOL> return globals . count == loops * <NUM_LIT:5> <EOL> res = self . wrap_stackless_function ( f ) <EOL> print res <EOL> assert res == <NUM_LIT:1> <EOL> def test_multiple_simple ( self ) : <EOL> class Tasklet1 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> schedule ( ) <EOL> class Tasklet2 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> schedule ( ) <EOL> globals . count += <NUM_LIT:1> <EOL> class Tasklet3 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> schedule ( ) <EOL> for ii in range ( <NUM_LIT:10> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> if ii % <NUM_LIT:2> : <EOL> schedule ( ) <EOL> schedule ( ) <EOL> def f ( ) : <EOL> for ii in range ( loops ) : <EOL> Tasklet1 ( ) . start ( ) <EOL> Tasklet2 ( ) . start ( ) <EOL> Tasklet3 ( ) . start ( ) <EOL> run ( ) <EOL> return globals . count == loops * <NUM_LIT> <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_schedule_remove ( self ) : <EOL> class Tasklet1 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:20> ) : <EOL> if ii < <NUM_LIT:10> : <EOL> schedule ( ) <EOL> else : <EOL> schedule_remove ( ) <EOL> globals . count += <NUM_LIT:1> <EOL> def f ( ) : <EOL> for ii in range ( loops ) : <EOL> Tasklet1 ( ) . start ( ) <EOL> run ( ) <EOL> for ii in range ( loops ) : <EOL> Tasklet1 ( ) . start ( ) <EOL> run ( ) <EOL> return globals . count == loops * <NUM_LIT:10> * <NUM_LIT:2> <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_run_immediately ( self ) : <EOL> globals . intermediate = <NUM_LIT:0> <EOL> class Tasklet1 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:20> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> schedule ( ) <EOL> class RunImmediate ( Tasklet ) : <EOL> def fn ( self ) : <EOL> globals . intermediate = globals . count <EOL> schedule ( ) <EOL> class Tasklet2 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:20> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> if ii == <NUM_LIT:10> : <EOL> RunImmediate ( ) . run ( ) <EOL> schedule ( ) <EOL> def f ( ) : <EOL> Tasklet2 ( ) . start ( ) <EOL> for ii in range ( loops ) : <EOL> Tasklet1 ( ) . start ( ) <EOL> run ( ) <EOL> total_expected = ( loops + <NUM_LIT:1> ) * <NUM_LIT:20> <EOL> return ( globals . intermediate == total_expected / <NUM_LIT:2> + <NUM_LIT:1> and <EOL> globals . count == total_expected ) <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_channel1 ( self ) : <EOL> ch = Channel ( ) <EOL> class Tasklet1 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> ch . send ( ii ) <EOL> class Tasklet2 ( Tasklet ) : <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:6> ) : <EOL> globals . count += ch . receive ( ) <EOL> def f ( ) : <EOL> Tasklet2 ( ) . start ( ) <EOL> Tasklet1 ( ) . start ( ) <EOL> run ( ) <EOL> return ( globals . count == <NUM_LIT:10> ) <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_channel2 ( self ) : <EOL> class Tasklet1 ( Tasklet ) : <EOL> def __init__ ( self , ch ) : <EOL> self . ch = ch <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> self . ch . send ( ii ) <EOL> class Tasklet2 ( Tasklet ) : <EOL> def __init__ ( self , ch ) : <EOL> self . ch = ch <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:6> ) : <EOL> res = self . ch . receive ( ) <EOL> globals . count += res <EOL> def f ( ) : <EOL> ch = Channel ( ) <EOL> Tasklet1 ( ch ) . start ( ) <EOL> Tasklet2 ( ch ) . start ( ) <EOL> run ( ) <EOL> return globals . count == <NUM_LIT:10> <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_channel3 ( self ) : <EOL> class Tasklet1 ( Tasklet ) : <EOL> def __init__ ( self , ch ) : <EOL> self . ch = ch <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> self . ch . send ( ii ) <EOL> class Tasklet2 ( Tasklet ) : <EOL> def __init__ ( self , ch ) : <EOL> self . ch = ch <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:16> ) : <EOL> res = self . ch . receive ( ) <EOL> globals . count += res <EOL> def f ( ) : <EOL> ch = Channel ( ) <EOL> Tasklet1 ( ch ) . start ( ) <EOL> Tasklet1 ( ch ) . start ( ) <EOL> Tasklet1 ( ch ) . start ( ) <EOL> Tasklet2 ( ch ) . start ( ) <EOL> run ( ) <EOL> return globals . count == <NUM_LIT:30> <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_flexible_channels ( self ) : <EOL> """<STR_LIT>""" <EOL> class A ( object ) : <EOL> def __init__ ( self , num ) : <EOL> self . num = num <EOL> def getvalue ( self ) : <EOL> res = self . num <EOL> self . num *= <NUM_LIT:2> <EOL> return res <EOL> class Data ( object ) : <EOL> pass <EOL> class IntData ( Data ) : <EOL> def __init__ ( self , i ) : <EOL> self . int = i <EOL> class StringData ( Data ) : <EOL> def __init__ ( self , s ) : <EOL> self . str = s <EOL> class InstanceData ( Data ) : <EOL> def __init__ ( self , i ) : <EOL> self . instance = i <EOL> class Tasklet1 ( Tasklet ) : <EOL> def __init__ ( self , ch ) : <EOL> self . ch = ch <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> self . ch . send ( IntData ( ii ) ) <EOL> class Tasklet2 ( Tasklet ) : <EOL> def __init__ ( self , ch , strdata ) : <EOL> self . ch = ch <EOL> self . strdata = strdata <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> self . ch . send ( StringData ( self . strdata ) ) <EOL> class Tasklet3 ( Tasklet ) : <EOL> def __init__ ( self , ch , instance ) : <EOL> self . ch = ch <EOL> self . instance = instance <EOL> def fn ( self ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> self . ch . send ( InstanceData ( self . instance ) ) <EOL> class Server ( Tasklet ) : <EOL> def __init__ ( self , ch ) : <EOL> self . ch = ch <EOL> self . loop = True <EOL> def stop ( self ) : <EOL> self . loop = False <EOL> def fn ( self ) : <EOL> while self . loop : <EOL> data = self . ch . receive ( ) <EOL> if isinstance ( data , IntData ) : <EOL> globals . count += data . int <EOL> elif isinstance ( data , StringData ) : <EOL> globals . count += len ( data . str ) <EOL> elif isinstance ( data , InstanceData ) : <EOL> globals . count += data . instance . getvalue ( ) <EOL> ch = Channel ( ) <EOL> server = Server ( ch ) <EOL> def f ( ) : <EOL> Tasklet1 ( ch ) . start ( ) <EOL> Tasklet2 ( ch , "<STR_LIT>" ) . start ( ) <EOL> Tasklet2 ( ch , "<STR_LIT>" ) . start ( ) <EOL> Tasklet3 ( ch , A ( <NUM_LIT:1> ) ) . start ( ) <EOL> server . start ( ) <EOL> run ( ) <EOL> return globals . count == ( <NUM_LIT:0> + <NUM_LIT:1> + <NUM_LIT:2> + <NUM_LIT:3> + <NUM_LIT:4> ) + ( <NUM_LIT:5> * <NUM_LIT:4> ) + ( <NUM_LIT:5> * <NUM_LIT:3> ) + ( <NUM_LIT:1> + <NUM_LIT:2> + <NUM_LIT:4> + <NUM_LIT:8> + <NUM_LIT:16> ) <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> <EOL> def test_original_api ( self ) : <EOL> class TaskletAsFunction ( Tasklet ) : <EOL> def __init__ ( self , fn ) : <EOL> self . redirect_fn = fn <EOL> def fn ( self ) : <EOL> self . redirect_fn ( ) <EOL> def tasklet ( fn ) : <EOL> return TaskletAsFunction ( fn ) <EOL> def simple ( ) : <EOL> for ii in range ( <NUM_LIT:5> ) : <EOL> globals . count += <NUM_LIT:1> <EOL> schedule ( ) <EOL> def f ( ) : <EOL> for ii in range ( loops ) : <EOL> tasklet ( simple ) . start ( ) <EOL> run ( ) <EOL> run ( ) <EOL> return globals . count == loops * <NUM_LIT:5> <EOL> res = self . wrap_stackless_function ( f ) <EOL> assert res == <NUM_LIT:1> </s>
