File: tasker.fs

package info (click to toggle)
gforth 0.3.0-4
  • links: PTS
  • area: main
  • in suites: slink
  • size: 2,972 kB
  • ctags: 743
  • sloc: ansic: 3,369; sh: 1,410; lisp: 725; makefile: 426; sed: 111
file content (69 lines) | stat: -rw-r--r-- 1,928 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
\ Multitasker                                          19aug94py

Create sleepers  sleepers A, sleepers A, 0 ,

\ LINK-TASK links task1 into the task chain of task2
: link-task ( task1 task2 -- )
  over 2@  2dup cell+ ! swap !  \ unlink task1
  2dup @ cell+ !  2dup dup @ rot 2!  ! ;

: sleep ( task -- )  sleepers  link-task ;
: wake  ( task -- )  next-task link-task ;

\ PAUSE is the task-switcher
: pause ( -- )
  rp@ fp@ lp@ sp@ save-task !
  next-task @ up! save-task @ sp!
  lp! fp! rp! ;

\ STOP sleeps a task and switches to the next
: stop ( -- )
  rp@ fp@ lp@ sp@ save-task !
  next-task @ up! save-task @ sp!
  lp! fp! rp! prev-task @ sleep ;

\ USER' computes the task offset
: user' ( 'user' -- n )
    ' >body @ postpone literal ; immediate
interpretation:
    ' >body @ ;

\ NEWTASK creates a new, sleeping task
: NewTask ( n -- Task )  dup 2* 2* udp @ + dup
  allocate throw  + >r
  r@ over - udp @ - next-task over udp @ move
  r> over user' r0 + ! dup >r
  dup r@ user' l0   + ! over -
  dup r@ user' f0   + ! over -
  dup r@ user' s0   + ! over -
  dup r@ user' normal-dp + dup >r !
   r> r@ user' dpp  + ! + $10 +
      r@ user' >tib + !
  r> dup 2dup 2! dup sleep ;

: kill-task
  next-task @ up! save-task @ sp!
  lp! fp! rp! prev-task @ dup dup link-task user' normal-dp + @ free throw ;

: (pass) ( x1 .. xn n task -- )  rdrop
  [ ' kill-task >body ] ALiteral r>
  rot >r r@ user' r0 + @ 2 cells - dup >r 2!
  r>              swap 1+
  r@ user' f0 + @ swap 1+
  r@ user' l0 + @ swap 1+
  cells r@ user' s0 + @ tuck swap - dup r@ user' save-task + !
  ?DO  I !  cell  +LOOP  r> wake ;

: activate ( task -- )  0 swap (pass) ;
: pass ( x1 .. xn n task -- )  (pass) ;

: single-tasking? ( -- flag )
    next-task dup @ = ;

: task-key   BEGIN  pause key? single-tasking? or  UNTIL  (key) ;
: task-emit  (emit) pause ;
: task-type  (type) pause ;

' task-key  IS key
' task-emit IS emit
' task-type IS type