I have finally convinced myself that there is no way to reuse the operating system mutexes from pthreads or Windows if we still want to have interruptible threads.

As a possible fix I have uploaded to git/CVS an implementation based on libatomics' CAS (compare-and-swap) combined with some simple-minded wait scheme (very similar to SBCL's). The code looks very simple. It consist on a function, get_lock_inner(), which is executed with disable threads, followed by some code that decides whether to wait and for how long.

The difference with respect to pthreads is that get_lock_inner() stores in the lock two values, the owner and the counter, which are enough to know whether a lock is owned or not. With that, WITH-LOCK becomes implementable with lisp functions and no special magic (See also below).

I would appreciate if you could test it and discuss here both the stability and the philosophy of the implementation.



(defmacro with-lock ((lock-form &rest options) &body body)
  (ext:with-unique-names (lock owner count)
    `(let* ((,lock ,lock-form)
            (,owner (mp:lock-owner ,lock))
   (,count (mp:lock-count ,lock)))
                    (mp::get-lock ,lock)
                  (locally ,@body))
             (when (and (eq mp:*current-process* (mp:lock-owner ,lock))
(or (not (eq ,owner mp:*current-process*))
   (> (mp:lock-count ,lock) ,count)))
               (mp::giveup-lock ,lock)))))))

static cl_fixnum
get_lock_inner(cl_object lock, cl_object own_process)
        if (AO_compare_and_swap_full((AO_t*)&(lock->lock.owner),
    (AO_t)Cnil, (AO_t)own_process)) {
return lock->lock.counter = 1;
} else if (lock->lock.owner == own_process) {
                if (!lock->lock.recursive) {
return -1;
                return ++lock->lock.counter;
        } else {
return 0;

Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)