platforms. (thanks to James Anderson for the optimization hint)
* bug fix: number of characters that can be written onto a single
line in a file is unlimited.
- * bug fix: GC deadlocks from asynchronous interrupts has been fixed
- by disabling interrupts for the duration of any
- SB-SYS:WITHOUT-GCING section.
+ * bug fix: some GC deadlocks caused by asynchronous interrupts have
+ been fixed by inhibiting interrupts for when GC is disbled.
+ * bug fix: GETHASH, PUTHASH, CLRHASH and REMHASH are now interrupt safe.
changes in sbcl-1.0.4 relative to sbcl-1.0.3:
* new platform: experimental support for x86-64/darwin (MacOS).
"%PRIMITIVE"
"%STANDARD-CHAR-P"
"*FOREIGN-LOCK*"
+ "*INTERRUPTS-ENABLED*" "*INTERRUPT-PENDING*"
"*LINKAGE-INFO*"
"*LONG-SITE-NAME*" "*SHORT-SITE-NAME*"
"*RUNTIME-DLHANDLE*"
*gc-inhibit* t
*gc-pending* nil
#!+sb-thread *stop-for-gc-pending* #!+sb-thread nil
- sb!unix::*interrupts-enabled* t
- sb!unix::*interrupt-pending* nil
+ *interrupts-enabled* t
+ *interrupt-pending* nil
*break-on-signals* nil
*maximum-error-depth* 10
*current-error-depth* 0
;; pseudo-atomicity too, but they handle it without
;; messing with special variables.)
#!+(or x86 x86-64) *pseudo-atomic-bits*
- sb!unix::*interrupts-enabled*
- sb!unix::*interrupt-pending*
+ *interrupts-enabled*
+ *interrupt-pending*
*free-interrupt-context-index*
sb!vm::*allocation-pointer*
sb!vm::*binding-stack-pointer*
other threads."
(let ((name (gensym "WITHOUT-INTERRUPTS-BODY-")))
`(flet ((,name () ,@body))
- (if *interrupts-enabled*
- (unwind-protect
- (let ((*interrupts-enabled* nil))
- (,name))
- ;; If we were interrupted in the protected section, then
- ;; the interrupts are still blocked and it remains so
- ;; until the pending interrupt is handled.
- ;;
- ;; If we were not interrupted in the protected section,
- ;; but here, then even if the interrupt handler enters
- ;; another WITHOUT-INTERRUPTS, the pending interrupt will
- ;; be handled immediately upon exit from said
- ;; WITHOUT-INTERRUPTS, so it is as if nothing has
- ;; happened.
- (when *interrupt-pending*
- (receive-pending-interrupt)))
- (,name)))))
+ (if *interrupts-enabled*
+ (unwind-protect
+ (let ((*interrupts-enabled* nil))
+ (,name))
+ ;; If we were interrupted in the protected section, then
+ ;; the interrupts are still blocked and it remains so
+ ;; until the pending interrupt is handled.
+ ;;
+ ;; If we were not interrupted in the protected section,
+ ;; but here, then even if the interrupt handler enters
+ ;; another WITHOUT-INTERRUPTS, the pending interrupt will
+ ;; be handled immediately upon exit from said
+ ;; WITHOUT-INTERRUPTS, so it is as if nothing has
+ ;; happened.
+ (when *interrupt-pending*
+ (receive-pending-interrupt)))
+ (,name)))))
(sb!xc:defmacro with-interrupts (&body body)
#!+sb-doc
(defmacro with-spinlock-and-without-gcing ((spinlock) &body body)
#!-sb-thread
(declare (ignore spinlock))
- (with-unique-names (old-gc-inhibit)
+ (with-unique-names (old-gc-inhibit old-interrupts-enabled)
`(let ((,old-gc-inhibit *gc-inhibit*)
+ (,old-interrupts-enabled *interrupts-enabled*)
+ (*interrupts-enabled* nil)
(*gc-inhibit* t))
(unwind-protect
(progn
,@body)
#!+sb-thread
(sb!thread::release-spinlock ,spinlock)
- (let ((*gc-inhibit* ,old-gc-inhibit))
- ;; the test is racy, but it can err only on the overeager side
+ (let ((*interrupts-enabled* ,old-interrupts-enabled)
+ (*gc-inhibit* ,old-gc-inhibit))
+ ;; the test is racy, but it can err only on the overeager
+ ;; side
(sb!kernel::maybe-handle-pending-gc))))))
(eval-when (:compile-toplevel :load-toplevel :execute)
(sb!vm::%instance-set spinlock 2 0))
(defmacro with-spinlock ((spinlock) &body body)
- (sb!int:with-unique-names (lock)
- `(let ((,lock ,spinlock))
- (get-spinlock ,lock)
+ (sb!int:with-unique-names (lock got-it)
+ `(let ((,lock ,spinlock)
+ (,got-it nil))
(unwind-protect
- (progn ,@body)
- (release-spinlock ,lock)))))
+ (progn
+ (setf ,got-it (get-spinlock ,lock))
+ (locally ,@body))
+ (when ,got-it
+ (release-spinlock ,lock))))))
;;;; mutexes
;;; FIXME: These could be converted to DEFVARs.
(declaim (special #!+(or x86 x86-64) *pseudo-atomic-bits*
- sb!unix::*interrupts-enabled*
- sb!unix::*interrupt-pending*
+ *interrupts-enabled*
+ *interrupt-pending*
*type-system-initialized*))
(defvar *cold-init-complete-p*)
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.4.29"
+"1.0.4.30"