-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlw6-stm.lisp
72 lines (55 loc) · 2.51 KB
/
lw6-stm.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
(in-package :lw6-stm)
(defmacro def-var (name &rest slots)
`(defstruct ,name
(%%modification-count 0)
(%%lock (mpcompat:make-lock))
,@slots))
(editor:setup-indent "def-var" 1)
(defun get-struct-arg (struct-name lambda-list)
(or (car (find struct-name
(remove-if (complement 'consp) lambda-list)
:key 'cadr))
(error "No ~A specializer in lambda list: ~A" struct-name lambda-list)))
(um:defmacro! def-accessor (method-name struct-name lambda-list &body body)
(let ((mod-name (intern (um:mkstr struct-name :-%%MODIFICATION-COUNT)))
(arg (get-struct-arg struct-name lambda-list)))
(multiple-value-bind (decls forms)
(um:separate-decls-and-body body)
`(defmethod ,method-name ,lambda-list
,@decls
(loop
(sys:with-modification-check-macro ,g!not-changed (,mod-name ,arg)
(let ((,g!ans (multiple-value-list (progn ,@forms))))
(when (,g!not-changed)
(return (values-list ,g!ans))))))) )))
(editor:setup-indent "def-accessor" 3 2)
(defmacro def-mutator (method-name struct-name lambda-list &body body)
(let ((lock-name (intern (um:mkstr struct-name :-%%LOCK)))
(mod-name (intern (um:mkstr struct-name :-%%MODIFICATION-COUNT)))
(arg (get-struct-arg struct-name lambda-list)))
(multiple-value-bind (decls forms)
(um:separate-decls-and-body body)
`(defmethod ,method-name ,lambda-list
,@decls
(mpcompat:with-spinlock ((,lock-name ,arg))
(sys:with-modification-change (,mod-name ,arg)
(progn
,@forms)))) )))
(editor:setup-indent "def-mutator" 3 2)
;; -----------------------------------------------------------------------------
(um:defmacro! with-accessing ((arg stm-type) &body body)
(let ((mod-name (intern (um:mkstr stm-type :-%%MODIFICATION-COUNT))))
`(loop
(sys:with-modification-check-macro ,g!not-changed (,mod-name ,arg)
(let ((,g!ans (multiple-value-list (progn ,@body))))
(when (,g!not-changed)
(return (values-list ,g!ans)))))) ))
(editor:setup-indent "with-accessing" 1)
(defmacro with-mutation ((arg stm-type) &body body)
(let ((mod-name (intern (um:mkstr stm-type :-%%MODIFICATION-COUNT)))
(lock-name (intern (um:mkstr stm-type :-%%LOCK))))
`(mpcompat:with-spinlock ((,lock-name ,arg))
(sys:with-modification-change (,mod-name ,arg)
(progn
,@body))) ))
(editor:setup-indent "with-mutation" 1)