Skip to content

Instantly share code, notes, and snippets.

@magiskboy
Created October 23, 2020 04:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magiskboy/db41264dd5d672d8e6f7e961404688c3 to your computer and use it in GitHub Desktop.
Save magiskboy/db41264dd5d672d8e6f7e961404688c3 to your computer and use it in GitHub Desktop.
from queue import Queue
class SystemCall:
__slots__ = ('sched', 'target')
def handle(self):
pass
class Task:
__slots__ = ('id', 'target', 'sendval')
_id = 0
def __init__(self, target):
Task._id += 1
self.id = Task._id
self.target = target
self.sendval = None
def run(self):
return self.target.send(self.sendval)
class Scheduler:
__slots__ = ('taskmap', 'ready')
def __init__(self):
self.taskmap = {}
self.ready = Queue()
def new(self, target):
task = Task(target)
self.taskmap[task.id] = task
self.schedule(task)
return task.id
def mainloop(self):
while self.taskmap:
task = self.ready.get()
try:
result = task.run()
if isinstance(result, SystemCall):
result.task = task
result.sched = self
result.handle()
continue
except StopIteration:
self.exit(task)
else:
self.schedule(task)
def schedule(self, task):
self.ready.put(task)
def exit(self, task):
print('Task %d terminated' % task.id)
del self.taskmap[task.id]
class GetTid(SystemCall):
def handle(self):
self.task.sendval = self.task.id
self.sched.schedule(self.task)
class NewTask(SystemCall):
def __init__(self, target):
self.target = target
def handle(self):
tid = self.sched.new(self.target)
self.task.sendval = tid
self.sched.schedule(self.task)
class KillTask(SystemCall):
def __init__(self, tid):
self.tid = tid
def handle(self):
task = self.sched.taskmap.get(self.tid, None)
if task:
task.target.close()
self.task.sendval = True
else:
self.task.sendval = False
self.sched.schedule(self.task)
if __name__ == '__main__':
def foo():
tid = yield GetTid()
print(f'I\'m foo and I am living in {tid} process')
for i in range(5):
print(f"Foo {tid} is in {i} step")
yield
def bar():
tid = yield GetTid()
print(f"I'm bar and I'm living in {tid} process")
yield NewTask(foo())
for i in range(3):
print(f"Bar {tid} is in {i} step")
yield
yield KillTask(1)
sched = Scheduler()
sched.new(foo())
sched.new(bar())
sched.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment