I'm trying to use stmx inside the lparallel infrastructure.
This simple snippet raises an exception:
(ql:quickload :stmx)
(ql:quickload :lparallel)
(setf lparallel:*kernel* (lparallel:make-kernel 4))
(lparallel:future
(stmx:atomic (format t "~a ~%" "it works")))
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "lparallel" RUNNING {1003F8F073}>:
STMX internal error!
stmx:*current-thread* contains a stale value:
found #<SB-THREAD:THREAD "main thread" RUNNING {1004DC01F3}>
expecting #<SB-THREAD:THREAD "lparallel" RUNNING {1003F8F073}>
Typical cause is:
new threads were created with implementation-specific functions,
as for example (sb-thread:make-thread) or (mp:process-run-function),
that do not apply thread-local bindings stored in
bordeaux-threads:*default-special-bindings*
Solution:
use (bordeaux-threads:make-thread) instead.
The problem is obvious: it seems that lparallel
starts a native sbcl thread, while stmx relies on bordeaux-threads
to function correctly.
And indeed, this one fixes an error (though it is a total nonsence):
(lparallel:future
(bt:make-thread
(lambda ()
(stmx:atomic (format t "~a ~%" "it works")))))
The question is: how to make lparallel spawn bordeaux-threads? is it even possible? or is there another workaround?
Update
following @Svante's proposal i've tried to bind stmx.lang:*current-thread*
to actual lparallel current thread, and surprisingly it works:
(defmacro lpar-atomic (&body body)
`(let ((stmx.lang:*current-thread* (lparallel.thread-util:current-thread)))
(stmx:atomic ,@body)))
(lparallel:future
(lpar-atomic (format t "~a ~%" "it works!")))
It seems to be a workaround, still it is kind of ugly. If someone has an idea how to do it in general, i'd be glad. Otherwise we probably need to 'fix' stmx somehow )