-
Notifications
You must be signed in to change notification settings - Fork 0
/
mp.lisp
61 lines (48 loc) · 1.75 KB
/
mp.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
(quicklisp:quickload "bordeaux-threads")
(defclass sync-stack ()
((storage :accessor storage-value
:initform '()
:initarg :storage)
(length :accessor length-value
:initform 0)
(lock :accessor lock-value
:initform (bt:make-lock)))
(:documentation "A lock syncronised stack"))
(defun §stack (&optional (l '()))
"Create a new stack with initial content l"
(make-instance 'sync-stack :storage l))
(defmethod §push (data (x sync-stack))
"Push data to the stack with the lock taken"
(bt:with-lock-held ((lock-value x))
(incf (length-value x))
(push data (storage-value x))))
(defmethod §pop ((x sync-stack))
"Pop data from the stach with the lock taken"
(bt:with-lock-held ((lock-value x))
(decf (length-value x))
(pop (storage-value x))))
(defmethod §top ((x sync-stack))
"View what is on the top of the stack"
(bt:with-lock-held ((slot-value x 'lock))
(first (storage-value x))))
(defmethod §isempty ((x sync-stack))
"Check if the stack is empty"
(bt:with-lock-held ((lock-value x))
(zerop (length-value x))))
(defclass thread-notifier (sync-stack)
()
(:documentation "Model a thread sync process"))
(defun §thread-notifier ()
(make-instance 'thread-notifier))
(defmethod §block-until-waken ((x thread-notifier) condition-var lock)
(declare (ignore x))
(bt:with-lock-held (lock)
(bt:condition-wait condition-var lock)))
(defmethod §available-for-work (condition-var (x thread-notifier))
(§push condition-var x))
(defmethod §remove-ourselves-from-work ((x thread-notifier))
(§pop x))
(defmethod §wake-up-first-available((x thread-notifier))
(bt:with-lock-held ((lock-value x))
(when (> (length-value x) 0)
(bt:condition-notify (first (storage-value x))))))