feat add CountDownLatch
Some checks failed
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Successful in 1m1s
linux-mips64-gcc / linux-gcc-mips64el (push) Successful in 1m8s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Successful in 1m11s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Successful in 1m26s
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 1m16s
linux-x64-gcc / linux-gcc (push) Failing after 1m14s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Successful in 1m14s

This commit is contained in:
tqcq 2023-12-16 01:34:42 +08:00
parent fc358c0ea5
commit 4c022a51df
9 changed files with 105 additions and 4 deletions

View File

@ -19,6 +19,8 @@ target_sources(${PROJECT_NAME} PRIVATE
src/ulib/concorrency/mutex.h
src/ulib/concorrency/condition_variable.cpp
src/ulib/concorrency/condition_variable.h
src/ulib/concorrency/countdown_latch.cpp
src/ulib/concorrency/countdown_latch.h
src/ulib/concorrency/internal/mutex_impl.cpp
src/ulib/concorrency/internal/mutex_impl.h
src/ulib/concorrency/internal/condition_variable_impl.cpp

View File

@ -0,0 +1,28 @@
#include "countdown_latch.h"
#include <assert.h>
namespace ulib {
CountDownLatch::CountDownLatch(uint32_t count) : count_(count) {
assert(count > 0);
}
void
CountDownLatch::CountDown()
{
MutexGuard guard(count_lock_);
assert(count_ > 0);
--count_;
if (count_ == 0) { count_cond_.NotifyAll(); }
}
void
CountDownLatch::Await()
{
if (count_ == 0) { return; }
MutexGuard guard(count_lock_);
while (count_ > 0) { count_cond_.Wait(guard); }
assert(count_ == 0);
}
}// namespace ulib

View File

@ -0,0 +1,17 @@
#include "ulib/base/types.h"
#include "ulib/concorrency/mutex.h"
#include "ulib/concorrency/event.h"
namespace ulib {
class CountDownLatch {
public:
CountDownLatch(uint32_t count);
void CountDown();
void Await();
private:
ulib::int64_t count_;
Mutex count_lock_;
ConditionVariable count_cond_;
};
}// namespace ulib

View File

@ -2,10 +2,11 @@ set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(ulib_test
ulib/base/types_test.cpp
ulib/log/log_test.cpp
ulib/concorrency/mutex_test.cpp
ulib/concorrency/event_test.cpp
ulib/base/types_unittest.cpp
ulib/log/log_unittest.cpp
ulib/concorrency/mutex_unittest.cpp
ulib/concorrency/event_unittest.cpp
ulib/concorrency/countdown_latch_unittest.cpp
)
target_link_libraries(ulib_test PRIVATE
ulib

View File

@ -0,0 +1,53 @@
#include <gtest/gtest.h>
#include <ulib/concorrency/countdown_latch.h>
#include <pthread.h>
TEST(CountdownLatch, CountDownLatch)
{
ulib::CountDownLatch latch(1);
latch.CountDown();
latch.Await();
}
TEST(CountdownLatch, CountDownLatch2)
{
ulib::CountDownLatch latch(2);
latch.CountDown();
latch.CountDown();
latch.Await();
}
void *
CountDownThread(void *arg)
{
ulib::CountDownLatch *latch = (ulib::CountDownLatch *) arg;
latch->CountDown();
return NULL;
}
TEST(CountdownLatch, DoubleCountDownLatch)
{
ulib::CountDownLatch latch(2);
pthread_t thread;
pthread_create(&thread, NULL, CountDownThread, &latch);
latch.CountDown();
latch.Await();
pthread_join(thread, NULL);
}
TEST(CountdownLatch, MultiThreadCountDownLatch)
{
#define THREAD_NUM 10
ulib::CountDownLatch latch(THREAD_NUM);
pthread_t thread[THREAD_NUM];
for (int i = 0; i < THREAD_NUM; ++i) { pthread_create(&thread[i], NULL, CountDownThread, &latch); }
latch.Await();
for (int i = 0; i < THREAD_NUM; ++i) { pthread_join(thread[i], NULL); }
}
TEST(CoundownLatch, Assert)
{
ulib::CountDownLatch latch(1);
latch.CountDown();
EXPECT_DEATH(latch.CountDown(), "Assertion.*");
}