diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/threading/light_rw_lock/bench/lightrwlock_test.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/threading/light_rw_lock/bench/lightrwlock_test.cpp')
-rw-r--r-- | library/cpp/threading/light_rw_lock/bench/lightrwlock_test.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/library/cpp/threading/light_rw_lock/bench/lightrwlock_test.cpp b/library/cpp/threading/light_rw_lock/bench/lightrwlock_test.cpp new file mode 100644 index 00000000000..c3027ea5449 --- /dev/null +++ b/library/cpp/threading/light_rw_lock/bench/lightrwlock_test.cpp @@ -0,0 +1,188 @@ +#include <library/cpp/threading/light_rw_lock/lightrwlock.h> +#include <util/random/random.h> + +#ifdef _linux_ +// Light rw lock is implemented only for linux + +using namespace NS_LightRWLock; + +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> + +#define LIGHT + +#ifdef RWSPINLOCK +#include <library/cpp/lwtrace/rwspinlock.h> +#endif + +#define CHECK_LOGIC 1 +#define LOOPCOUNT 1000000 +#define RANRCOUNT 100 +#define THREADCOUNT 40 +#define WRITELOCKS 100 + +#if defined(_MSC_VER) +static int Y_FORCE_INLINE AtomicFetchAdd(volatile int& item, int value) { + return _InterlockedExchangeAdd((&item, value); +} +#elif defined(__GNUC__) +#else +#error unsupported platform +#endif + +class TPosixRWLock { +public: + TPosixRWLock() { + } + + ~TPosixRWLock() { + pthread_rwlock_destroy(&rwlock); + } + + TPosixRWLock(const TPosixRWLock&) = delete; + void operator=(const TPosixRWLock&) = delete; + +private: + pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; + friend class TPosixRWShareLocker; + friend class TPosixRWExclusiveLocker; +}; + +#if defined(LIGHT) +TLightRWLock __attribute__((aligned(64))) rwlock; +#elif defined(POSIX) +TPosixRWLock rwlock; +#elif defined(RWSPINLOCK) +TRWSpinLock __attribute__((aligned(64))) rwlock; +#else +#error "define lock type" +#endif + +volatile __attribute__((aligned(64))) int checkIt = 0; +volatile int checkExcl = 0; + +class TPosixRWShareLocker { +public: + TPosixRWShareLocker(TPosixRWLock& lock) + : LockP_(&lock) + { + pthread_rwlock_rdlock(&LockP_->rwlock); + } + + ~TPosixRWShareLocker() { + pthread_rwlock_unlock(&LockP_->rwlock); + } + + TPosixRWShareLocker(const TPosixRWShareLocker&) = delete; + void operator=(const TPosixRWShareLocker&) = delete; + +private: + TPosixRWLock* LockP_; +}; + +class TPosixRWExclusiveLocker { +public: + TPosixRWExclusiveLocker(TPosixRWLock& lock) + : LockP_(&lock) + { + pthread_rwlock_wrlock(&LockP_->rwlock); + } + + ~TPosixRWExclusiveLocker() { + pthread_rwlock_unlock(&LockP_->rwlock); + } + TPosixRWExclusiveLocker(const TPosixRWExclusiveLocker&) = delete; + void operator=(const TPosixRWExclusiveLocker&) = delete; + +private: + TPosixRWLock* LockP_; +}; + +template <typename TLocker, bool excl> +static Y_FORCE_INLINE void Run() { + TLocker lockIt(rwlock); + +#if defined(CHECK_LOGIC) && CHECK_LOGIC + if (!excl && checkExcl == 1) { + printf("there is a bug\n"); + } + + int result = AtomicFetchAdd(checkIt, 1); + if (excl) + checkExcl = 1; + + if (excl && result > 1) + printf("there is a bug\n"); +#endif + + for (unsigned w = 0; w < RANRCOUNT; ++w) + RandomNumber<ui32>(); + +#if defined(CHECK_LOGIC) && CHECK_LOGIC + if (excl) + checkExcl = 0; + + AtomicFetchAdd(checkIt, -1); +#endif +} + +#ifdef LIGHT +static void* fast_thread_start(__attribute__((unused)) void* arg) { + for (unsigned q = 0; q < LOOPCOUNT; ++q) { + char excl = (RandomNumber<ui32>() % WRITELOCKS) == 0; + if (excl) + Run<TLightWriteGuard, 1>(); + else + Run<TLightReadGuard, 0>(); + } + return NULL; +} +#endif + +#ifdef POSIX +static void* fast_thread_start(__attribute__((unused)) void* arg) { + for (unsigned q = 0; q < LOOPCOUNT; ++q) { + char excl = (RandomNumber<ui32>() % WRITELOCKS) == 0; + if (excl) + Run<TPosixRWExclusiveLocker, 1>(); + else + Run<TPosixRWShareLocker, 0>(); + } + return NULL; +} +#endif + +#ifdef RWSPINLOCK +static void* fast_thread_start(__attribute__((unused)) void* arg) { + for (unsigned q = 0; q < LOOPCOUNT; ++q) { + char excl = (RandomNumber<ui32>() % WRITELOCKS) == 0; + if (excl) + Run<TWriteSpinLockGuard, 1>(); + else + Run<TReadSpinLockGuard, 0>(); + } + return NULL; +} +#endif + +int main() { + pthread_t threads[THREADCOUNT]; + + for (unsigned q = 0; q < THREADCOUNT; ++q) { + pthread_create(&(threads[q]), NULL, &fast_thread_start, NULL); + } + + for (unsigned q = 0; q < THREADCOUNT; ++q) + pthread_join(threads[q], NULL); + + return 0; +} + +#else // !_linux_ + +int main() { + return 0; +} + +#endif |