Add a more performant SpinLockDelay implementation for Windows based on WaitOnAddress and friends
This commit is contained in:
parent
fd0fabe183
commit
589d416977
|
@ -566,6 +566,9 @@ if(MINGW OR MSVC)
|
|||
# We also need to tell mingw that sysinfo.cc needs shlwapi.lib.
|
||||
# (We do this via a #pragma for msvc, but need to do it here for mingw).
|
||||
target_link_libraries(sysinfo shlwapi)
|
||||
# spinlock uses WaitOnAddress et al. We need to link to synchronization.lib
|
||||
# (We also do this via a #pragma for msvc, but need to do it here for mingw).
|
||||
target_link_libraries(spinlock synchronization)
|
||||
|
||||
else()
|
||||
set(SPINLOCK_INCLUDES src/base/spinlock.h
|
||||
|
|
|
@ -205,6 +205,7 @@ noinst_LTLIBRARIES += libspinlock.la
|
|||
libspinlock_la_SOURCES = src/base/spinlock.cc \
|
||||
src/base/spinlock_internal.cc \
|
||||
$(SPINLOCK_INCLUDES)
|
||||
libspinlock_la_LIBADD = -lsynchronization
|
||||
|
||||
LIBSPINLOCK = libwindows.la libspinlock.la libsysinfo.la liblogging.la
|
||||
|
||||
|
|
|
@ -35,19 +35,28 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma comment(lib, "Synchronization.lib")
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
namespace internal {
|
||||
|
||||
void SpinLockDelay(std::atomic<int> *w, int32 value, int loop) {
|
||||
if (loop == 0) {
|
||||
} else if (loop == 1) {
|
||||
Sleep(0);
|
||||
} else {
|
||||
Sleep(base::internal::SuggestedDelayNS(loop) / 1000000);
|
||||
if (loop != 0) {
|
||||
auto wait_ns = static_cast<uint64_t>(base::internal::SuggestedDelayNS(loop)) * 16;
|
||||
auto wait_ms = wait_ns / 1000000;
|
||||
|
||||
WaitOnAddress(w, &value, 4, static_cast<DWORD>(wait_ms));
|
||||
}
|
||||
}
|
||||
|
||||
void SpinLockWake(std::atomic<int> *w, bool all) {
|
||||
if (all) {
|
||||
WakeByAddressAll((void*)w);
|
||||
} else {
|
||||
WakeByAddressSingle((void*)w);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
|
Loading…
Reference in New Issue