From 756eccc7e86486cf696cc0953f921d6287de6f70 Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Fri, 28 Aug 2020 14:18:56 +0300 Subject: [PATCH] Remove remainder of PIP and use library instruction --- ...{piblockingdequeue.h => blockingdequeue.h} | 37 ++++----------- include/{piexecutor.h => executor.h} | 45 ++++++------------- readme.md | 8 ++++ test/src/BlockingDequeueUnitTest.cpp | 18 ++++---- test/src/ExecutorIntegrationTest.cpp | 10 ++--- test/src/ExecutorUnitTest.cpp | 26 +++++------ 6 files changed, 57 insertions(+), 87 deletions(-) rename include/{piblockingdequeue.h => blockingdequeue.h} (87%) rename include/{piexecutor.h => executor.h} (79%) diff --git a/include/piblockingdequeue.h b/include/blockingdequeue.h similarity index 87% rename from include/piblockingdequeue.h rename to include/blockingdequeue.h index 6c24d35..f67d570 100644 --- a/include/piblockingdequeue.h +++ b/include/blockingdequeue.h @@ -1,24 +1,5 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef PIBLOCKINGDEQUEUE_H -#define PIBLOCKINGDEQUEUE_H +#ifndef BLOCKINGDEQUEUE_H +#define BLOCKINGDEQUEUE_H #include #include @@ -28,14 +9,14 @@ * wait for space to become available in the queue when storing an element. */ template class Queue_ = std::deque, typename ConditionVariable_ = std::condition_variable> -class PIBlockingDequeue { +class BlockingDequeue { public: typedef Queue_ QueueType; /** * @brief Constructor */ - explicit PIBlockingDequeue(size_t capacity = SIZE_MAX) + explicit BlockingDequeue(size_t capacity = SIZE_MAX) : cond_var_add(new ConditionVariable_()), cond_var_rem(new ConditionVariable_()), max_size(capacity) { } /** @@ -43,7 +24,7 @@ public: */ template::value, int>::type = 0> - explicit PIBlockingDequeue(const Iterable& other): PIBlockingDequeue() { + explicit BlockingDequeue(const Iterable& other): BlockingDequeue() { mutex.lock(); for (const T& t : other) data_queue.push_back(t); mutex.unlock(); @@ -52,7 +33,7 @@ public: /** * @brief Thread-safe copy constructor. Initialize queue with copy of other queue elements. */ - explicit PIBlockingDequeue(PIBlockingDequeue& other): PIBlockingDequeue() { + explicit BlockingDequeue(BlockingDequeue& other): BlockingDequeue() { other.mutex.lock(); mutex.lock(); max_size = other.max_size; @@ -61,7 +42,7 @@ public: other.mutex.unlock(); } - ~PIBlockingDequeue() { + ~BlockingDequeue() { delete cond_var_add; delete cond_var_rem; } @@ -244,7 +225,7 @@ public: /** * @brief Removes all available elements from this queue and adds them to other given queue. */ - size_t drainTo(PIBlockingDequeue& other, size_t maxCount = SIZE_MAX) { + size_t drainTo(BlockingDequeue& other, size_t maxCount = SIZE_MAX) { mutex.lock(); other.mutex.lock(); size_t count = maxCount > data_queue.size() ? data_queue.size() : maxCount; @@ -269,4 +250,4 @@ protected: }; -#endif // PIBLOCKINGDEQUEUE_H +#endif // BLOCKINGDEQUEUE_H diff --git a/include/piexecutor.h b/include/executor.h similarity index 79% rename from include/piexecutor.h rename to include/executor.h index 764d275..3b87aa5 100644 --- a/include/piexecutor.h +++ b/include/executor.h @@ -1,26 +1,7 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko +#ifndef EXECUTOR_H +#define EXECUTOR_H - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef PIEXECUTOR_H -#define PIEXECUTOR_H - -#include "piblockingdequeue.h" +#include "blockingdequeue.h" #include #include @@ -62,8 +43,8 @@ public: FunctionWrapper& operator=(const FunctionWrapper&) = delete; }; -template > -class PIThreadPoolExecutorTemplate { +template > +class ThreadPoolExecutorTemplate { protected: enum thread_command { run, @@ -72,9 +53,9 @@ protected: }; public: - explicit PIThreadPoolExecutorTemplate(size_t corePoolSize = 1) : thread_command_(thread_command::run) { makePool(corePoolSize); } + explicit ThreadPoolExecutorTemplate(size_t corePoolSize = 1) : thread_command_(thread_command::run) { makePool(corePoolSize); } - virtual ~PIThreadPoolExecutorTemplate() { + virtual ~ThreadPoolExecutorTemplate() { shutdownNow(); awaitTermination(1000); while (threadPool.size() > 0) { @@ -139,7 +120,7 @@ protected: std::vector threadPool; template - PIThreadPoolExecutorTemplate(size_t corePoolSize, Function&& onBeforeStart) : thread_command_(thread_command::run) { + ThreadPoolExecutorTemplate(size_t corePoolSize, Function&& onBeforeStart) : thread_command_(thread_command::run) { makePool(corePoolSize, std::forward(onBeforeStart)); } @@ -159,7 +140,7 @@ protected: } }; -typedef PIThreadPoolExecutorTemplate<> PIThreadPoolExecutor; +typedef ThreadPoolExecutorTemplate<> ThreadPoolExecutor; #ifdef DOXYGEN /** @@ -167,11 +148,11 @@ typedef PIThreadPoolExecutorTemplate<> PIThreadPoolExecutor; * numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and * managing the resources, including threads, consumed when executing a collection of tasks. */ -class PIThreadPoolExecutor { +class ThreadPoolExecutor { public: - explicit PIThreadPoolExecutor(size_t corePoolSize); + explicit ThreadPoolExecutor(size_t corePoolSize); - virtual ~PIThreadPoolExecutor(); + virtual ~ThreadPoolExecutor(); /** * @brief Submits a Runnable task for execution and returns a Future representing that task. The Future's get method @@ -211,4 +192,4 @@ public: }; #endif //DOXYGEN -#endif //PIEXECUTOR_H +#endif //EXECUTOR_H diff --git a/readme.md b/readme.md index d1530da..59b9857 100644 --- a/readme.md +++ b/readme.md @@ -33,6 +33,14 @@ cmake -DCMAKE_BUILD_TYPE=Release .. cmake --build . --target install ``` +4 Use in your project cmake files: + +```cmake +find_package(Concurrent REQUIRED) +add_executable(your_app ${YOUR_SOURCES}) +target_link_libraries(your_app concurrent) +``` + ## Build tests 1 Clone GTest: diff --git a/test/src/BlockingDequeueUnitTest.cpp b/test/src/BlockingDequeueUnitTest.cpp index 6a91d25..841e65e 100644 --- a/test/src/BlockingDequeueUnitTest.cpp +++ b/test/src/BlockingDequeueUnitTest.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" #include "testutil.h" -#include "piblockingdequeue.h" +#include "blockingdequeue.h" using ::testing::_; using ::testing::Return; @@ -77,15 +77,15 @@ public: template class MockDeque: public NiceMock> {}; -class PIBlockingDequeuePrepare: public PIBlockingDequeue> { +class BlockingDequeuePrepare: public BlockingDequeue> { public: - typedef PIBlockingDequeue> SuperClass; + typedef BlockingDequeue> SuperClass; - explicit PIBlockingDequeuePrepare(size_t capacity = SIZE_MAX): SuperClass(capacity) { } + explicit BlockingDequeuePrepare(size_t capacity = SIZE_MAX): SuperClass(capacity) { } template::value, int>::type = 0> - explicit PIBlockingDequeuePrepare(const Iterable& other): SuperClass(other) { } + explicit BlockingDequeuePrepare(const Iterable& other): SuperClass(other) { } MockConditionVar* getCondVarAdd() { return this->cond_var_add; } MockConditionVar* getCondVarRem() { return this->cond_var_rem; } @@ -97,7 +97,7 @@ class BlockingDequeueUnitTest: public ::testing::Test { public: int timeout = 100; size_t capacity; - PIBlockingDequeuePrepare dequeue; + BlockingDequeuePrepare dequeue; QueueElement element; BlockingDequeueUnitTest(): capacity(1), dequeue(capacity), element(11) {} @@ -108,12 +108,12 @@ public: }; TEST_F(BlockingDequeueUnitTest, construct_default_is_max_size_eq_size_max) { - PIBlockingDequeuePrepare dequeue; + BlockingDequeuePrepare dequeue; ASSERT_EQ(dequeue.getMaxSize(), SIZE_MAX); } TEST_F(BlockingDequeueUnitTest, construct_from_constant_is_max_size_eq_capacity) { - PIBlockingDequeuePrepare dequeue(2); + BlockingDequeuePrepare dequeue(2); ASSERT_EQ(dequeue.getMaxSize(), 2); } @@ -125,7 +125,7 @@ TEST_F(BlockingDequeueUnitTest, construct_from_iterable) { std::vector iterable; iterable.emplace_back(11); iterable.emplace_back(22); - PIBlockingDequeuePrepare dequeue(iterable); + BlockingDequeuePrepare dequeue(iterable); } void BlockingDequeueUnitTest::put_is_wait_predicate(bool isCapacityReach) { diff --git a/test/src/ExecutorIntegrationTest.cpp b/test/src/ExecutorIntegrationTest.cpp index 8a1b783..0108078 100644 --- a/test/src/ExecutorIntegrationTest.cpp +++ b/test/src/ExecutorIntegrationTest.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" #include "testutil.h" -#include "piexecutor.h" +#include "executor.h" using namespace std; using namespace chrono; @@ -8,7 +8,7 @@ using namespace chrono; TEST(ExcutorIntegrationTest, execute_is_runnable_invoke) { std::mutex m; int invokedRunnables = 0; - PIThreadPoolExecutor executorService(1); + ThreadPoolExecutor executorService(1); executorService.execute([&]() { m.lock(); invokedRunnables++; @@ -22,7 +22,7 @@ TEST(ExcutorIntegrationTest, execute_is_runnable_invoke) { TEST(ExcutorIntegrationTest, execute_is_not_execute_after_shutdown) { volatile bool isRunnableInvoke = false; - PIThreadPoolExecutor executorService(1); + ThreadPoolExecutor executorService(1); executorService.shutdown(); executorService.execute([&]() { isRunnableInvoke = true; @@ -33,7 +33,7 @@ TEST(ExcutorIntegrationTest, execute_is_not_execute_after_shutdown) { TEST(ExcutorIntegrationTest, execute_is_execute_before_shutdown) { volatile bool isRunnableInvoke = false; - PIThreadPoolExecutor executorService(1); + ThreadPoolExecutor executorService(1); executorService.execute([&]() { this_thread::sleep_for(milliseconds(WAIT_THREAD_TIME_MS)); isRunnableInvoke = true; @@ -45,7 +45,7 @@ TEST(ExcutorIntegrationTest, execute_is_execute_before_shutdown) { // FIXME TEST(DISABLED_ExcutorIntegrationTest, execute_is_awaitTermination_wait) { - PIThreadPoolExecutor executorService(1); + ThreadPoolExecutor executorService(1); executorService.execute([&]() { this_thread::sleep_for(milliseconds(2 * WAIT_THREAD_TIME_MS)); }); diff --git a/test/src/ExecutorUnitTest.cpp b/test/src/ExecutorUnitTest.cpp index dd0a79e..1ec21f1 100644 --- a/test/src/ExecutorUnitTest.cpp +++ b/test/src/ExecutorUnitTest.cpp @@ -3,7 +3,7 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" #include "testutil.h" -#include "piexecutor.h" +#include "executor.h" using ::testing::_; using ::testing::SetArgReferee; @@ -40,7 +40,7 @@ public: MOCK_METHOD0(join, void()); }; -class MockDeque : public PIBlockingDequeue { +class MockDeque : public BlockingDequeue { public: MOCK_METHOD1(offer, bool(const FunctionWrapper&)); MOCK_METHOD0(take, FunctionWrapper()); @@ -49,14 +49,14 @@ public: MOCK_METHOD0(remainingCapacity, size_t()); }; -typedef PIThreadPoolExecutorTemplate, MockDeque> PIThreadPoolExecutorMoc_t; +typedef ThreadPoolExecutorTemplate, MockDeque> ThreadPoolExecutorMoc_t; -class PIThreadPoolExecutorMoc : public PIThreadPoolExecutorMoc_t { +class ThreadPoolExecutorMoc : public ThreadPoolExecutorMoc_t { public: - explicit PIThreadPoolExecutorMoc(size_t corePoolSize) : PIThreadPoolExecutorMoc_t(corePoolSize) { } + explicit ThreadPoolExecutorMoc(size_t corePoolSize) : ThreadPoolExecutorMoc_t(corePoolSize) { } template - explicit PIThreadPoolExecutorMoc(size_t corePoolSize, Function onBeforeStart) : PIThreadPoolExecutorMoc_t(corePoolSize, onBeforeStart) { } + explicit ThreadPoolExecutorMoc(size_t corePoolSize, Function onBeforeStart) : ThreadPoolExecutorMoc_t(corePoolSize, onBeforeStart) { } std::vector*>* getThreadPool() { return &threadPool; } bool isShutdown() { return thread_command_ != thread_command::run; } @@ -64,18 +64,18 @@ public: }; TEST(ExecutorUnitTest, is_corePool_created) { - PIThreadPoolExecutorMoc executor(THREAD_COUNT); + ThreadPoolExecutorMoc executor(THREAD_COUNT); ASSERT_EQ(THREAD_COUNT, executor.getThreadPool()->size()); } TEST(ExecutorUnitTest, is_corePool_started) { - PIThreadPoolExecutorMoc executor(THREAD_COUNT); + ThreadPoolExecutorMoc executor(THREAD_COUNT); for (auto* thread : *executor.getThreadPool()) ASSERT_TRUE(thread->is_executed); } TEST(ExecutorUnitTest, submit_is_added_to_taskQueue) { VoidFunc voidFunc = [](){}; - PIThreadPoolExecutorMoc executor(THREAD_COUNT); + ThreadPoolExecutorMoc executor(THREAD_COUNT); // TODO add check of offered EXPECT_CALL(*executor.getTaskQueue(), offer) .WillOnce(Return(true)); @@ -84,7 +84,7 @@ TEST(ExecutorUnitTest, submit_is_added_to_taskQueue) { TEST(ExecutorUnitTest, submit_is_return_valid_future) { VoidFunc voidFunc = [](){}; - PIThreadPoolExecutorMoc executor(THREAD_COUNT); + ThreadPoolExecutorMoc executor(THREAD_COUNT); // TODO add check of offered EXPECT_CALL(*executor.getTaskQueue(), offer) .WillOnce(Return(true)); @@ -94,7 +94,7 @@ TEST(ExecutorUnitTest, submit_is_return_valid_future) { TEST(ExecutorUnitTest, execute_is_added_to_taskQueue) { VoidFunc voidFunc = [](){}; - PIThreadPoolExecutorMoc executor(THREAD_COUNT); + ThreadPoolExecutorMoc executor(THREAD_COUNT); // TODO add check of offered EXPECT_CALL(*executor.getTaskQueue(), offer) .WillOnce(Return(true)); @@ -104,7 +104,7 @@ TEST(ExecutorUnitTest, execute_is_added_to_taskQueue) { // TODO fix TEST(DISABLED_ExecutorUnitTest, is_corePool_execute_queue_elements) { bool is_executed = false; - PIThreadPoolExecutorMoc executor(1); + ThreadPoolExecutorMoc executor(1); EXPECT_EQ(executor.getThreadPool()->size(), 1); EXPECT_CALL(*executor.getTaskQueue(), poll(Ge(0))) .WillOnce([&is_executed](int){ @@ -117,7 +117,7 @@ TEST(DISABLED_ExecutorUnitTest, is_corePool_execute_queue_elements) { // FIXME TEST(DISABLED_ExecutorUnitTest, shutdown_is_stop_threads) { // Exclude stop calls when executor deleting - auto* executor = new PIThreadPoolExecutorMoc(THREAD_COUNT, [](MockThread* thread){ + auto* executor = new ThreadPoolExecutorMoc(THREAD_COUNT, [](MockThread* thread){ testing::Mock::AllowLeak(thread); EXPECT_CALL(*thread, join()) .WillOnce(Return());