-
Notifications
You must be signed in to change notification settings - Fork 3
/
actors-testing.lisp
114 lines (94 loc) · 2.6 KB
/
actors-testing.lisp
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
(in-package #:actors-user)
(kill-executives)
(get-actors)
(make-actor () ((x 15))
(sleep 0.1)
(pr (format nil "~&Self (1) = ~A" self))
(wait (a b c)
(list "ayy" "bee" "see") ;; <-- performed in foreign thead
(pr "After WAIT"
(format nil "~&Self (2) = ~A" self)
(list a b c))
(send self 32)
(next-message (msg)
(pr (format nil "~&Self (3) = ~A" self)
msg
'done))
))
(defun tst ()
(make-actor () ()
(pr self)
(wait (a b c)
(list "ayy" "bee" "see") ;; <-- performed in foreign thead
(pr self
(list a b c))
(send self 32)
(next-message (msg)
(pr msg 'done))
)))
(compile 'tst)
(tst)
(defun tst (n)
;; Ans: about 10 usec/ spawn-exit elapsed time
(loop repeat n do
(spawn (lambda ()))))
(let ()
(dotimes (ix 1000)
(spawn (lambda (ix) (pr ix)) ix)))
;; --------------------------------------
(make-actor (&rest msg)
(shared-state)
(do-something)
(wait (&rest msg)
(wait-form)
(do-more)))
=>
(make-actor (&rest msg)
(shared-state)
(do-something)
(spawn (lambda ()
(send self (wait-form))))
(become (behav (&rest msg)
((old-me #'me))
(do-more)
(become old-me))))
(lw:function-lambda-list (lambda (a b &key c &rest x)
(list a b c x)))
(defun tst (a b &rest x &key c &allow-other-keys)
(list a b c x))
;; ---------------------------------------------
(defun do-become (self behav)
(setf (actor-behavior self) behav))
(defmacro become (args state &body body)
(let ((a!self (anaphor 'self)))
`(do-become (behav ,args ,state ,@body))
))
(defun re-enqueue (actor msg-lst)
(map nil (lambda (msg)
(apply #'send actor msg))
(nreverse msg-lst)))
(defmacro wait (args wait-form &body body)
(let ((a!self (anaphor 'self))
(g!unique (gensym-like :msg-))
(g!msg (gensym-like :msg-))
(g!args (gensym-like :args-))
(g!queue (gensym-like :queue-))
(g!old-me (gensym-like :old-me-)))
`(progn
(spawn (lambda ()
(send ,a!self ,g!unique ,wait-form)))
(become (&rest ,g!msg) ((,g!old-me #',a!me))
(um:dcase ,g!msg
(,g!unique ,args
,@body
(re-enqueue ,a!self ,g!queue)
(become ,g!old-me))
(_ (&rest ,g!args)
(push ,g!args ,g!queue))
)))
))
(progn
(doit-toit)
(become (&rest msg)
()
(didit-already)))