# a round robin scheduler for pf # FIXME: DEPRECATED: consider using coroutines/generators instead of # this, or proper tasks. provide >taskq # define words to run round robin tasks. # a task is a structure containing a datastack and a return stack # tasks suspend by calling yield. variable tasks variable backup-tasks : clear-tasks tasks @> backup-tasks ! () tasks ! ; clear-tasks # task queue access : >taskq tasks push ; : >>taskq tasks queue ; : taskq> tasks pop ; : task-trampoline execute ; # startup stub : make-task-rs () ['] task-trampoline xt>body + ; # entry address = stub body : make-task + make-task-rs swap 2 pack ; # ( datastack xt -- task ) : start-task make-task >taskq ; : drop-task taskq> drop ; # kill last task : swap-task taskq> taskq> swap >taskq >taskq ; # swap tasks : dup-task taskq> dup >taskq >taskq ; # control flow : yield taskq> swaptask >>taskq ; # transfers control to the next task : exit-task taskq> swaptask drop ; # exit current task # NOTE: tasks & exceptions # each task needs its own error handler, which should call # exit-task.. needs to be done in the task boot code. :noname clear-tasks ; is idle # like make-task, but in addition the words defined by the loader word # are captured on the return stack. arguments are passed to 'start' : boot-task # next words are temporary. links (code & data) will be stored on task's RS. # setup code is symbolic for ease of connecting things. mark # execute loader execute # get boot data ` start find mark> # ( ds xt.start links ) # prepare task >r + r> # ( mod.ds links ) make-task-rs swap + # ( mod.ds rs ) swap 2 pack # ( task ) ; "( datastack xt.loader -- task )\tLoad and boot a task and convert to task structure. This avoids child dicts, and stores links in task struct (RS)." , : load-task boot-task >taskq ; "( datastack xt.loader -- )\tLoad, boot and schedule a task." ,