Don Cohen wrote:
> Is it possible to interrupt between the incf and the setf?
> If so, what is to be done about it? Defer interrupts around the setf ?
> Is there some reasonably easy way to understand/predict where
> interrupts can occur?
Hash Tables and Sequences
Nothing is ever locked, so the user is required to use locks when
sharing HASH-TABLEs and SEQUENCEs between threads.
If two threads evaluate
(INCF (GETHASH x global-ht 0)),
the results are undefined.
-- But this doesn't allow the programmer to fulfill the Parallelizability
Program PRELUDE: (defparameter global-ht (make-hash-table))
Program A: (setf (gethash 'a global-ht) 'aaaa)
Program B: (setf (gethash 'b global-ht) 'bbbb)
The Parallelizability Principle implies that one should
have an easy way to declare that global-ht is shared, without modifying
the programs A and B. The obvious proposal is a change in the PRELUDE:
(defparameter global-ht (make-hash-table :lockable t))
While this automatic locking will indeed work when no keys are shared,
this is not a universal solution:
Program A: (incf (gethash 10 global-ht 0))
Program B: (incf (gethash 10 global-ht 0))
It is possible that both GETHASH calls will happen before both
PUTHASH calls unless both INCF forms are guarded with a lock.
Instead of making GLOBAL-HT an instance of LOCK (and relying on some
magic which cannot always work), one needs to create an explicit lock with
(defparameter global-ht-lock (ext:make-lock))
and wrap all his GLOBAL-HT accesses with
(incf (gethash 'a global-ht 0)))
The bottom line is: programs that use global variables do not fall
under the Parallelizability Principle because they share application
objects with programs running in other threads.
Automatic locking will impose an unjustifiable penalty on HASH-TABLEs
and SEQUENCEs local to threads.
It is also consistent with the usual Common Lisp approach of
The consequences are undefined when code executed during an
object-traversing operation destructively modifies the object in
a way that might affect the ongoing traversal operation...
If an object O1 is used as a key in a hash table H and is then
visibly modified with regard to the equivalence test of H, then
the consequences are unspecified if O1 is used as a key in
further operations on H...
I.e., if you want to shoot yourself, it is YOUR responsibility to wear armor.