(setf (mutex-value mutex) new-value)
t)
#!+sb-thread
- (when (eql new-value (mutex-value mutex))
- (warn "recursive lock attempt ~S~%" mutex)
- (format *debug-io* "Thread: ~A~%" *current-thread*)
- (sb!debug:backtrace most-positive-fixnum *debug-io*)
- (force-output *debug-io*))
- ;; FIXME: Lutexes do not currently support deadlines, as at least
- ;; on Darwin pthread_foo_timedbar functions are not supported:
- ;; this means that we probably need to use the Carbon multiprocessing
- ;; functions on Darwin.
- #!+sb-lutex
- (when (zerop (with-lutex-address (lutex (mutex-lutex mutex))
- (if waitp
- (%lutex-lock lutex)
- (%lutex-trylock lutex))))
- (setf (mutex-value mutex) new-value))
- #!-sb-lutex
- (let (old)
- (when (and (setf old (compare-and-exchange-mutex-value mutex nil new-value))
- waitp)
- (loop while old
- do (multiple-value-bind (to-sec to-usec) (decode-timeout nil)
- (when (= 1 (with-pinned-objects (mutex old)
- (futex-wait (mutex-value-address mutex)
- (get-lisp-obj-address old)
- (or to-sec -1)
- (or to-usec 0))))
- (signal-deadline)))
- (setf old (compare-and-exchange-mutex-value mutex nil new-value))))
- (not old)))
+ (progn
+ (when (eql new-value (mutex-value mutex))
+ (warn "recursive lock attempt ~S~%" mutex)
+ (format *debug-io* "Thread: ~A~%" *current-thread*)
+ (sb!debug:backtrace most-positive-fixnum *debug-io*)
+ (force-output *debug-io*))
+ ;; FIXME: Lutexes do not currently support deadlines, as at least
+ ;; on Darwin pthread_foo_timedbar functions are not supported:
+ ;; this means that we probably need to use the Carbon multiprocessing
+ ;; functions on Darwin.
+ #!+sb-lutex
+ (when (zerop (with-lutex-address (lutex (mutex-lutex mutex))
+ (if waitp
+ (%lutex-lock lutex)
+ (%lutex-trylock lutex))))
+ (setf (mutex-value mutex) new-value))
+ #!-sb-lutex
+ (let (old)
+ (when (and (setf old (compare-and-exchange-mutex-value mutex nil new-value))
+ waitp)
+ (loop while old
+ do (multiple-value-bind (to-sec to-usec) (decode-timeout nil)
+ (when (= 1 (with-pinned-objects (mutex old)
+ (futex-wait (mutex-value-address mutex)
+ (get-lisp-obj-address old)
+ (or to-sec -1)
+ (or to-usec 0))))
+ (signal-deadline)))
+ (setf old (compare-and-exchange-mutex-value mutex nil new-value))))
+ (not old))))
(defun release-mutex (mutex)
#!+sb-doc
#ifndef LISP_FEATURE_WIN32
if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) {
sigset_t *context_sigmask = os_context_sigmask_addr(context);
+#ifdef LISP_FEATURE_SB_THREAD
/* What if the context we'd like to restore has GC signals
* blocked? Just skip the GC: we can't set GC_PENDING, because
* that would block the next attempt, and we don't know when
undo_fake_foreign_function_call(context);
return 1;
}
+#endif
thread_sigmask(SIG_SETMASK, context_sigmask, 0);
}
else
unblock_gc_signals();
#endif
+ /* SIG_STOP_FOR_GC needs to be enabled before we can call lisp:
+ * otherwise two threads racing here may deadlock: the other will
+ * wait on the GC lock, and the other cannot stop the first one... */
funcall0(SymbolFunction(SUB_GC));
undo_fake_foreign_function_call(context);
return 1;