5 (macrolet ((test (init op
)
9 (assert (eql nil
(compare-and-swap (,op x
) nil y
)))
10 (assert (eql y
(compare-and-swap (,op x
) nil z
)))
11 (assert (eql y
(,op x
)))
13 (multiple-value-bind (res err
)
14 (ignore-errors (compare-and-swap (,op x
) nil nil
))
16 (assert (typep err
'type-error
)))))))
17 (test (cons nil
:no
) car
)
18 (test (cons nil
:no
) first
)
19 (test (cons :no nil
) cdr
)
20 (test (cons :no nil
) rest
)
21 (test '.foo. symbol-plist
)
22 (test (progn (set '.bar. nil
) '.bar.
) symbol-value
)
23 (test (make-xxx) xxx-yyy
))
27 ;;; thread-local bindings
31 (assert (eql nil
(compare-and-swap (symbol-value '*foo
*) nil t
)))
32 (assert (eql t
(compare-and-swap (symbol-value '*foo
*) nil
:foo
)))
33 (assert (eql t
*foo
*)))
34 (assert (eql 42 *foo
*)))
36 ;;; unbound symbols + symbol-value
38 (assert (not (boundp '*foo
*)))
40 (multiple-value-bind (res err
)
41 (ignore-errors (compare-and-swap (symbol-value '*foo
*) nil t
))
43 (assert (typep err
'unbound-variable
)))
49 (multiple-value-bind (res err
)
50 (ignore-errors (compare-and-swap (symbol-value '*bar
*) nil t
))
52 (assert (typep err
'unbound-variable
))))
56 (defvar *v
* (vector 1))
59 (assert (eql 1 (compare-and-swap (svref *v
* 0) 1 2)))
60 (assert (eql 2 (compare-and-swap (svref *v
* 0) 1 3)))
61 (assert (eql 2 (svref *v
* 0)))
64 (multiple-value-bind (res err
)
65 (ignore-errors (compare-and-swap (svref *v
* -
1) 1 2))
67 (assert (typep err
'type-error
)))
68 (multiple-value-bind (res err
)
69 (ignore-errors (compare-and-swap (svref *v
* 1) 1 2))
71 (assert (typep err
'type-error
)))
73 ;; type of the first argument
74 (multiple-value-bind (res err
)
75 (ignore-errors (compare-and-swap (svref "foo" 1) 1 2))
77 (assert (typep err
'type-error
)))
79 ;; Check that we don't modify constants
80 (defconstant +a-constant
+ 42)
84 (sb-ext:compare-and-swap
(symbol-value '+a-constant
+) 42 13)
86 (let ((name '+a-constant
+))
90 (sb-ext:compare-and-swap
(symbol-value name
) 42 13)
93 ;; Check that we don't mess declaimed types
94 (declaim (boolean *a-boolean
*))
95 (defparameter *a-boolean
* t
)
99 (sb-ext:compare-and-swap
(symbol-value '*a-boolean
*) t
42)
101 (let ((name '*a-boolean
*))
105 (sb-ext:compare-and-swap
(symbol-value name
) t
42)
106 (error () :error
)))))
108 ;;;; ATOMIC-INCF (we should probably rename this file atomic-ops...)
111 (word 0 :type sb-vm
:word
))
113 (defun inc-box (box n
)
114 (declare (fixnum n
) (box box
))
116 do
(sb-ext:atomic-incf
(box-word box
))))
118 (defun dec-box (box n
)
119 (declare (fixnum n
) (box box
))
121 do
(sb-ext:atomic-incf
(box-word box
) -
1)))
123 (let ((box (make-box)))
125 (assert (= 10000 (box-word box
)))
127 (assert (= 0 (box-word box
))))
130 (let* ((box (make-box))
131 (threads (loop repeat
64
132 collect
(sb-thread:make-thread
(lambda ()
137 :name
"inc/dec thread"))))
138 (mapc #'sb-thread
:join-thread threads
)
139 (assert (= 0 (box-word box
))))