Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
470 commits
Select commit Hold shift + click to select a range
be86c90
Formatting
AlexGuteniev May 6, 2020
57f15ca
ARM build
AlexGuteniev May 6, 2020
ca11289
Merge remote-tracking branch 'upstream/master'
AlexGuteniev May 7, 2020
cbb2803
I expect it to pass
AlexGuteniev May 7, 2020
f2f01a1
Don't try to support nonexistent "old ABI"
AlexGuteniev May 8, 2020
7b4a03a
formatting
AlexGuteniev May 8, 2020
9acff2e
Update stl/inc/xatomic_wait.h
AlexGuteniev May 9, 2020
7069749
Update stl/inc/xatomic_wait.h
AlexGuteniev May 9, 2020
380c281
Update stl/inc/memory
AlexGuteniev May 9, 2020
073f30b
Update stl/inc/atomic
AlexGuteniev May 9, 2020
9c5cb7e
correctly mark test as passing
AlexGuteniev May 9, 2020
e9969c1
duplicate duplicate
AlexGuteniev May 9, 2020
237f535
Merge branch 'master' of https://github.com/AlexGuteniev/STL
AlexGuteniev May 9, 2020
750356b
abort on unexpected situation even in release
AlexGuteniev May 9, 2020
0f89af1
actually don't see a value in this check
AlexGuteniev May 9, 2020
84d32f0
too much mimic of existing code by too much copying
AlexGuteniev May 9, 2020
2dbcf8e
Merge remote-tracking branch 'upstream/master'
AlexGuteniev May 9, 2020
53f056f
Merge remote-tracking branch 'upstream/master'
AlexGuteniev May 13, 2020
edff7ca
More time to pass test
AlexGuteniev May 13, 2020
f8f9abe
Merge remote-tracking branch 'upstream/master'
AlexGuteniev May 23, 2020
9ca6c15
Merge remote-tracking branch 'upstream/master'
AlexGuteniev May 30, 2020
4287866
Merge remote-tracking branch 'origin/master' into HEAD
BillyONeal Jun 30, 2020
f34dee5
Merge remote-tracking branch 'origin/master' into atomic_wait
BillyONeal Jul 8, 2020
05a65fa
Add msbuild build system.
BillyONeal Jul 8, 2020
e46c447
Manually inline _Save_function_pointer_relaxed -- I think atomic ops …
BillyONeal Jul 8, 2020
7f05ee2
More build fixes discovered in DevDiv test harness
BillyONeal Jul 9, 2020
4dcd154
Merge remote-tracking branch 'origin/master' into atomic_wait
BillyONeal Jul 9, 2020
9dcb98e
clang-format
BillyONeal Jul 9, 2020
83290f4
Fix cmake dependency information for the .src, thanks to Robert Schum…
BillyONeal Jul 9, 2020
f8e6cea
_Ugly some things in atomic_wait.cpp
BillyONeal Jul 14, 2020
4c454e7
Merge _Atomic_wait_direct_timed_for_internal_spinlock into only caller.
BillyONeal Jul 14, 2020
6e3951d
de-inline template
BillyONeal Jul 14, 2020
e80bbc6
Remove synchronization.lib pragma which is problematic for _ONECORE p…
BillyONeal Jul 14, 2020
bb15189
Rename _Deadline_picoseconds to _Reserved as it is currently unused.
BillyONeal Jul 15, 2020
84df7ef
Rename _Get_remaining_waiting_time to _Get_remaining_wait_millisecond…
BillyONeal Jul 15, 2020
653c270
Merge remote-tracking branch 'origin/master' into atomic_wait
BillyONeal Jul 15, 2020
f866822
fixup
BillyONeal Jul 15, 2020
e8b38a1
Add missing _INLINE_VAR.
BillyONeal Jul 15, 2020
c8f10c6
Merge remote-tracking branch 'upstream/master'
AlexGuteniev Jul 15, 2020
f3ffdaf
Merge remote-tracking branch 'origin/master'
AlexGuteniev Jul 15, 2020
8fa9d54
Update stl/inc/atomic
AlexGuteniev Jul 15, 2020
21b0352
Update stl/inc/memory
AlexGuteniev Jul 15, 2020
c3aa7e1
Fix CMakeLists.txt declaration order.
BillyONeal Jul 15, 2020
eb99cd0
Fix test sort order.
BillyONeal Jul 15, 2020
0b0de84
Use <assert.h> and pragma once.
BillyONeal Jul 15, 2020
74ab22a
STL CR feedback:
BillyONeal Jul 15, 2020
aaf8f46
Merge remote-tracking branch 'AlexGuteniev/master' into atomic_wait
BillyONeal Jul 15, 2020
0334bda
Compiler errors.
BillyONeal Jul 15, 2020
c281047
Fix the same build system bug in the cmake version.
BillyONeal Jul 15, 2020
7565517
Find missing ^^^s with regex:
BillyONeal Jul 16, 2020
bdeb5ad
Bill forgot to save before committing.
BillyONeal Jul 16, 2020
dcf4216
remove spinner to pass tests
AlexGuteniev Jul 18, 2020
1caf417
Correct default for wait phase
AlexGuteniev Jul 18, 2020
71d5d1b
whitespace
AlexGuteniev Jul 18, 2020
54c2eda
rewrite to avoid the complexity of indirect wait
AlexGuteniev Jul 18, 2020
ba3d8c8
clang format
AlexGuteniev Jul 18, 2020
c1157f7
notify_one for indirect wake
AlexGuteniev Jul 19, 2020
7327523
clang format
AlexGuteniev Jul 19, 2020
fed4f21
optimize acquire wait functions
AlexGuteniev Jul 19, 2020
2c348af
latch, part of #52, based on atomic wait
AlexGuteniev Jul 19, 2020
cf43fdc
formatting
AlexGuteniev Jul 19, 2020
26ac662
consistency
AlexGuteniev Jul 19, 2020
e0c4a08
another const
AlexGuteniev Jul 19, 2020
e777a8b
p1865r1
AlexGuteniev Jul 19, 2020
97c72c2
unterse
AlexGuteniev Jul 19, 2020
375db7c
typo
AlexGuteniev Jul 19, 2020
209cdfb
avoid dependency on system_error
AlexGuteniev Jul 19, 2020
19a1dd2
feature
AlexGuteniev Jul 19, 2020
902ad61
latch not /clr:pure
AlexGuteniev Jul 19, 2020
50ac866
tests
AlexGuteniev Jul 19, 2020
eaed150
c++20 guard
AlexGuteniev Jul 19, 2020
8aab61e
Merge remote-tracking branch 'upstream/master'
AlexGuteniev Jul 21, 2020
f5d945e
remove unwait
AlexGuteniev Jul 21, 2020
21a395c
All. Sorry we don't track waiter count.
AlexGuteniev Jul 21, 2020
94f2f87
actually one, we don't track the waiting too
AlexGuteniev Jul 21, 2020
6d78db0
no wheel invention actually
AlexGuteniev Jul 21, 2020
b893242
}
AlexGuteniev Jul 21, 2020
b627266
whitespace
AlexGuteniev Jul 21, 2020
3e82ec5
actually lets call it "unrecoverable"
AlexGuteniev Jul 21, 2020
cebacd5
Merge remote-tracking branch 'upstream/master'
AlexGuteniev Jul 21, 2020
c5cb0b9
apply padding bits resolution
AlexGuteniev Jul 21, 2020
18e5184
attempt on 16 bytes case
AlexGuteniev Jul 21, 2020
6726c5d
attempt on 16 bytes case
AlexGuteniev Jul 21, 2020
1b4be08
clang format
AlexGuteniev Jul 21, 2020
866966c
Merge remote-tracking branch 'origin/master' into latch
AlexGuteniev Jul 21, 2020
b42025f
attempt on 16 bytes case
AlexGuteniev Jul 21, 2020
fe33a36
attempt on 16 bytes case
AlexGuteniev Jul 21, 2020
73c5cc6
Add test for discovered notify_all_indirect deadlock.
BillyONeal Jul 22, 2020
1244e9c
Fix deadlock in notify_all.
BillyONeal Jul 22, 2020
c55368f
Add RAII guards.
BillyONeal Jul 22, 2020
b308261
Remove timed variants from header; timed infrastructure on the other …
BillyONeal Jul 23, 2020
c326f7f
Use return instead of break in the indirect mode.
BillyONeal Jul 23, 2020
66a2e6e
Add comments explaining the ABI layer to <xatomic_wait.h> and remove …
BillyONeal Jul 23, 2020
7edc9f6
Merge pull request #5 from BillyONeal/atomic_upstream
AlexGuteniev Jul 23, 2020
6279b7b
Document deliberately waking before SRWLOCK exit
AlexGuteniev Jul 23, 2020
de50735
Direct wait to API convention for aliasobj
AlexGuteniev Jul 23, 2020
ba5364d
Some respect to padding bits
AlexGuteniev Jul 23, 2020
b9acf63
clang format
AlexGuteniev Jul 23, 2020
3be75d0
Avoid killing correct pad bits of observed value
AlexGuteniev Jul 23, 2020
3ac6b7b
Minor improvements
AlexGuteniev Jul 23, 2020
50b6861
clang format
AlexGuteniev Jul 24, 2020
4d764eb
no loop needed here, caller handles spurious wakes
AlexGuteniev Jul 24, 2020
9a8de74
STL CR comments.
BillyONeal Jul 24, 2020
1703d44
header safety
AlexGuteniev Jul 25, 2020
74f4758
Merge branch 'master' into latch
AlexGuteniev Jul 25, 2020
5fa1b64
+semaphore
AlexGuteniev Jul 25, 2020
1c61535
memory order
AlexGuteniev Jul 25, 2020
44abe1d
correct use of atomic wait
AlexGuteniev Jul 25, 2020
92c2862
+binary_semahpore
AlexGuteniev Jul 25, 2020
bbd7ea2
until
AlexGuteniev Jul 25, 2020
73ec64c
max for latch to avoid <limits>
AlexGuteniev Jul 25, 2020
0f5bd2a
update test skip list
AlexGuteniev Jul 25, 2020
c9a5b78
handle partial timeout properly
AlexGuteniev Jul 25, 2020
3c4c736
barrier feature stub
AlexGuteniev Jul 26, 2020
dbe9bcb
barrier tentative implementation
AlexGuteniev Jul 26, 2020
15cb748
clang-format
AlexGuteniev Jul 26, 2020
50be0b1
fix bae type
AlexGuteniev Jul 26, 2020
fa7ae3f
fix, make test pass
AlexGuteniev Jul 26, 2020
dc222a9
functor test
AlexGuteniev Jul 26, 2020
4ac114d
fix barrier test, add nodiscard
AlexGuteniev Jul 26, 2020
2f05501
test for max
AlexGuteniev Jul 26, 2020
8faba66
typo
AlexGuteniev Jul 26, 2020
bc0f30d
partial timeout one more fix
AlexGuteniev Jul 26, 2020
b94e722
clang format
AlexGuteniev Jul 26, 2020
9ec059d
simpler barrier counting
AlexGuteniev Jul 26, 2020
f22c43d
calculate step
AlexGuteniev Jul 26, 2020
7628df6
more timeout to avoid spurious fail
AlexGuteniev Jul 26, 2020
2de9335
newline
AlexGuteniev Jul 26, 2020
5241b82
barrier is barrier
AlexGuteniev Jul 26, 2020
dabd97a
acquire fence instead of acq_rel,
AlexGuteniev Jul 27, 2020
44c141f
missing weaker order
AlexGuteniev Jul 27, 2020
cd9e105
longer rel time
AlexGuteniev Jul 27, 2020
558bda0
actually here it should be acq_rel memory order
AlexGuteniev Jul 27, 2020
770bae9
More reliable arrival_token validation
AlexGuteniev Jul 27, 2020
864772e
fix compile
AlexGuteniev Jul 27, 2020
0f2f42b
()
AlexGuteniev Jul 27, 2020
3af10a4
explicit type would be cleaner than nullptr_t
AlexGuteniev Jul 27, 2020
c6cf987
employ empty base optimization for any case
AlexGuteniev Jul 27, 2020
d849add
nothrow
AlexGuteniev Jul 27, 2020
735e3e6
get back member
AlexGuteniev Jul 27, 2020
159020b
no_[[no_unique_address]]
AlexGuteniev Jul 27, 2020
940f949
Better empty base optimization selection
AlexGuteniev Jul 27, 2020
39dcae8
Actually cannot report error as exceptions
AlexGuteniev Jul 27, 2020
d7ddcbc
Actually cannot report error as exceptions++
AlexGuteniev Jul 27, 2020
95b9630
_STL_VERIFY
AlexGuteniev Jul 28, 2020
1adc379
clang format
AlexGuteniev Jul 28, 2020
f0650f1
should notify all
AlexGuteniev Jul 28, 2020
a5b42a7
missing return
AlexGuteniev Jul 28, 2020
7abbc71
empty completion to match Standard
AlexGuteniev Jul 28, 2020
bc6b6d0
Don't miss empty base
AlexGuteniev Jul 28, 2020
21a0776
Improve _STL_VERIFY
AlexGuteniev Jul 28, 2020
8918b8c
acq+rel for arrive_and_wait
AlexGuteniev Jul 28, 2020
061ccf2
_Ugly
AlexGuteniev Jul 28, 2020
b0027e7
fix race
AlexGuteniev Jul 28, 2020
89f90d9
reduce timeouts
AlexGuteniev Jul 28, 2020
2bfa19a
fix `memcmp` race
AlexGuteniev Jul 29, 2020
5471aad
optimize: check before waiting
AlexGuteniev Jul 29, 2020
4266db1
newlines
AlexGuteniev Jul 29, 2020
20356ed
Let's implement this in scope of atomic_ref
AlexGuteniev Jul 29, 2020
fbb3d11
clang format
AlexGuteniev Jul 29, 2020
df57ccd
don't need this if statically available
AlexGuteniev Jul 29, 2020
7f57f6a
STL review: remove wrong const, add noexcept
AlexGuteniev Jul 29, 2020
fa295ec
tests complain
AlexGuteniev Jul 29, 2020
61ec9fe
enforce barrier noexcept
AlexGuteniev Jul 29, 2020
8922377
Merge remote-tracking branch 'origin/master' into latch
AlexGuteniev Jul 29, 2020
04b9622
make semaphore test less sensitive to timing
AlexGuteniev Jul 29, 2020
45b0923
Merge remote-tracking branch 'origin/master' into HEAD
BillyONeal Jul 31, 2020
0968ed2
* Fix timeouts correctness bug wherein we would blow up the timeout o…
BillyONeal Aug 1, 2020
b4478b7
Add perf improvement special case for no timeout to reduce the number…
BillyONeal Aug 1, 2020
a832e67
Apply Stephan and Casey code review fixes.
BillyONeal Aug 1, 2020
fa0aaf6
Merge remote-tracking branch 'upstream/master' into latch
AlexGuteniev Aug 1, 2020
3a9ece4
Merge remote-tracking branch 'origin/master' into latch
AlexGuteniev Aug 1, 2020
c9f9f4d
Remove const from unnamed function parameter
CaseyCarter Aug 1, 2020
1212a8f
Semaphore counter optimization
AlexGuteniev Aug 1, 2020
e73081c
cover max count case with test
AlexGuteniev Aug 1, 2020
7130a20
clang format
AlexGuteniev Aug 1, 2020
fdb5886
Merge remote-tracking branch 'upstream/master' into latch
AlexGuteniev Aug 2, 2020
ea2e773
fix merge error
AlexGuteniev Aug 2, 2020
981556a
fix merge error
AlexGuteniev Aug 2, 2020
1f1f2c3
ws
AlexGuteniev Aug 2, 2020
4e90c42
Merge remote-tracking branch 'upstream/master'
AlexGuteniev Aug 2, 2020
cd4bfd4
remove timing assumption
AlexGuteniev Aug 2, 2020
f5ae641
latch test: assumption to finish in a finite time
AlexGuteniev Aug 2, 2020
4e4be53
no <chrono> needed then
AlexGuteniev Aug 2, 2020
b8b7598
semaphore test: mask out timing assumption
AlexGuteniev Aug 2, 2020
213e66b
16-bit type too
AlexGuteniev Aug 2, 2020
560e237
GH-1133 workaround
AlexGuteniev Aug 3, 2020
2fddcbf
typo
AlexGuteniev Aug 3, 2020
cf9e869
barrier check precondition better
AlexGuteniev Aug 4, 2020
97276f4
Update stl/inc/semaphore
AlexGuteniev Aug 5, 2020
f934eeb
STL comments
AlexGuteniev Aug 5, 2020
7057962
Merge branch 'latch'
AlexGuteniev Aug 5, 2020
7efa65c
STL comments
AlexGuteniev Aug 5, 2020
d5b926f
Update tests/std/tests/P1135R6_semaphore/test.cpp
AlexGuteniev Aug 5, 2020
8a2fcfc
Update tests/std/tests/P1135R6_semaphore/test.cpp
AlexGuteniev Aug 5, 2020
d768838
~
AlexGuteniev Aug 5, 2020
1ad2d32
Merge branch 'latch' of https://github.com/AlexGuteniev/STL into latch
AlexGuteniev Aug 5, 2020
7ddf346
:-(
AlexGuteniev Aug 5, 2020
594147b
Update tests/libcxx/expected_results.txt
AlexGuteniev Aug 5, 2020
1cd4bc6
Update tests/libcxx/skipped_tests.txt
AlexGuteniev Aug 5, 2020
2240714
remove extra spaces
AlexGuteniev Aug 5, 2020
6e2ef71
more STL comments
AlexGuteniev Aug 5, 2020
8a4a9f2
Merge branch 'latch' of https://github.com/AlexGuteniev/STL into latch
AlexGuteniev Aug 5, 2020
787a36a
clang format
AlexGuteniev Aug 5, 2020
b8cde5f
timing assumptions
AlexGuteniev Aug 5, 2020
107c140
++
AlexGuteniev Aug 5, 2020
6dbc25c
\
AlexGuteniev Aug 5, 2020
22a1417
I speak Standardese
AlexGuteniev Aug 5, 2020
60a6ada
prevent token reuse
AlexGuteniev Aug 5, 2020
0dcd50f
optimize contended scenario
AlexGuteniev Aug 7, 2020
893a1db
{
AlexGuteniev Aug 7, 2020
8167828
!=
AlexGuteniev Aug 7, 2020
9898469
avoid #1150
AlexGuteniev Aug 7, 2020
cdb907f
Precise wake count optimization
AlexGuteniev Aug 8, 2020
bead733
grammer
AlexGuteniev Aug 8, 2020
a3e8546
order
AlexGuteniev Aug 8, 2020
a497f2c
Revert "Precise wake count optimization"
AlexGuteniev Aug 8, 2020
cf4bf36
Precise wake count optimization
AlexGuteniev Aug 8, 2020
5ecf1b0
+document
AlexGuteniev Aug 8, 2020
cda5f8a
private value
AlexGuteniev Aug 8, 2020
961a5f8
comment on shift before pre check
AlexGuteniev Aug 8, 2020
1d74f13
+ semaphore optimization for no waiters
AlexGuteniev Aug 8, 2020
55c3cff
-
AlexGuteniev Aug 8, 2020
cafd052
more readable this way
AlexGuteniev Aug 8, 2020
ae60448
Resolves #1120
AlexGuteniev Aug 8, 2020
90f1913
Revert "Resolves #1120"
AlexGuteniev Aug 8, 2020
485311c
Merge remote-tracking branch 'upstream/master' into latch
AlexGuteniev Aug 10, 2020
a6235ad
This is now the last piece of P1135R6
AlexGuteniev Aug 10, 2020
24ec0a5
less
AlexGuteniev Aug 10, 2020
3ca997c
_Compressed_pair
AlexGuteniev Aug 11, 2020
a887830
Enforce least_max_value
AlexGuteniev Aug 11, 2020
b71e86d
Merge remote-tracking 'origin/master' into latch
AlexGuteniev Aug 13, 2020
acf2cb4
Merge remote-tracking 'upstream/master' into latch
AlexGuteniev Aug 13, 2020
97bef22
Mention P1865R1
AlexGuteniev Aug 13, 2020
e337d66
noexcept /* strengthened */
AlexGuteniev Aug 13, 2020
84f5ac6
barrier micro optimizations
AlexGuteniev Aug 13, 2020
f53c9e9
Update stl/inc/semaphore
AlexGuteniev Aug 18, 2020
1c9192c
Update stl/inc/semaphore
AlexGuteniev Aug 18, 2020
9ff64e2
move max
AlexGuteniev Aug 18, 2020
26abe22
Merge branch 'latch' of https://github.com/AlexGuteniev/STL into latch
AlexGuteniev Aug 18, 2020
499297d
@BillyONeal comments
AlexGuteniev Aug 25, 2020
684f77b
token test
AlexGuteniev Aug 25, 2020
0166140
more precise precondition
AlexGuteniev Aug 25, 2020
9883201
memory order paranoia
AlexGuteniev Aug 25, 2020
a6900e4
comment on relaxed
AlexGuteniev Aug 25, 2020
a44a596
Merge remote-tracking branch 'origin/master' into latch
BillyONeal Aug 25, 2020
ae9e2a4
millisecondize
BillyONeal Aug 25, 2020
3dfe326
Apply suggestions from code review
AlexGuteniev Aug 26, 2020
326c18f
Update tests/std/tests/P1135R6_barrier/test.cpp
AlexGuteniev Aug 26, 2020
0c2971a
Update tests/std/tests/P1135R6_barrier/test.cpp
AlexGuteniev Aug 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions stl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/any
${CMAKE_CURRENT_LIST_DIR}/inc/array
${CMAKE_CURRENT_LIST_DIR}/inc/atomic
${CMAKE_CURRENT_LIST_DIR}/inc/barrier
${CMAKE_CURRENT_LIST_DIR}/inc/bit
${CMAKE_CURRENT_LIST_DIR}/inc/bitset
${CMAKE_CURRENT_LIST_DIR}/inc/cassert
Expand Down Expand Up @@ -153,6 +154,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/iso646.h
${CMAKE_CURRENT_LIST_DIR}/inc/istream
${CMAKE_CURRENT_LIST_DIR}/inc/iterator
${CMAKE_CURRENT_LIST_DIR}/inc/latch
${CMAKE_CURRENT_LIST_DIR}/inc/limits
${CMAKE_CURRENT_LIST_DIR}/inc/list
${CMAKE_CURRENT_LIST_DIR}/inc/locale
Expand All @@ -171,6 +173,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/ratio
${CMAKE_CURRENT_LIST_DIR}/inc/regex
${CMAKE_CURRENT_LIST_DIR}/inc/scoped_allocator
${CMAKE_CURRENT_LIST_DIR}/inc/semaphore
${CMAKE_CURRENT_LIST_DIR}/inc/set
${CMAKE_CURRENT_LIST_DIR}/inc/shared_mutex
${CMAKE_CURRENT_LIST_DIR}/inc/span
Expand Down
3 changes: 3 additions & 0 deletions stl/inc/__msvc_all_public_headers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@

#ifndef _M_CEE_PURE
#include <atomic>
#include <barrier>
#include <latch>
#include <semaphore>
#endif // _M_CEE_PURE

#ifndef _M_CEE
Expand Down
198 changes: 198 additions & 0 deletions stl/inc/barrier
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// barrier standard header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once
#ifndef _BARRIER_
#define _BARRIER_
#include <yvals.h>
#if _STL_COMPILER_PREPROCESSOR

#ifdef _M_CEE_PURE
#error <barrier> is not supported when compiling with /clr:pure.
#endif // _M_CEE_PURE

#if !_HAS_CXX20
#pragma message("The contents of <barrier> are available only with C++20 or later.")
#else // ^^^ !_HAS_CXX20 / _HAS_CXX20 vvv

#include <atomic>
#include <limits.h>
#include <type_traits>
#include <xmemory>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

_STD_BEGIN

struct _No_completion_function {
void operator()() noexcept {}
};

template <class _Completion_function = _No_completion_function>
class barrier;

inline constexpr ptrdiff_t _Barrier_arrival_token_mask = 1;
inline constexpr ptrdiff_t _Barrier_value_mask = ~_Barrier_arrival_token_mask;
inline constexpr ptrdiff_t _Barrier_value_shift = 1;
inline constexpr ptrdiff_t _Barrier_invalid_token = 0;
inline constexpr ptrdiff_t _Barrier_value_step = 1 << _Barrier_value_shift;
inline constexpr ptrdiff_t _Barrier_max = (1ULL << (sizeof(ptrdiff_t) * CHAR_BIT - 2)) - 1;

template <class _Completion_function>
class _Arrival_token {
public:
_Arrival_token(_Arrival_token&& _Other) noexcept {
_Value = _Other._Value;
_Other._Value = _Barrier_invalid_token;
}

_Arrival_token& operator=(_Arrival_token&& _Other) noexcept {
_Value = _Other._Value;
_Other._Value = _Barrier_invalid_token;
return *this;
}

private:
explicit _Arrival_token(ptrdiff_t _Value_) noexcept : _Value(_Value_) {}
friend barrier<_Completion_function>;

ptrdiff_t _Value;
};

template <class _Completion_function>
class barrier {
public:
static_assert(
#ifndef __cpp_noexcept_function_type
is_function_v<remove_pointer_t<_Completion_function>> ||
#endif // __cpp_noexcept_function_type
is_nothrow_invocable_v<_Completion_function&>,
"N4861 [thread.barrier.class]/5: is_nothrow_invocable_v<CompletionFunction&> shall be true");

using arrival_token = _Arrival_token<_Completion_function>;

constexpr explicit barrier(
const ptrdiff_t _Expected, _Completion_function _Fn = _Completion_function()) noexcept /* strengthened */
: _Val(_One_then_variadic_args_t{}, _STD move(_Fn), _Expected << _Barrier_value_shift) {
_STL_VERIFY(_Val._Myval2._Current.load(memory_order_relaxed) >= 0,
"Precondition: expected >= 0 and expected <= max() (N4861 [thread.barrier.class]/9)");
}

barrier(const barrier&) = delete;
barrier& operator=(const barrier&) = delete;

_NODISCARD static constexpr ptrdiff_t(max)() noexcept {
return _Barrier_max;
}

_NODISCARD arrival_token arrive(ptrdiff_t _Update = 1) noexcept /* strengthened */ {
// Shifting before precondition check, so that exceeding max() will trigger precondition check too
_Update <<= _Barrier_value_shift;
_STL_VERIFY(_Update > 0, "Precondition: update > 0 (N4861 [thread.barrier.class]/12)");
// TRANSITION, GH-1133: should be memory_order_release
ptrdiff_t _Current = _Val._Myval2._Current.fetch_sub(_Update) - _Update;
_STL_VERIFY(_Current >= 0, "Precondition: update is less than or equal to the expected count "
"for the current barrier phase (N4861 [thread.barrier.class]/12)");
if ((_Current & _Barrier_value_mask) == 0) {
// TRANSITION, GH-1133: should have this fence:
// atomic_thread_fence(memory_order_acquire);
_Completion(_Current);
}
// Embedding this into the token to provide an additional correctness check that the token is from the same
// barrier and wasn't used. All bits of this fit, as barrier should be aligned to at least the size of an
// atomic counter.
return arrival_token{(_Current & _Barrier_arrival_token_mask) | reinterpret_cast<intptr_t>(this)};
}

void wait(arrival_token&& _Arrival) const noexcept /* strengthened */ {
_STL_VERIFY((_Arrival._Value & _Barrier_value_mask) == reinterpret_cast<intptr_t>(this),
"Preconditions: arrival is associated with the phase synchronization point for the current phase "
"or the immediately preceding phase of the same barrier object (N4861 [thread.barrier.class]/19)");
const ptrdiff_t _Arrival_value = _Arrival._Value & _Barrier_arrival_token_mask;
_Arrival._Value = _Barrier_invalid_token;
for (;;) {
// TRANSITION, GH-1133: should be memory_order_acquire
const ptrdiff_t _Current = _Val._Myval2._Current.load();
_STL_VERIFY(_Current >= 0, "Invariant counter >= 0, possibly caused by preconditions violation "
"(N4861 [thread.barrier.class]/12)");
if ((_Current & _Barrier_arrival_token_mask) != _Arrival_value) {
break;
}
_Val._Myval2._Current.wait(_Current, memory_order_relaxed);
}
}

void arrive_and_wait() noexcept /* strengthened */ {
// TRANSITION, GH-1133: should be memory_order_acq_rel
ptrdiff_t _Current = _Val._Myval2._Current.fetch_sub(_Barrier_value_step) - _Barrier_value_step;
const ptrdiff_t _Arrival = _Current & _Barrier_arrival_token_mask;
_STL_VERIFY(_Current >= 0, "Precondition: update is less than or equal to the expected count "
"for the current barrier phase (N4861 [thread.barrier.class]/12)");
if ((_Current & _Barrier_value_mask) == 0) {
_Completion(_Current);
return;
}

for (;;) {
_Val._Myval2._Current.wait(_Current, memory_order_relaxed);
// TRANSITION, GH-1133: should be memory_order_acquire
_Current = _Val._Myval2._Current.load();
_STL_VERIFY(_Current >= 0, "Invariant counter >= 0, possibly caused by preconditions violation "
"(N4861 [thread.barrier.class]/12)");
if ((_Current & _Barrier_arrival_token_mask) != _Arrival) {
break;
}
}
}

void arrive_and_drop() noexcept /* strengthened */ {
const ptrdiff_t _Rem_count =
_Val._Myval2._Total.fetch_sub(_Barrier_value_step, memory_order_relaxed) - _Barrier_value_step;
_STL_VERIFY(_Rem_count >= 0, "Precondition: The expected count for the current barrier phase "
"is greater than zero (N4861 [thread.barrier.class]/24) "
"(checked initial expected count, which is not less than the current)");
(void) arrive(1);
}

private:
void _Completion(const ptrdiff_t _Current) noexcept {
const ptrdiff_t _Rem_count = _Val._Myval2._Total.load(memory_order_relaxed);
_STL_VERIFY(_Rem_count >= 0, "Invariant: initial expected count less than zero, "
"possibly caused by preconditions violation "
"(N4861 [thread.barrier.class]/24)");
_Val._Get_first()();
const ptrdiff_t _New_phase_count = _Rem_count | ((_Current + 1) & _Barrier_arrival_token_mask);
// TRANSITION, GH-1133: should be memory_order_release
_Val._Myval2._Current.store(_New_phase_count);
_Val._Myval2._Current.notify_all();
}

struct _Counter_t {
constexpr explicit _Counter_t(ptrdiff_t _Initial) : _Current(_Initial), _Total(_Initial) {}
// wait(arrival_token&&) accepts a token from the current phase or the immediately preceding phase; this means
// we can track which phase is the current phase using 1 bit which alternates between each phase. For this
// purpose we use the low order bit of _Current.
atomic<ptrdiff_t> _Current;
atomic<ptrdiff_t> _Total;
};

_Compressed_pair<_Completion_function, _Counter_t> _Val;
};

_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // ^^^ _HAS_CXX20 ^^^

#endif // _STL_COMPILER_PREPROCESSOR
#endif // _BARRIER_
101 changes: 101 additions & 0 deletions stl/inc/latch
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// latch standard header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once
#ifndef _LATCH_
#define _LATCH_
#include <yvals.h>
#if _STL_COMPILER_PREPROCESSOR

#ifdef _M_CEE_PURE
#error <latch> is not supported when compiling with /clr:pure.
#endif // _M_CEE_PURE

#if !_HAS_CXX20
#pragma message("The contents of <latch> are available only with C++20 or later.")
#else // ^^^ !_HAS_CXX20 / _HAS_CXX20 vvv

#include <atomic>
#include <limits.h>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

_STD_BEGIN

class latch {
public:
_NODISCARD static constexpr ptrdiff_t(max)() noexcept {
return (1ULL << (sizeof(ptrdiff_t) * CHAR_BIT - 1)) - 1;
}

constexpr explicit latch(const ptrdiff_t _Expected) noexcept /* strengthened */ : _Counter{_Expected} {
_STL_VERIFY(_Expected >= 0, "Precondition: expected >= 0 (N4861 [thread.latch.class]/4)");
}

latch(const latch&) = delete;
latch& operator=(const latch&) = delete;

void count_down(const ptrdiff_t _Update = 1) noexcept /* strengthened */ {
_STL_VERIFY(_Update >= 0, "Precondition: update >= 0 (N4861 [thread.latch.class]/7)");
// TRANSITION, GH-1133: should be memory_order_release
const ptrdiff_t _Current = _Counter.fetch_sub(_Update) - _Update;
if (_Current == 0) {
_Counter.notify_all();
} else {
_STL_VERIFY(_Current >= 0, "Precondition: update <= counter (N4861 [thread.latch.class]/7)");
}
}

_NODISCARD bool try_wait() const noexcept {
// TRANSITION, GH-1133: should be memory_order_acquire
return _Counter.load() == 0;
}

void wait() const noexcept /* strengthened */ {
for (;;) {
// TRANSITION, GH-1133: should be memory_order_acquire
const ptrdiff_t _Current = _Counter.load();
if (_Current == 0) {
return;
} else {
_STL_VERIFY(_Current > 0, "Invariant counter >= 0, possibly caused by preconditions violation "
"(N4861 [thread.latch.class]/7)");
}
_Counter.wait(_Current, memory_order_relaxed);
}
}

void arrive_and_wait(const ptrdiff_t _Update = 1) noexcept /* strengthened */ {
_STL_VERIFY(_Update >= 0, "Precondition: update >= 0 (N4861 [thread.latch.class]/7)");
// TRANSITION, GH-1133: should be memory_order_acq_rel
const ptrdiff_t _Current = _Counter.fetch_sub(_Update) - _Update;
if (_Current == 0) {
_Counter.notify_all();
} else {
_STL_VERIFY(_Current > 0, "Precondition: update <= counter (N4861 [thread.latch.class]/7)");
_Counter.wait(_Current, memory_order_relaxed);
wait();
}
}

private:
atomic<ptrdiff_t> _Counter;
};

_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // ^^^ _HAS_CXX20 ^^^

#endif // _STL_COMPILER_PREPROCESSOR
#endif // _LATCH_
Loading