Init
This commit is contained in:
221
cppdraft/thread/sema/cnt.md
Normal file
221
cppdraft/thread/sema/cnt.md
Normal file
@@ -0,0 +1,221 @@
|
||||
[thread.sema.cnt]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.8 Semaphore [[thread.sema]](thread.sema#cnt)
|
||||
|
||||
### 32.8.3 Class template counting_semaphore [thread.sema.cnt]
|
||||
|
||||
namespace std {template<ptrdiff_t least_max_value = *implementation-defined*>class counting_semaphore {public:static constexpr ptrdiff_t max() noexcept; constexpr explicit counting_semaphore(ptrdiff_t desired); ~counting_semaphore();
|
||||
|
||||
counting_semaphore(const counting_semaphore&) = delete;
|
||||
counting_semaphore& operator=(const counting_semaphore&) = delete; void release(ptrdiff_t update = 1); void acquire(); bool try_acquire() noexcept; template<class Rep, class Period>bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time); private: ptrdiff_t counter; // *exposition only*};}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10490)
|
||||
|
||||
Class template counting_semaphore maintains an internal counter
|
||||
that is initialized when the semaphore is created[.](#1.sentence-1)
|
||||
|
||||
The counter is decremented when a thread acquires the semaphore, and
|
||||
is incremented when a thread releases the semaphore[.](#1.sentence-2)
|
||||
|
||||
If a thread tries to acquire the semaphore when the counter is zero,
|
||||
the thread will block
|
||||
until another thread increments the counter by releasing the semaphore[.](#1.sentence-3)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10500)
|
||||
|
||||
least_max_value shall be non-negative; otherwise the program is ill-formed[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10503)
|
||||
|
||||
Concurrent invocations of the member functions of counting_semaphore,
|
||||
other than its destructor, do not introduce data races[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:max,counting_semaphore)
|
||||
|
||||
`static constexpr ptrdiff_t max() noexcept;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10513)
|
||||
|
||||
*Returns*: The maximum value of counter[.](#4.sentence-1)
|
||||
|
||||
This value is greater than or equal to least_max_value[.](#4.sentence-2)
|
||||
|
||||
[ð](#lib:counting_semaphore,constructor)
|
||||
|
||||
`constexpr explicit counting_semaphore(ptrdiff_t desired);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10525)
|
||||
|
||||
*Preconditions*: desired >= 0 is true, anddesired <= max() is true[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10530)
|
||||
|
||||
*Effects*: Initializes counter with desired[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10534)
|
||||
|
||||
*Throws*: Nothing[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:release,counting_semaphore)
|
||||
|
||||
`void release(ptrdiff_t update = 1);
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10545)
|
||||
|
||||
*Preconditions*: update >= 0 is true, andupdate <= max() - counter is true[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10550)
|
||||
|
||||
*Effects*: Atomically execute counter += update[.](#9.sentence-1)
|
||||
|
||||
Then, unblocks any threads
|
||||
that are waiting for counter to be greater than zero[.](#9.sentence-2)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10556)
|
||||
|
||||
*Synchronization*: Strongly happens before invocations of try_acquire that observe the result of the effects[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10561)
|
||||
|
||||
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10565)
|
||||
|
||||
*Error conditions*: Any of the error conditions
|
||||
allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types"))[.](#12.sentence-1)
|
||||
|
||||
[ð](#lib:try_acquire,counting_semaphore)
|
||||
|
||||
`bool try_acquire() noexcept;
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10577)
|
||||
|
||||
*Effects*: Attempts to atomically decrement counter if it is positive,
|
||||
without blocking[.](#13.sentence-1)
|
||||
|
||||
If counter is not decremented, there is no effect andtry_acquire immediately returns[.](#13.sentence-2)
|
||||
|
||||
An implementation may fail to decrement counter even if it is positive[.](#13.sentence-3)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This spurious failure is normally uncommon, but
|
||||
allows interesting implementations
|
||||
based on a simple compare and exchange ([[atomics]](atomics "32.5 Atomic operations"))[.](#13.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
An implementation should ensure that try_acquire does not consistently return false in the absence of contending semaphore operations[.](#13.sentence-5)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10594)
|
||||
|
||||
*Returns*: true if counter was decremented, otherwise false[.](#14.sentence-1)
|
||||
|
||||
[ð](#lib:acquire,counting_semaphore)
|
||||
|
||||
`void acquire();
|
||||
`
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10605)
|
||||
|
||||
*Effects*: Repeatedly performs the following steps, in order:
|
||||
|
||||
- [(15.1)](#15.1)
|
||||
|
||||
Evaluates try_acquire()[.](#15.1.sentence-1)
|
||||
If the result is true, returns[.](#15.1.sentence-2)
|
||||
|
||||
- [(15.2)](#15.2)
|
||||
|
||||
Blocks on *this until counter is greater than zero[.](#15.2.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10615)
|
||||
|
||||
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#16.sentence-1)
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10619)
|
||||
|
||||
*Error conditions*: Any of the error conditions
|
||||
allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types"))[.](#17.sentence-1)
|
||||
|
||||
[ð](#lib:try_acquire_for,counting_semaphore)
|
||||
|
||||
`template<class Rep, class Period>
|
||||
bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
|
||||
template<class Clock, class Duration>
|
||||
bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10635)
|
||||
|
||||
*Effects*: Repeatedly performs the following steps, in order:
|
||||
|
||||
- [(18.1)](#18.1)
|
||||
|
||||
Evaluates try_acquire()[.](#18.1.sentence-1)
|
||||
If the result is true, returns true[.](#18.1.sentence-2)
|
||||
|
||||
- [(18.2)](#18.2)
|
||||
|
||||
Blocks on *this until counter is greater than zero or until the timeout expires[.](#18.2.sentence-1)
|
||||
If it is unblocked by the timeout expiring, returns false[.](#18.2.sentence-2)
|
||||
|
||||
The timeout expires ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))
|
||||
when the current time is after abs_time (for try_acquire_until)
|
||||
or when at least rel_time has passed
|
||||
from the start of the function (for try_acquire_for)[.](#18.sentence-2)
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10653)
|
||||
|
||||
*Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")), or system_error when a non-timeout-related exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10658)
|
||||
|
||||
*Error conditions*: Any of the error conditions
|
||||
allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2 Mutex types"))[.](#20.sentence-1)
|
||||
29
cppdraft/thread/sema/general.md
Normal file
29
cppdraft/thread/sema/general.md
Normal file
@@ -0,0 +1,29 @@
|
||||
[thread.sema.general]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.8 Semaphore [[thread.sema]](thread.sema#general)
|
||||
|
||||
### 32.8.1 General [thread.sema.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10435)
|
||||
|
||||
Semaphores are lightweight synchronization primitives
|
||||
used to constrain concurrent access to a shared resource[.](#1.sentence-1)
|
||||
|
||||
They are widely used to implement other synchronization primitives and,
|
||||
whenever both are applicable, can be more efficient than condition variables[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10441)
|
||||
|
||||
A counting semaphore is a semaphore object
|
||||
that models a non-negative resource count[.](#2.sentence-1)
|
||||
|
||||
A binary semaphore is a semaphore object that has only two states[.](#2.sentence-2)
|
||||
|
||||
A binary semaphore should be more efficient than
|
||||
the default implementation of a counting semaphore with a unit resource count[.](#2.sentence-3)
|
||||
Reference in New Issue
Block a user