Skip to content

Commit

Permalink
xnotify.cpp: SRWLOCK to protect the at-thread-exit data instead o…
Browse files Browse the repository at this point in the history
…f an indexed `CRITICAL_SECTION` (#4408)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
  • Loading branch information
AlexGuteniev and StephanTLavavej authored Feb 27, 2024
1 parent 88fe449 commit 85c6ecd
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 24 deletions.
7 changes: 3 additions & 4 deletions stl/inc/yvals.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,9 @@ _EMIT_STL_WARNING(STL4001, "/clr:pure is deprecated and will be REMOVED.");
#endif
#endif // !defined(_CRTDATA2_IMPORT)

#define _LOCK_LOCALE 0
#define _LOCK_STREAM 2
#define _LOCK_DEBUG 3
#define _LOCK_AT_THREAD_EXIT 4
#define _LOCK_LOCALE 0
#define _LOCK_STREAM 2
#define _LOCK_DEBUG 3

#ifndef _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B
#if _STL_WIN32_WINNT >= _STL_WIN32_WINNT_WINBLUE && defined(_WIN64)
Expand Down
12 changes: 1 addition & 11 deletions stl/src/xlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

_STD_BEGIN

constexpr int _Max_lock = 8; // must be power of two
constexpr int _Max_lock = 8; // must be power of two; TRANSITION, ABI: may be less now

#pragma warning(disable : 4074)
#pragma init_seg(compiler)
Expand Down Expand Up @@ -121,14 +121,4 @@ void __cdecl _Lockit::_Lockit_dtor(int kind) noexcept { // unlock the mutex
_Mtxunlock(&mtx[kind & (_Max_lock - 1)]);
}
}

extern "C" {
void _Lock_at_thread_exit_mutex() noexcept { // lock the at-thread-exit mutex
_Mtxlock(&mtx[_LOCK_AT_THREAD_EXIT]);
}
void _Unlock_at_thread_exit_mutex() noexcept { // unlock the at-thread-exit mutex
_Mtxunlock(&mtx[_LOCK_AT_THREAD_EXIT]);
}
} // extern "C"

_STD_END
15 changes: 6 additions & 9 deletions stl/src/xnotify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cstdlib>
#include <mutex>
#include <xthreads.h>

#include <Windows.h>
Expand All @@ -23,20 +24,19 @@ namespace {
};

_At_thread_exit_block _Thread_exit_data;

constinit std::mutex _Thread_exit_data_mutex;
} // unnamed namespace

extern "C" {

void _Lock_at_thread_exit_mutex() noexcept;
void _Unlock_at_thread_exit_mutex() noexcept;

_CRTIMP2_PURE void __cdecl _Cnd_register_at_thread_exit(_Cnd_t cnd, _Mtx_t mtx, int* p) noexcept {
// register condition variable and mutex for cleanup at thread exit

// find block with available space
_At_thread_exit_block* block = &_Thread_exit_data;

_Lock_at_thread_exit_mutex();
std::lock_guard _Lock{_Thread_exit_data_mutex};
while (block != nullptr) { // loop through list of blocks
if (block->num_used == _Nitems) { // block is full; move to next block and allocate
if (block->next == nullptr) {
Expand All @@ -58,7 +58,6 @@ _CRTIMP2_PURE void __cdecl _Cnd_register_at_thread_exit(_Cnd_t cnd, _Mtx_t mtx,
block = nullptr;
}
}
_Unlock_at_thread_exit_mutex();
}

_CRTIMP2_PURE void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_t mtx) noexcept {
Expand All @@ -67,7 +66,7 @@ _CRTIMP2_PURE void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_t mtx) noexcept {
// find condition variables waiting for this thread to exit
_At_thread_exit_block* block = &_Thread_exit_data;

_Lock_at_thread_exit_mutex();
std::lock_guard _Lock{_Thread_exit_data_mutex};
while (block != nullptr) { // loop through list of blocks
for (int i = 0; block->num_used != 0 && i < _Nitems; ++i) {
if (block->data[i].mtx == mtx) { // release slot
Expand All @@ -78,7 +77,6 @@ _CRTIMP2_PURE void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_t mtx) noexcept {

block = block->next;
}
_Unlock_at_thread_exit_mutex();
}

_CRTIMP2_PURE void __cdecl _Cnd_do_broadcast_at_thread_exit() noexcept {
Expand All @@ -88,7 +86,7 @@ _CRTIMP2_PURE void __cdecl _Cnd_do_broadcast_at_thread_exit() noexcept {
_At_thread_exit_block* block = &_Thread_exit_data;
const unsigned int currentThreadId = _Thrd_id();

_Lock_at_thread_exit_mutex();
std::lock_guard _Lock{_Thread_exit_data_mutex};
while (block != nullptr) { // loop through list of blocks
for (int i = 0; block->num_used != 0 && i < _Nitems; ++i) {
if (block->data[i].mtx != nullptr && block->data[i].id._Id == currentThreadId) { // notify and release slot
Expand All @@ -104,7 +102,6 @@ _CRTIMP2_PURE void __cdecl _Cnd_do_broadcast_at_thread_exit() noexcept {

block = block->next;
}
_Unlock_at_thread_exit_mutex();
}

} // extern "C"
Expand Down

0 comments on commit 85c6ecd

Please sign in to comment.