Import thread-pool from klay
authorSangwan Kwon <sangwan.kwon@samsung.com>
Wed, 15 Jan 2020 05:29:37 +0000 (14:29 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Fri, 17 Jan 2020 06:24:01 +0000 (15:24 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
src/vist/common/CMakeLists.txt
src/vist/common/tests/thread-pool.cpp [new file with mode: 0644]
src/vist/common/thread-pool.cpp [new file with mode: 0644]
src/vist/thread-pool.hpp [new file with mode: 0644]

index 883dfc3..ec46edd 100644 (file)
@@ -14,7 +14,8 @@
 
 ADD_VIST_COMMON_LIBRARY(vist_common archive.cpp
                                                                        common.cpp
-                                                                       stringfy.cpp)
+                                                                       stringfy.cpp
+                                                                       thread-pool.cpp)
 
 FILE(GLOB COMMON_TESTS "tests/*.cpp")
 ADD_VIST_TEST(${COMMON_TESTS})
diff --git a/src/vist/common/tests/thread-pool.cpp b/src/vist/common/tests/thread-pool.cpp
new file mode 100644 (file)
index 0000000..0061c0d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include <vist/thread-pool.hpp>
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+
+using namespace vist;
+
+TEST(ThreadPoolTests, submit)
+{
+       int count = 0;
+
+       ThreadPool worker(5);
+       auto task = [&count]() {
+               count++;
+       };
+
+       std::size_t repeat = 10;
+       while (repeat--)
+               worker.submit(task);
+
+       std::this_thread::sleep_for(std::chrono::seconds(2));
+       EXPECT_TRUE(count > 5);
+}
diff --git a/src/vist/common/thread-pool.cpp b/src/vist/common/thread-pool.cpp
new file mode 100644 (file)
index 0000000..0d8bfdc
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <vist/thread-pool.hpp>
+
+#define __BEGIN_CRITICAL__  { std::unique_lock<std::mutex> lock(this->queueMutex);
+#define __END_CRITICAL__    }
+
+namespace vist {
+
+ThreadPool::ThreadPool(std::size_t threads)
+{
+       for (std::size_t i = 0; i < threads; i++) {
+          workers.emplace_back([this] {
+                       while (true) {
+                               std::function<void()> task;
+
+                               __BEGIN_CRITICAL__
+                               condition.wait(lock, [this]{ return stop || !tasks.empty();});
+                               if (stop && tasks.empty()) {
+                                       return;
+                               }
+
+                               task = std::move(tasks.front());
+                               tasks.pop_front();
+                               __END_CRITICAL__
+
+                               task();
+                       }
+               });
+       }
+}
+
+ThreadPool::~ThreadPool()
+{
+       __BEGIN_CRITICAL__
+       stop = true;
+       __END_CRITICAL__
+
+       condition.notify_all();
+
+       for (std::thread &worker: workers) {
+               if (worker.joinable()) {
+                       worker.join();
+               }
+       }
+}
+
+void ThreadPool::submit(std::function<void()>&& task)
+{
+       __BEGIN_CRITICAL__
+       if (!stop) {
+               tasks.push_back(std::forward<std::function<void()>>(task));
+       }
+       __END_CRITICAL__
+
+       condition.notify_one();
+}
+
+} // namespace vist
diff --git a/src/vist/thread-pool.hpp b/src/vist/thread-pool.hpp
new file mode 100644 (file)
index 0000000..0398bad
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (c) 2015-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <condition_variable>
+#include <deque>
+#include <functional>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+namespace vist {
+
+class ThreadPool final {
+public:
+       ThreadPool(std::size_t threads);
+       ~ThreadPool();
+
+       void submit(std::function<void()>&& task);
+
+private:
+       std::vector<std::thread> workers;
+       std::deque<std::function<void()>> tasks;
+
+       std::mutex queueMutex;
+       std::condition_variable condition;
+       bool stop = false;
+};
+
+} // namespace vist