Coverage report: /home/ellis/.stash/quicklisp/dists/ultralisp/software/sionescu-bordeaux-threads-20250412101706/apiv2/api-condition-variables.lisp

KindCoveredAll%
expression024 0.0
branch00nil
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-lisp; Base: 10; Package: BORDEAUX-THREADS-2 -*-
2
 ;;;; The above modeline is required for Genera. Do not change.
3
 
4
 (in-package :bordeaux-threads-2)
5
 
6
 ;;; Resource contention: condition variables
7
 
8
 ;;; A condition variable provides a mechanism for threads to put
9
 ;;; themselves to sleep while waiting for the state of something to
10
 ;;; change, then to be subsequently woken by another thread which has
11
 ;;; changed the state.
12
 ;;;
13
 ;;; A condition variable must be used in conjunction with a lock to
14
 ;;; protect access to the state of the object of interest. The
15
 ;;; procedure is as follows:
16
 ;;;
17
 ;;; Suppose two threads A and B, and some kind of notional event
18
 ;;; channel C. A is consuming events in C, and B is producing them.
19
 ;;; CV is a condition-variable
20
 ;;;
21
 ;;; 1) A acquires the lock that safeguards access to C
22
 ;;; 2) A threads and removes all events that are available in C
23
 ;;; 3) When C is empty, A calls CONDITION-WAIT, which atomically
24
 ;;;    releases the lock and puts A to sleep on CV
25
 ;;; 4) Wait to be notified; CONDITION-WAIT will acquire the lock again
26
 ;;;    before returning
27
 ;;; 5) Loop back to step 2, for as long as threading should continue
28
 ;;;
29
 ;;; When B generates an event E, it
30
 ;;; 1) acquires the lock guarding C
31
 ;;; 2) adds E to the channel
32
 ;;; 3) calls CONDITION-NOTIFY on CV to wake any sleeping thread
33
 ;;; 4) releases the lock
34
 ;;;
35
 ;;; To avoid the "lost wakeup" problem, the implementation must
36
 ;;; guarantee that CONDITION-WAIT in thread A atomically releases the
37
 ;;; lock and sleeps. If this is not guaranteed there is the
38
 ;;; possibility that thread B can add an event and call
39
 ;;; CONDITION-NOTIFY between the lock release and the sleep - in this
40
 ;;; case the notify call would not see A, which would be left sleeping
41
 ;;; despite there being an event available.
42
 
43
 (defun condition-variable-p (object)
44
   "Returns TRUE if OBJECT is a condition variable, and NIL otherwise."
45
   (typep object 'condition-variable))
46
 
47
 (defun make-condition-variable (&key name)
48
   "Returns a new condition-variable object for use
49
   with CONDITION-WAIT and CONDITION-NOTIFY."
50
   (check-type name (or null string))
51
   (%make-condition-variable name))
52
 
53
 (defun condition-wait (condition-variable lock &key timeout)
54
   "Atomically release LOCK and enqueue the calling
55
   thread waiting for CONDITION-VARIABLE. The thread will resume when
56
   another thread has notified it using CONDITION-NOTIFY; it may also
57
   resume if interrupted by some external event or in other
58
   implementation-dependent circumstances: the caller must always test
59
   on waking that there is threading to be done, instead of assuming
60
   that it can go ahead.
61
 
62
   It is an error to call this function unless from the thread that
63
   holds LOCK.
64
 
65
   If TIMEOUT is nil or not provided, the call blocks until a
66
   notification is received.
67
 
68
   If TIMEOUT is non-nil, the call will return after at most TIMEOUT
69
   seconds (approximately), whether or not a notification has occurred.
70
 
71
   Either NIL or T will be returned. A return of NIL indicates that the
72
   timeout has expired without receiving a notification. A return of T
73
   indicates that a notification was received."
74
   (check-type timeout (or null (real 0)))
75
   (%condition-wait condition-variable
76
                    (lock-native-lock lock)
77
                    timeout))
78
 
79
 (defun condition-notify (condition-variable)
80
   "Notify one of the threads waiting for
81
   CONDITION-VARIABLE.
82
 
83
   It is unspecified which thread gets a wakeup and does not
84
   necessarily relate to the order that the threads went to sleep in.
85
 
86
   CONDITION-NOTIFY returns always NIL."
87
   (%condition-notify condition-variable)
88
   nil)
89
 
90
 (defun condition-broadcast (condition-variable)
91
   "Notify all threads waiting for CONDITION-VARIABLE.
92
   
93
   The order of wakeup is unspecified and does not necessarily relate
94
   to the order that the threads went to sleep in.
95
 
96
   CONDITION-BROADCAST returns always NIL."
97
   (%condition-broadcast condition-variable)
98
   nil)