The advertised usage of condition-wait may never timeout
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
Code using WAIT-ON-GATE with :TIMEOUT did not return in time under situations with lots of GC.
This can be traced back to the use of CONDITION-WAIT according to the documentation. When CONDITION-WAIT returns due to a spurious interrupt, the original timeout is reused in the next iteration. If the period of interrupts is shorter than TIMEOUT, this means that WAIT-ON-GATE may never return.
A simple example, using GC to trigger interrupts:
(require :sb-concurrency)
(defun test-condition-wait (&key (gc-p t) (timeout 1))
"Expect to be timed out after TIMEOUT. When GC-P is true, generate lots of
interrupts, otherwise do nothing while waiting."
(let ((gate (sb-concurrency
(stop nil))
(flet ((_waiter ()
;; We expect to be timed out:
(setf stop t)))
(let ((waiter (sb-thread:
;; Do something until stopped by WAITER after TIMEOUT.
(loop
(when gc-p (sb-ext:gc))
(when stop (return)))
(when (sb-thread:
* (test-condition
;; after one second:
NIL
* (test-condition
;; does not return...
This is SBCL 1.4.5, an implementation of ANSI Common Lisp.
Linux si2l 4.4.92-31-default #1 SMP Sun Oct 22 06:56:24 UTC 2017 (1d80e8a) x86_64 x86_64 x86_64 GNU/Linux
(:64-BIT :64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS
:C-STACK-
:COMPARE-
:FP-AND-
:IMMOBILE-SPACE :INLINE-CONSTANTS :INTEGER-EQL-VOP :LARGEFILE :LINKAGE-TABLE
:LINUX :LITTLE-ENDIAN :MEMORY-
:OS-PROVIDES-
:OS-PROVIDES-
:OS-PROVIDES-
:RAW-SIGNED-WORD :RELOCATABLE-HEAP :SB-DOC :SB-EVAL :SB-FUTEX :SB-LDB
:SB-PACKAGE-LOCKS :SB-SIMD-PACK :SB-SOURCE-
:SBCL :STACK-
:STACK-
:STACK-
:UNDEFINED-
The patch #1 is naive because it is doing some work already done in %CONDITION-WAIT and because it may not be solving some on all levels. For example, the FIXME in %WAIT-FOR-MUTEX could probably lead to a similar issue.
A serious patch will use the remaining time values computed and returned by %CONDITION-WAIT and lower-level calls.
Probably timeouts have to be treated like deadlines, having both an absolute and relative component. Merging the timeout and deadline concepts might simplify some code.