From Jason Turner

[thread.sema]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpplnglriy/{from.md → to.md} +160 -0
tmp/tmpplnglriy/{from.md → to.md} RENAMED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Semaphore <a id="thread.sema">[[thread.sema]]</a>
2
+
3
+ Semaphores are lightweight synchronization primitives used to constrain
4
+ concurrent access to a shared resource. They are widely used to
5
+ implement other synchronization primitives and, whenever both are
6
+ applicable, can be more efficient than condition variables.
7
+
8
+ A counting semaphore is a semaphore object that models a non-negative
9
+ resource count. A binary semaphore is a semaphore object that has only
10
+ two states. A binary semaphore should be more efficient than the default
11
+ implementation of a counting semaphore with a unit resource count.
12
+
13
+ ### Header `<semaphore>` synopsis <a id="semaphore.syn">[[semaphore.syn]]</a>
14
+
15
+ ``` cpp
16
+ namespace std {
17
+ template<ptrdiff_t least_max_value = implementation-defined>
18
+ class counting_semaphore;
19
+
20
+ using binary_semaphore = counting_semaphore<1>;
21
+ }
22
+ ```
23
+
24
+ ### Class template `counting_semaphore` <a id="thread.sema.cnt">[[thread.sema.cnt]]</a>
25
+
26
+ ``` cpp
27
+ namespace std {
28
+ template<ptrdiff_t least_max_value = implementation-defined>
29
+ class counting_semaphore {
30
+ public:
31
+ static constexpr ptrdiff_t max() noexcept;
32
+
33
+ constexpr explicit counting_semaphore(ptrdiff_t desired);
34
+ ~counting_semaphore();
35
+
36
+ counting_semaphore(const counting_semaphore&) = delete;
37
+ counting_semaphore& operator=(const counting_semaphore&) = delete;
38
+
39
+ void release(ptrdiff_t update = 1);
40
+ void acquire();
41
+ bool try_acquire() noexcept;
42
+ template<class Rep, class Period>
43
+ bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
44
+ template<class Clock, class Duration>
45
+ bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
46
+
47
+ private:
48
+ ptrdiff_t counter; // exposition only
49
+ };
50
+ }
51
+ ```
52
+
53
+ Class template `counting_semaphore` maintains an internal counter that
54
+ is initialized when the semaphore is created. The counter is decremented
55
+ when a thread acquires the semaphore, and is incremented when a thread
56
+ releases the semaphore. If a thread tries to acquire the semaphore when
57
+ the counter is zero, the thread will block until another thread
58
+ increments the counter by releasing the semaphore.
59
+
60
+ `least_max_value` shall be non-negative; otherwise the program is
61
+ ill-formed.
62
+
63
+ Concurrent invocations of the member functions of `counting_semaphore`,
64
+ other than its destructor, do not introduce data races.
65
+
66
+ ``` cpp
67
+ static constexpr ptrdiff_t max() noexcept;
68
+ ```
69
+
70
+ *Returns:* The maximum value of `counter`. This value is greater than or
71
+ equal to `least_max_value`.
72
+
73
+ ``` cpp
74
+ constexpr explicit counting_semaphore(ptrdiff_t desired);
75
+ ```
76
+
77
+ *Preconditions:* `desired >= 0` is `true`, and `desired <= max()` is
78
+ `true`.
79
+
80
+ *Effects:* Initializes `counter` with `desired`.
81
+
82
+ *Throws:* Nothing.
83
+
84
+ ``` cpp
85
+ void release(ptrdiff_t update = 1);
86
+ ```
87
+
88
+ *Preconditions:* `update >= 0` is `true`, and
89
+ `update <= max() - counter` is `true`.
90
+
91
+ *Effects:* Atomically execute `counter += update`. Then, unblocks any
92
+ threads that are waiting for `counter` to be greater than zero.
93
+
94
+ *Synchronization:* Strongly happens before invocations of `try_acquire`
95
+ that observe the result of the effects.
96
+
97
+ *Throws:* `system_error` when an exception is
98
+ required [[thread.req.exception]].
99
+
100
+ *Error conditions:* Any of the error conditions allowed for mutex
101
+ types [[thread.mutex.requirements.mutex]].
102
+
103
+ ``` cpp
104
+ bool try_acquire() noexcept;
105
+ ```
106
+
107
+ *Effects:* Attempts to atomically decrement `counter` if it is positive,
108
+ without blocking. If `counter` is not decremented, there is no effect
109
+ and `try_acquire` immediately returns. An implementation may fail to
110
+ decrement `counter` even if it is positive.
111
+
112
+ [*Note 1*: This spurious failure is normally uncommon, but allows
113
+ interesting implementations based on a simple compare and
114
+ exchange [[atomics]]. — *end note*]
115
+
116
+ An implementation should ensure that `try_acquire` does not consistently
117
+ return `false` in the absence of contending semaphore operations.
118
+
119
+ *Returns:* `true` if `counter` was decremented, otherwise `false`.
120
+
121
+ ``` cpp
122
+ void acquire();
123
+ ```
124
+
125
+ *Effects:* Repeatedly performs the following steps, in order:
126
+
127
+ - Evaluates `try_acquire`. If the result is `true`, returns.
128
+ - Blocks on `*this` until `counter` is greater than zero.
129
+
130
+ *Throws:* `system_error` when an exception is
131
+ required [[thread.req.exception]].
132
+
133
+ *Error conditions:* Any of the error conditions allowed for mutex
134
+ types [[thread.mutex.requirements.mutex]].
135
+
136
+ ``` cpp
137
+ template<class Rep, class Period>
138
+ bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
139
+ template<class Clock, class Duration>
140
+ bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
141
+ ```
142
+
143
+ *Effects:* Repeatedly performs the following steps, in order:
144
+
145
+ - Evaluates `try_acquire()`. If the result is `true`, returns `true`.
146
+ - Blocks on `*this` until `counter` is greater than zero or until the
147
+ timeout expires. If it is unblocked by the timeout expiring, returns
148
+ `false`.
149
+
150
+ The timeout expires [[thread.req.timing]] when the current time is after
151
+ `abs_time` (for `try_acquire_until`) or when at least `rel_time` has
152
+ passed from the start of the function (for `try_acquire_for`).
153
+
154
+ *Throws:* Timeout-related exceptions [[thread.req.timing]], or
155
+ `system_error` when a non-timeout-related exception is
156
+ required [[thread.req.exception]].
157
+
158
+ *Error conditions:* Any of the error conditions allowed for mutex
159
+ types [[thread.mutex.requirements.mutex]].
160
+