diff options
author | nga <nga@yandex-team.ru> | 2022-02-10 16:48:09 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:48:09 +0300 |
commit | 1f553f46fb4f3c5eec631352cdd900a0709016af (patch) | |
tree | a231fba2c03b440becaea6c86a2702d0bfb0336e /util/thread | |
parent | c4de7efdedc25b49cbea74bd589eecb61b55b60a (diff) | |
download | ydb-1f553f46fb4f3c5eec631352cdd900a0709016af.tar.gz |
Restoring authorship annotation for <nga@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'util/thread')
-rw-r--r-- | util/thread/lfqueue.h | 58 | ||||
-rw-r--r-- | util/thread/lfqueue_ut.cpp | 144 | ||||
-rw-r--r-- | util/thread/lfstack.h | 46 | ||||
-rw-r--r-- | util/thread/lfstack_ut.cpp | 316 | ||||
-rw-r--r-- | util/thread/pool.cpp | 4 | ||||
-rw-r--r-- | util/thread/pool_ut.cpp | 8 | ||||
-rw-r--r-- | util/thread/singleton.h | 30 | ||||
-rw-r--r-- | util/thread/singleton_ut.cpp | 32 |
8 files changed, 319 insertions, 319 deletions
diff --git a/util/thread/lfqueue.h b/util/thread/lfqueue.h index ab523631e4..2bd4416737 100644 --- a/util/thread/lfqueue.h +++ b/util/thread/lfqueue.h @@ -173,27 +173,27 @@ class TLockFreeQueue: public TNonCopyable { void EnqueueImpl(TListNode* head, TListNode* tail) { TRootNode* newRoot = new TRootNode; - AsyncRef(); + AsyncRef(); AtomicSet(newRoot->PushQueue, head); - for (;;) { + for (;;) { TRootNode* curRoot = AtomicGet(JobQueue); AtomicSet(tail->Next, AtomicGet(curRoot->PushQueue)); AtomicSet(newRoot->PopQueue, AtomicGet(curRoot->PopQueue)); - newRoot->CopyCounter(curRoot); - + newRoot->CopyCounter(curRoot); + for (TListNode* node = head;; node = AtomicGet(node->Next)) { - newRoot->IncCount(node->Data); - if (node == tail) - break; - } - - if (AtomicCas(&JobQueue, newRoot, curRoot)) { + newRoot->IncCount(node->Data); + if (node == tail) + break; + } + + if (AtomicCas(&JobQueue, newRoot, curRoot)) { AsyncUnref(curRoot, nullptr); - break; - } - } - } - + break; + } + } + } + template <typename TCollection> static void FillCollection(TListNode* lst, TCollection* res) { while (lst) { @@ -242,8 +242,8 @@ public: template <typename U> void Enqueue(U&& data) { TListNode* newNode = new TListNode(std::forward<U>(data)); - EnqueueImpl(newNode, newNode); - } + EnqueueImpl(newNode, newNode); + } void Enqueue(T&& data) { TListNode* newNode = new TListNode(std::move(data)); EnqueueImpl(newNode, newNode); @@ -252,24 +252,24 @@ public: TListNode* newNode = new TListNode(data); EnqueueImpl(newNode, newNode); } - template <typename TCollection> + template <typename TCollection> void EnqueueAll(const TCollection& data) { - EnqueueAll(data.begin(), data.end()); - } - template <typename TIter> + EnqueueAll(data.begin(), data.end()); + } + template <typename TIter> void EnqueueAll(TIter dataBegin, TIter dataEnd) { - if (dataBegin == dataEnd) - return; - - TIter i = dataBegin; + if (dataBegin == dataEnd) + return; + + TIter i = dataBegin; TListNode* volatile node = new TListNode(*i); TListNode* volatile tail = node; - - for (++i; i != dataEnd; ++i) { - TListNode* nextNode = node; + + for (++i; i != dataEnd; ++i) { + TListNode* nextNode = node; node = new TListNode(*i, nextNode); } - EnqueueImpl(node, tail); + EnqueueImpl(node, tail); } bool Dequeue(T* data) { TRootNode* newRoot = nullptr; diff --git a/util/thread/lfqueue_ut.cpp b/util/thread/lfqueue_ut.cpp index 83bca100cf..d65fbd3769 100644 --- a/util/thread/lfqueue_ut.cpp +++ b/util/thread/lfqueue_ut.cpp @@ -6,9 +6,9 @@ #include <util/generic/ptr.h> #include <util/system/atomic.h> #include <util/thread/pool.h> - + #include "lfqueue.h" - + class TMoveTest { public: TMoveTest(int marker = 0, int value = 0) @@ -122,74 +122,74 @@ Y_UNIT_TEST_SUITE(TLockFreeQueueTests) { } Y_UNIT_TEST(TestSimpleEnqueueDequeue) { - TLockFreeQueue<int> queue; - + TLockFreeQueue<int> queue; + int i = -1; - - UNIT_ASSERT(!queue.Dequeue(&i)); + + UNIT_ASSERT(!queue.Dequeue(&i)); UNIT_ASSERT_VALUES_EQUAL(i, -1); - - queue.Enqueue(10); - queue.Enqueue(11); - queue.Enqueue(12); - - UNIT_ASSERT(queue.Dequeue(&i)); - UNIT_ASSERT_VALUES_EQUAL(10, i); - UNIT_ASSERT(queue.Dequeue(&i)); - UNIT_ASSERT_VALUES_EQUAL(11, i); - - queue.Enqueue(13); - - UNIT_ASSERT(queue.Dequeue(&i)); - UNIT_ASSERT_VALUES_EQUAL(12, i); - UNIT_ASSERT(queue.Dequeue(&i)); - UNIT_ASSERT_VALUES_EQUAL(13, i); - - UNIT_ASSERT(!queue.Dequeue(&i)); + + queue.Enqueue(10); + queue.Enqueue(11); + queue.Enqueue(12); + + UNIT_ASSERT(queue.Dequeue(&i)); + UNIT_ASSERT_VALUES_EQUAL(10, i); + UNIT_ASSERT(queue.Dequeue(&i)); + UNIT_ASSERT_VALUES_EQUAL(11, i); + + queue.Enqueue(13); + + UNIT_ASSERT(queue.Dequeue(&i)); + UNIT_ASSERT_VALUES_EQUAL(12, i); + UNIT_ASSERT(queue.Dequeue(&i)); + UNIT_ASSERT_VALUES_EQUAL(13, i); + + UNIT_ASSERT(!queue.Dequeue(&i)); const int tmp = 100; queue.Enqueue(tmp); UNIT_ASSERT(queue.Dequeue(&i)); UNIT_ASSERT_VALUES_EQUAL(i, tmp); - } - + } + Y_UNIT_TEST(TestSimpleEnqueueAllDequeue) { - TLockFreeQueue<int> queue; - + TLockFreeQueue<int> queue; + int i = -1; - - UNIT_ASSERT(!queue.Dequeue(&i)); + + UNIT_ASSERT(!queue.Dequeue(&i)); UNIT_ASSERT_VALUES_EQUAL(i, -1); - + TVector<int> v; - v.push_back(20); - v.push_back(21); - - queue.EnqueueAll(v); - - v.clear(); - v.push_back(22); - v.push_back(23); - v.push_back(24); - - queue.EnqueueAll(v); - - v.clear(); - queue.EnqueueAll(v); - - v.clear(); - v.push_back(25); - - queue.EnqueueAll(v); - - for (int j = 20; j <= 25; ++j) { - UNIT_ASSERT(queue.Dequeue(&i)); - UNIT_ASSERT_VALUES_EQUAL(j, i); - } - - UNIT_ASSERT(!queue.Dequeue(&i)); - } - + v.push_back(20); + v.push_back(21); + + queue.EnqueueAll(v); + + v.clear(); + v.push_back(22); + v.push_back(23); + v.push_back(24); + + queue.EnqueueAll(v); + + v.clear(); + queue.EnqueueAll(v); + + v.clear(); + v.push_back(25); + + queue.EnqueueAll(v); + + for (int j = 20; j <= 25; ++j) { + UNIT_ASSERT(queue.Dequeue(&i)); + UNIT_ASSERT_VALUES_EQUAL(j, i); + } + + UNIT_ASSERT(!queue.Dequeue(&i)); + } + void DequeueAllRunner(TLockFreeQueue<int>& queue, bool singleConsumer) { size_t threadsNum = 4; size_t enqueuesPerThread = 10'000; @@ -304,19 +304,19 @@ Y_UNIT_TEST_SUITE(TLockFreeQueueTests) { Y_UNIT_TEST(CleanInDestructor) { TSimpleSharedPtr<bool> p(new bool); - UNIT_ASSERT_VALUES_EQUAL(1u, p.RefCount()); - - { + UNIT_ASSERT_VALUES_EQUAL(1u, p.RefCount()); + + { TLockFreeQueue<TSimpleSharedPtr<bool>> stack; - - stack.Enqueue(p); - stack.Enqueue(p); - - UNIT_ASSERT_VALUES_EQUAL(3u, p.RefCount()); - } - - UNIT_ASSERT_VALUES_EQUAL(1, p.RefCount()); - } + + stack.Enqueue(p); + stack.Enqueue(p); + + UNIT_ASSERT_VALUES_EQUAL(3u, p.RefCount()); + } + + UNIT_ASSERT_VALUES_EQUAL(1, p.RefCount()); + } Y_UNIT_TEST(CheckOperationsCount) { TOperationsChecker o; @@ -330,4 +330,4 @@ Y_UNIT_TEST_SUITE(TLockFreeQueueTests) { queue.Dequeue(&o); o.Check(0, 0, 2, 1, 0); } -} +} diff --git a/util/thread/lfstack.h b/util/thread/lfstack.h index ca3d95f3c3..81534cd1d1 100644 --- a/util/thread/lfstack.h +++ b/util/thread/lfstack.h @@ -43,12 +43,12 @@ class TLockFreeStack: TNonCopyable { } } void EnqueueImpl(TNode* volatile head, TNode* volatile tail) { - for (;;) { + for (;;) { tail->Next = AtomicGet(Head); - if (AtomicCas(&Head, head, tail->Next)) - break; - } - } + if (AtomicCas(&Head, head, tail->Next)) + break; + } + } template <class U> void EnqueueImpl(U&& u) { TNode* volatile node = new TNode(std::forward<U>(u)); @@ -69,31 +69,31 @@ public: void Enqueue(const T& t) { EnqueueImpl(t); - } + } void Enqueue(T&& t) { EnqueueImpl(std::move(t)); } - template <typename TCollection> + template <typename TCollection> void EnqueueAll(const TCollection& data) { - EnqueueAll(data.begin(), data.end()); - } - template <typename TIter> + EnqueueAll(data.begin(), data.end()); + } + template <typename TIter> void EnqueueAll(TIter dataBegin, TIter dataEnd) { - if (dataBegin == dataEnd) { - return; + if (dataBegin == dataEnd) { + return; } - TIter i = dataBegin; + TIter i = dataBegin; TNode* volatile node = new TNode(*i); TNode* volatile tail = node; - - for (++i; i != dataEnd; ++i) { - TNode* nextNode = node; - node = new TNode(*i); - node->Next = nextNode; - } - EnqueueImpl(node, tail); + + for (++i; i != dataEnd; ++i) { + TNode* nextNode = node; + node = new TNode(*i); + node->Next = nextNode; + } + EnqueueImpl(node, tail); } bool Dequeue(T* res) { AtomicAdd(DequeueCount, 1); @@ -122,8 +122,8 @@ public: return false; } // add all elements to *res - // elements are returned in order of dequeue (top to bottom; see example in unittest) - template <typename TCollection> + // elements are returned in order of dequeue (top to bottom; see example in unittest) + template <typename TCollection> void DequeueAll(TCollection* res) { AtomicAdd(DequeueCount, 1); for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) { @@ -168,7 +168,7 @@ public: } // add all elements to *res // elements are returned in order of dequeue (top to bottom; see example in unittest) - template <typename TCollection> + template <typename TCollection> void DequeueAllSingleConsumer(TCollection* res) { for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) { if (AtomicCas(&Head, (TNode*)nullptr, current)) { diff --git a/util/thread/lfstack_ut.cpp b/util/thread/lfstack_ut.cpp index e20a838f95..824d633a62 100644 --- a/util/thread/lfstack_ut.cpp +++ b/util/thread/lfstack_ut.cpp @@ -1,194 +1,194 @@ -#include <util/system/atomic.h> -#include <util/system/event.h> +#include <util/system/atomic.h> +#include <util/system/event.h> #include <util/generic/deque.h> #include <library/cpp/threading/future/legacy_future.h> - + #include <library/cpp/testing/unittest/registar.h> - + #include "lfstack.h" - + Y_UNIT_TEST_SUITE(TLockFreeStackTests) { - class TCountDownLatch { - private: + class TCountDownLatch { + private: TAtomic Current_; TSystemEvent EventObject_; - public: - TCountDownLatch(unsigned initial) + public: + TCountDownLatch(unsigned initial) : Current_(initial) { } - - void CountDown() { + + void CountDown() { if (AtomicDecrement(Current_) == 0) { EventObject_.Signal(); - } - } - - void Await() { + } + } + + void Await() { EventObject_.Wait(); - } - - bool Await(TDuration timeout) { + } + + bool Await(TDuration timeout) { return EventObject_.WaitT(timeout); - } - }; - - template <bool SingleConsumer> - struct TDequeueAllTester { - size_t EnqueueThreads; - size_t DequeueThreads; - - size_t EnqueuesPerThread; - TAtomic LeftToDequeue; - - TCountDownLatch StartLatch; - TLockFreeStack<int> Stack; - - TDequeueAllTester() - : EnqueueThreads(4) - , DequeueThreads(SingleConsumer ? 1 : 3) - , EnqueuesPerThread(100000) - , LeftToDequeue(EnqueueThreads * EnqueuesPerThread) - , StartLatch(EnqueueThreads + DequeueThreads) - { - } - - void Enqueuer() { - StartLatch.CountDown(); - StartLatch.Await(); - - for (size_t i = 0; i < EnqueuesPerThread; ++i) { - Stack.Enqueue(i); - } - } - - void DequeuerAll() { - StartLatch.CountDown(); - StartLatch.Await(); - + } + }; + + template <bool SingleConsumer> + struct TDequeueAllTester { + size_t EnqueueThreads; + size_t DequeueThreads; + + size_t EnqueuesPerThread; + TAtomic LeftToDequeue; + + TCountDownLatch StartLatch; + TLockFreeStack<int> Stack; + + TDequeueAllTester() + : EnqueueThreads(4) + , DequeueThreads(SingleConsumer ? 1 : 3) + , EnqueuesPerThread(100000) + , LeftToDequeue(EnqueueThreads * EnqueuesPerThread) + , StartLatch(EnqueueThreads + DequeueThreads) + { + } + + void Enqueuer() { + StartLatch.CountDown(); + StartLatch.Await(); + + for (size_t i = 0; i < EnqueuesPerThread; ++i) { + Stack.Enqueue(i); + } + } + + void DequeuerAll() { + StartLatch.CountDown(); + StartLatch.Await(); + TVector<int> temp; - while (AtomicGet(LeftToDequeue) > 0) { - size_t dequeued = 0; - for (size_t i = 0; i < 100; ++i) { - temp.clear(); - if (SingleConsumer) { - Stack.DequeueAllSingleConsumer(&temp); - } else { - Stack.DequeueAll(&temp); - } - dequeued += temp.size(); - } - AtomicAdd(LeftToDequeue, -dequeued); - } - } - - void Run() { + while (AtomicGet(LeftToDequeue) > 0) { + size_t dequeued = 0; + for (size_t i = 0; i < 100; ++i) { + temp.clear(); + if (SingleConsumer) { + Stack.DequeueAllSingleConsumer(&temp); + } else { + Stack.DequeueAll(&temp); + } + dequeued += temp.size(); + } + AtomicAdd(LeftToDequeue, -dequeued); + } + } + + void Run() { TVector<TSimpleSharedPtr<NThreading::TLegacyFuture<>>> futures; - - for (size_t i = 0; i < EnqueueThreads; ++i) { + + for (size_t i = 0; i < EnqueueThreads; ++i) { futures.push_back(new NThreading::TLegacyFuture<>(std::bind(&TDequeueAllTester<SingleConsumer>::Enqueuer, this))); - } - - for (size_t i = 0; i < DequeueThreads; ++i) { + } + + for (size_t i = 0; i < DequeueThreads; ++i) { futures.push_back(new NThreading::TLegacyFuture<>(std::bind(&TDequeueAllTester<SingleConsumer>::DequeuerAll, this))); - } - - // effectively join - futures.clear(); - - UNIT_ASSERT_VALUES_EQUAL(0, int(AtomicGet(LeftToDequeue))); - + } + + // effectively join + futures.clear(); + + UNIT_ASSERT_VALUES_EQUAL(0, int(AtomicGet(LeftToDequeue))); + TVector<int> left; - Stack.DequeueAll(&left); - UNIT_ASSERT(left.empty()); - } - }; - + Stack.DequeueAll(&left); + UNIT_ASSERT(left.empty()); + } + }; + Y_UNIT_TEST(TestDequeueAll) { - TDequeueAllTester<false>().Run(); - } - + TDequeueAllTester<false>().Run(); + } + Y_UNIT_TEST(TestDequeueAllSingleConsumer) { - TDequeueAllTester<true>().Run(); - } - + TDequeueAllTester<true>().Run(); + } + Y_UNIT_TEST(TestDequeueAllEmptyStack) { - TLockFreeStack<int> stack; - + TLockFreeStack<int> stack; + TVector<int> r; - stack.DequeueAll(&r); - - UNIT_ASSERT(r.empty()); - } - + stack.DequeueAll(&r); + + UNIT_ASSERT(r.empty()); + } + Y_UNIT_TEST(TestDequeueAllReturnsInReverseOrder) { - TLockFreeStack<int> stack; - - stack.Enqueue(17); - stack.Enqueue(19); - stack.Enqueue(23); - + TLockFreeStack<int> stack; + + stack.Enqueue(17); + stack.Enqueue(19); + stack.Enqueue(23); + TVector<int> r; - - stack.DequeueAll(&r); - - UNIT_ASSERT_VALUES_EQUAL(size_t(3), r.size()); - UNIT_ASSERT_VALUES_EQUAL(23, r.at(0)); - UNIT_ASSERT_VALUES_EQUAL(19, r.at(1)); - UNIT_ASSERT_VALUES_EQUAL(17, r.at(2)); - } - + + stack.DequeueAll(&r); + + UNIT_ASSERT_VALUES_EQUAL(size_t(3), r.size()); + UNIT_ASSERT_VALUES_EQUAL(23, r.at(0)); + UNIT_ASSERT_VALUES_EQUAL(19, r.at(1)); + UNIT_ASSERT_VALUES_EQUAL(17, r.at(2)); + } + Y_UNIT_TEST(TestEnqueueAll) { - TLockFreeStack<int> stack; - + TLockFreeStack<int> stack; + TVector<int> v; TVector<int> expected; - - stack.EnqueueAll(v); // add empty - - v.push_back(2); - v.push_back(3); - v.push_back(5); - expected.insert(expected.end(), v.begin(), v.end()); - stack.EnqueueAll(v); - - v.clear(); - - stack.EnqueueAll(v); // add empty - - v.push_back(7); - v.push_back(11); - v.push_back(13); - v.push_back(17); - expected.insert(expected.end(), v.begin(), v.end()); - stack.EnqueueAll(v); - + + stack.EnqueueAll(v); // add empty + + v.push_back(2); + v.push_back(3); + v.push_back(5); + expected.insert(expected.end(), v.begin(), v.end()); + stack.EnqueueAll(v); + + v.clear(); + + stack.EnqueueAll(v); // add empty + + v.push_back(7); + v.push_back(11); + v.push_back(13); + v.push_back(17); + expected.insert(expected.end(), v.begin(), v.end()); + stack.EnqueueAll(v); + TVector<int> actual; - stack.DequeueAll(&actual); - - UNIT_ASSERT_VALUES_EQUAL(expected.size(), actual.size()); - for (size_t i = 0; i < actual.size(); ++i) { - UNIT_ASSERT_VALUES_EQUAL(expected.at(expected.size() - i - 1), actual.at(i)); - } - } - + stack.DequeueAll(&actual); + + UNIT_ASSERT_VALUES_EQUAL(expected.size(), actual.size()); + for (size_t i = 0; i < actual.size(); ++i) { + UNIT_ASSERT_VALUES_EQUAL(expected.at(expected.size() - i - 1), actual.at(i)); + } + } + Y_UNIT_TEST(CleanInDestructor) { TSimpleSharedPtr<bool> p(new bool); - UNIT_ASSERT_VALUES_EQUAL(1u, p.RefCount()); - - { + UNIT_ASSERT_VALUES_EQUAL(1u, p.RefCount()); + + { TLockFreeStack<TSimpleSharedPtr<bool>> stack; - - stack.Enqueue(p); - stack.Enqueue(p); - - UNIT_ASSERT_VALUES_EQUAL(3u, p.RefCount()); - } - - UNIT_ASSERT_VALUES_EQUAL(1, p.RefCount()); - } + + stack.Enqueue(p); + stack.Enqueue(p); + + UNIT_ASSERT_VALUES_EQUAL(3u, p.RefCount()); + } + + UNIT_ASSERT_VALUES_EQUAL(1, p.RefCount()); + } Y_UNIT_TEST(NoCopyTest) { static unsigned copied = 0; @@ -343,4 +343,4 @@ Y_UNIT_TEST_SUITE(TLockFreeStackTests) { Y_UNIT_TEST(TesMultiThreadMove) { TMultiThreadTester<TMoveTest>().Run(); } -} +} diff --git a/util/thread/pool.cpp b/util/thread/pool.cpp index 05fad02e9b..25018ea95f 100644 --- a/util/thread/pool.cpp +++ b/util/thread/pool.cpp @@ -22,8 +22,8 @@ #include <util/system/condvar.h> #include <util/system/thread.h> -#include <util/datetime/base.h> - +#include <util/datetime/base.h> + #include "factory.h" #include "pool.h" diff --git a/util/thread/pool_ut.cpp b/util/thread/pool_ut.cpp index 893770d0c4..86f167f423 100644 --- a/util/thread/pool_ut.cpp +++ b/util/thread/pool_ut.cpp @@ -1,14 +1,14 @@ #include "pool.h" #include <library/cpp/testing/unittest/registar.h> - + #include <util/stream/output.h> #include <util/random/fast.h> #include <util/system/spinlock.h> #include <util/system/thread.h> #include <util/system/mutex.h> #include <util/system/condvar.h> - + struct TThreadPoolTest { TSpinLock Lock; long R = -1; @@ -65,7 +65,7 @@ struct TThreadPoolTest { for (size_t i = 0; i < cnt; ++i) { UNIT_ASSERT(queue->Add(new TTask(this, (long)rand.GenRand()))); - } + } queue->Stop(); @@ -124,7 +124,7 @@ Y_UNIT_TEST_SUITE(TThreadPoolTest) { UNIT_ASSERT_C(processed, "Not processed"); UNIT_ASSERT_C(destructed, "Not destructed"); } - + Y_UNIT_TEST(TestAddFunc) { TFailAddQueue queue; bool added = queue.AddFunc( diff --git a/util/thread/singleton.h b/util/thread/singleton.h index 4a1e05aea0..e9d43bcf20 100644 --- a/util/thread/singleton.h +++ b/util/thread/singleton.h @@ -1,20 +1,20 @@ -#pragma once - -#include <util/system/tls.h> -#include <util/generic/singleton.h> -#include <util/generic/ptr.h> - +#pragma once + +#include <util/system/tls.h> +#include <util/generic/singleton.h> +#include <util/generic/ptr.h> + namespace NPrivate { template <class T, size_t Priority> struct TFastThreadSingletonHelper { static inline T* GetSlow() { return SingletonWithPriority<NTls::TValue<T>, Priority>()->GetPtr(); } - + static inline T* Get() { #if defined(Y_HAVE_FAST_POD_TLS) Y_POD_STATIC_THREAD(T*) fast(nullptr); - + if (Y_UNLIKELY(!fast)) { fast = GetSlow(); } @@ -25,16 +25,16 @@ namespace NPrivate { #endif } }; -} - +} + template <class T, size_t Priority> static inline T* FastTlsSingletonWithPriority() { return ::NPrivate::TFastThreadSingletonHelper<T, Priority>::Get(); -} - -// NB: the singleton is the same for all modules that use -// FastTlsSingleton with the same type parameter. If unique singleton -// required, use unique types. +} + +// NB: the singleton is the same for all modules that use +// FastTlsSingleton with the same type parameter. If unique singleton +// required, use unique types. template <class T> static inline T* FastTlsSingleton() { return FastTlsSingletonWithPriority<T, TSingletonTraits<T>::Priority>(); diff --git a/util/thread/singleton_ut.cpp b/util/thread/singleton_ut.cpp index 164b1cc184..f02316e6ba 100644 --- a/util/thread/singleton_ut.cpp +++ b/util/thread/singleton_ut.cpp @@ -1,21 +1,21 @@ #include <library/cpp/testing/unittest/registar.h> - -#include "singleton.h" - -namespace { - struct TFoo { - int i; - TFoo() - : i(0) + +#include "singleton.h" + +namespace { + struct TFoo { + int i; + TFoo() + : i(0) { } - }; -} - + }; +} + Y_UNIT_TEST_SUITE(Tls) { Y_UNIT_TEST(FastThread) { - UNIT_ASSERT_VALUES_EQUAL(0, FastTlsSingleton<TFoo>()->i); - FastTlsSingleton<TFoo>()->i += 3; - UNIT_ASSERT_VALUES_EQUAL(3, FastTlsSingleton<TFoo>()->i); - } -} + UNIT_ASSERT_VALUES_EQUAL(0, FastTlsSingleton<TFoo>()->i); + FastTlsSingleton<TFoo>()->i += 3; + UNIT_ASSERT_VALUES_EQUAL(3, FastTlsSingleton<TFoo>()->i); + } +} |