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})
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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