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.<div><br></div><div>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.</div>

<div><br></div><div>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).</div>

<div><br></div><div>I would appreciate if you could test it and discuss here both the stability and the philosophy of the implementation.</div><div><br></div><div>Best,</div><div><br></div><div>Juanjo</div><div><div><br>
</div>
<div>(defmacro with-lock ((lock-form &rest options) &body body)</div></div><div>  (ext:with-unique-names (lock owner count)</div><div><div>    `(let* ((,lock ,lock-form)</div><div>            (,owner (mp:lock-owner ,lock))</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>    (,count (mp:lock-count ,lock)))</div><div>       (without-interrupts</div><div>           (unwind-protect</div><div>                (with-restored-interrupts</div>

<div>                    (mp::get-lock ,lock)</div><div>                  (locally ,@body))</div><div>             (when (and (eq mp:*current-process* (mp:lock-owner ,lock))</div><div><span class="Apple-tab-span" style="white-space:pre">                       </span>(or (not (eq ,owner mp:*current-process*))</div>

<div><span class="Apple-tab-span" style="white-space:pre">                      </span>    (> (mp:lock-count ,lock) ,count)))</div><div>               (mp::giveup-lock ,lock)))))))</div></div><div><br></div><div><div>static cl_fixnum</div>

<div>get_lock_inner(cl_object lock, cl_object own_process)</div><div>{</div><div>        if (AO_compare_and_swap_full((AO_t*)&(lock->lock.owner),</div><div><span class="Apple-tab-span" style="white-space:pre">                            </span>     (AO_t)Cnil, (AO_t)own_process)) {</div>

<div><span class="Apple-tab-span" style="white-space:pre">              </span>return lock->lock.counter = 1;</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>} else if (lock->lock.owner == own_process) {</div>

<div>                if (!lock->lock.recursive) {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>return -1;</div><div><span class="Apple-tab-span" style="white-space:pre">           </span>}</div><div>

                return ++lock->lock.counter;</div><div>        } else {</div><div><span class="Apple-tab-span" style="white-space:pre">            </span>return 0;</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>}</div>

<div>}</div><div><br></div><div><br></div>-- <br>Instituto de Física Fundamental, CSIC<br>c/ Serrano, 113b, Madrid 28006 (Spain) <br><a href="http://juanjose.garciaripoll.googlepages.com" target="_blank">http://juanjose.garciaripoll.googlepages.com</a><br>


</div>