From 866b19ee051dc14789b511dcb1108f12b0bcb311 Mon Sep 17 00:00:00 2001 From: Chris Blume Date: Mon, 10 Nov 2025 09:41:05 +0900 Subject: [PATCH 1/2] Add threadpool --- Code/max/Algorithms/TaskThread.cpp | 29 ++++++++++ Code/max/Algorithms/TaskThread.hpp | 30 ++++++++++ Code/max/Algorithms/ThreadPool.cpp | 57 +++++++++++++++++++ Code/max/Algorithms/ThreadPool.hpp | 28 +++++++++ Projects/VisualStudio/max/max.vcxproj | 4 ++ Projects/VisualStudio/max/max.vcxproj.filters | 12 ++++ 6 files changed, 160 insertions(+) create mode 100644 Code/max/Algorithms/TaskThread.cpp create mode 100644 Code/max/Algorithms/TaskThread.hpp create mode 100644 Code/max/Algorithms/ThreadPool.cpp create mode 100644 Code/max/Algorithms/ThreadPool.hpp diff --git a/Code/max/Algorithms/TaskThread.cpp b/Code/max/Algorithms/TaskThread.cpp new file mode 100644 index 0000000..455b6af --- /dev/null +++ b/Code/max/Algorithms/TaskThread.cpp @@ -0,0 +1,29 @@ +// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "TaskThread.hpp" + +#include + +namespace FileReadSpeedTest { + + TaskThread::TaskThread(std::unique_ptr task_queue, std::thread thread) noexcept + : task_queue_(std::move(task_queue)) + , thread_(std::move(thread)) + {} + + std::optional CreateTaskThread() noexcept { + auto create_task_queue_result = max::CreateTaskQueue(); + if (!create_task_queue_result) { + return std::nullopt; + } + std::unique_ptr task_queue = std::move(*create_task_queue_result); + + auto thread = std::thread(max::TaskRunnerLoop, task_queue.get()); + // TODO: Attempt to lock that thread to the preferred type of core. + + return TaskThread(std::move(task_queue), std::move(thread)); + } + +} // namespace FileReadSpeedTest \ No newline at end of file diff --git a/Code/max/Algorithms/TaskThread.hpp b/Code/max/Algorithms/TaskThread.hpp new file mode 100644 index 0000000..3d30991 --- /dev/null +++ b/Code/max/Algorithms/TaskThread.hpp @@ -0,0 +1,30 @@ +// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FILEREADSPEEDTEST_TASKTHREAD_HPP +#define FILEREADSPEEDTEST_TASKTHREAD_HPP + +#include +#include +#include + +#include + +namespace FileReadSpeedTest { + + class TaskThread { + public: + + explicit TaskThread(std::unique_ptr task_queue, std::thread thread) noexcept; + + std::unique_ptr task_queue_; + std::thread thread_; + + }; + + std::optional CreateTaskThread() noexcept; + +} // namespace FileReadSpeedTest + +#endif // #ifndef FILEREADSPEEDTEST_TASKTHREAD_HPP \ No newline at end of file diff --git a/Code/max/Algorithms/ThreadPool.cpp b/Code/max/Algorithms/ThreadPool.cpp new file mode 100644 index 0000000..9ad62eb --- /dev/null +++ b/Code/max/Algorithms/ThreadPool.cpp @@ -0,0 +1,57 @@ +// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ThreadPool.hpp" + +#include + +#include "GetProcessorCoreInformation.hpp" + +namespace FileReadSpeedTest { + + ThreadPool::ThreadPool(std::vector task_threads) noexcept + : task_threads_(std::move(task_threads)) + {} + + std::optional CreateThreadPool() noexcept { + // Get processor information. + auto processor_core_information = FileReadSpeedTest::GetProcessorCoreInformation(); + if (!processor_core_information.has_value()) { + std::cerr << "Error: Could not find processor information." << std::endl; + return std::nullopt; + } + + + // Determine how many threads to create based on the different core types. + // Each program will want to do this differently--some processing is heavy, some light... + int16_t max_efficiency = -1; + uint16_t max_efficiency_core_count = 0; + for (auto& core_information : *processor_core_information) { + std::cout << "CPU cores: " << core_information.count_ << " @ performance class: " << core_information.efficiency_class_; + if (core_information.has_hyperthreading_ != 0) { + std::cout << " (with hyperthreading)"; + } + if (core_information.efficiency_class_ > max_efficiency) { + max_efficiency = core_information.efficiency_class_; + max_efficiency_core_count = core_information.count_; + } + std::cout << std::endl; + } + + + // Create task threads. + std::vector task_threads; + + for (size_t i = 0; i < max_efficiency_core_count; i++) { + auto task_thread = CreateTaskThread(); + if (!task_thread.has_value()) { + return std::nullopt; + } + task_threads.emplace_back(std::move(*task_thread)); + } + + return ThreadPool(std::move(task_threads)); + } + +} // namespace FileReadSpeedTest \ No newline at end of file diff --git a/Code/max/Algorithms/ThreadPool.hpp b/Code/max/Algorithms/ThreadPool.hpp new file mode 100644 index 0000000..8805964 --- /dev/null +++ b/Code/max/Algorithms/ThreadPool.hpp @@ -0,0 +1,28 @@ +// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FILEREADSPEEDTEST_THREADPOOL_HPP +#define FILEREADSPEEDTEST_THREADPOOL_HPP + +#include +#include + +#include "TaskThread.hpp" + +namespace FileReadSpeedTest { + + class ThreadPool { + public: + + explicit ThreadPool(std::vector task_threads) noexcept; + + std::vector task_threads_; + + }; + + std::optional CreateThreadPool() noexcept; + +} // namespace FileReadSpeedTest + +#endif // #ifndef FILEREADSPEEDTEST_THREADPOOL_HPP \ No newline at end of file diff --git a/Projects/VisualStudio/max/max.vcxproj b/Projects/VisualStudio/max/max.vcxproj index 18e336f..c744d57 100644 --- a/Projects/VisualStudio/max/max.vcxproj +++ b/Projects/VisualStudio/max/max.vcxproj @@ -83,6 +83,8 @@ true true + + @@ -222,6 +224,8 @@ true true + + true true diff --git a/Projects/VisualStudio/max/max.vcxproj.filters b/Projects/VisualStudio/max/max.vcxproj.filters index eaa76c9..eb3bdc0 100644 --- a/Projects/VisualStudio/max/max.vcxproj.filters +++ b/Projects/VisualStudio/max/max.vcxproj.filters @@ -393,6 +393,12 @@ Code\max\Compiling + + Code\max\Algorithms + + + Code\max\Algorithms + @@ -479,6 +485,12 @@ Code\max\Containers + + Code\max\Algorithms + + + Code\max\Algorithms + From 1747cdb546a6b317cc9241fa6253ceb52c436981 Mon Sep 17 00:00:00 2001 From: Chris Blume Date: Mon, 10 Nov 2025 10:08:49 +0900 Subject: [PATCH 2/2] Add missing files --- Code/max/Algorithms/TaskThread.cpp | 29 ---- Code/max/Algorithms/TaskThread.hpp | 30 ----- Code/max/Algorithms/ThreadPool.cpp | 57 -------- Code/max/Algorithms/ThreadPool.hpp | 28 ---- .../Compiling/Configuration/Compiler/VC.hpp | 2 +- Code/max/Hardware/CPU/Task.cpp | 15 +++ Code/max/Hardware/CPU/Task.hpp | 25 ++++ Code/max/Hardware/CPU/TaskQueue.cpp | 124 ++++++++++++++++++ Code/max/Hardware/CPU/TaskQueue.hpp | 89 +++++++++++++ Code/max/Hardware/CPU/TaskThread.cpp | 33 +++++ Code/max/Hardware/CPU/TaskThread.hpp | 34 +++++ Projects/VisualStudio/max/max.vcxproj | 10 +- Projects/VisualStudio/max/max.vcxproj.filters | 22 ++-- 13 files changed, 341 insertions(+), 157 deletions(-) delete mode 100644 Code/max/Algorithms/TaskThread.cpp delete mode 100644 Code/max/Algorithms/TaskThread.hpp delete mode 100644 Code/max/Algorithms/ThreadPool.cpp delete mode 100644 Code/max/Algorithms/ThreadPool.hpp create mode 100644 Code/max/Hardware/CPU/Task.cpp create mode 100644 Code/max/Hardware/CPU/Task.hpp create mode 100644 Code/max/Hardware/CPU/TaskQueue.cpp create mode 100644 Code/max/Hardware/CPU/TaskQueue.hpp create mode 100644 Code/max/Hardware/CPU/TaskThread.cpp create mode 100644 Code/max/Hardware/CPU/TaskThread.hpp diff --git a/Code/max/Algorithms/TaskThread.cpp b/Code/max/Algorithms/TaskThread.cpp deleted file mode 100644 index 455b6af..0000000 --- a/Code/max/Algorithms/TaskThread.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "TaskThread.hpp" - -#include - -namespace FileReadSpeedTest { - - TaskThread::TaskThread(std::unique_ptr task_queue, std::thread thread) noexcept - : task_queue_(std::move(task_queue)) - , thread_(std::move(thread)) - {} - - std::optional CreateTaskThread() noexcept { - auto create_task_queue_result = max::CreateTaskQueue(); - if (!create_task_queue_result) { - return std::nullopt; - } - std::unique_ptr task_queue = std::move(*create_task_queue_result); - - auto thread = std::thread(max::TaskRunnerLoop, task_queue.get()); - // TODO: Attempt to lock that thread to the preferred type of core. - - return TaskThread(std::move(task_queue), std::move(thread)); - } - -} // namespace FileReadSpeedTest \ No newline at end of file diff --git a/Code/max/Algorithms/TaskThread.hpp b/Code/max/Algorithms/TaskThread.hpp deleted file mode 100644 index 3d30991..0000000 --- a/Code/max/Algorithms/TaskThread.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FILEREADSPEEDTEST_TASKTHREAD_HPP -#define FILEREADSPEEDTEST_TASKTHREAD_HPP - -#include -#include -#include - -#include - -namespace FileReadSpeedTest { - - class TaskThread { - public: - - explicit TaskThread(std::unique_ptr task_queue, std::thread thread) noexcept; - - std::unique_ptr task_queue_; - std::thread thread_; - - }; - - std::optional CreateTaskThread() noexcept; - -} // namespace FileReadSpeedTest - -#endif // #ifndef FILEREADSPEEDTEST_TASKTHREAD_HPP \ No newline at end of file diff --git a/Code/max/Algorithms/ThreadPool.cpp b/Code/max/Algorithms/ThreadPool.cpp deleted file mode 100644 index 9ad62eb..0000000 --- a/Code/max/Algorithms/ThreadPool.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ThreadPool.hpp" - -#include - -#include "GetProcessorCoreInformation.hpp" - -namespace FileReadSpeedTest { - - ThreadPool::ThreadPool(std::vector task_threads) noexcept - : task_threads_(std::move(task_threads)) - {} - - std::optional CreateThreadPool() noexcept { - // Get processor information. - auto processor_core_information = FileReadSpeedTest::GetProcessorCoreInformation(); - if (!processor_core_information.has_value()) { - std::cerr << "Error: Could not find processor information." << std::endl; - return std::nullopt; - } - - - // Determine how many threads to create based on the different core types. - // Each program will want to do this differently--some processing is heavy, some light... - int16_t max_efficiency = -1; - uint16_t max_efficiency_core_count = 0; - for (auto& core_information : *processor_core_information) { - std::cout << "CPU cores: " << core_information.count_ << " @ performance class: " << core_information.efficiency_class_; - if (core_information.has_hyperthreading_ != 0) { - std::cout << " (with hyperthreading)"; - } - if (core_information.efficiency_class_ > max_efficiency) { - max_efficiency = core_information.efficiency_class_; - max_efficiency_core_count = core_information.count_; - } - std::cout << std::endl; - } - - - // Create task threads. - std::vector task_threads; - - for (size_t i = 0; i < max_efficiency_core_count; i++) { - auto task_thread = CreateTaskThread(); - if (!task_thread.has_value()) { - return std::nullopt; - } - task_threads.emplace_back(std::move(*task_thread)); - } - - return ThreadPool(std::move(task_threads)); - } - -} // namespace FileReadSpeedTest \ No newline at end of file diff --git a/Code/max/Algorithms/ThreadPool.hpp b/Code/max/Algorithms/ThreadPool.hpp deleted file mode 100644 index 8805964..0000000 --- a/Code/max/Algorithms/ThreadPool.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FILEREADSPEEDTEST_THREADPOOL_HPP -#define FILEREADSPEEDTEST_THREADPOOL_HPP - -#include -#include - -#include "TaskThread.hpp" - -namespace FileReadSpeedTest { - - class ThreadPool { - public: - - explicit ThreadPool(std::vector task_threads) noexcept; - - std::vector task_threads_; - - }; - - std::optional CreateThreadPool() noexcept; - -} // namespace FileReadSpeedTest - -#endif // #ifndef FILEREADSPEEDTEST_THREADPOOL_HPP \ No newline at end of file diff --git a/Code/max/Compiling/Configuration/Compiler/VC.hpp b/Code/max/Compiling/Configuration/Compiler/VC.hpp index 13e2931..739cb09 100644 --- a/Code/max/Compiling/Configuration/Compiler/VC.hpp +++ b/Code/max/Compiling/Configuration/Compiler/VC.hpp @@ -241,7 +241,7 @@ #if _MSC_FULL_VER >= 190024210 // MSVC++ 14.3 (Visual Studio 2015 Update 3) // Visual Studio 2015 Update 3 introduced the _MSVC_LANG pre-defined macro #if _MSVC_LANG > 202004L - #MAX_COMPILER_MESSAGE( "Compiling with a newer version of C++ than max recognizes. Using last known version."); + MAX_COMPILER_MESSAGE( "Compiling with a newer version of C++ than max recognizes. Using last known version."); #elif _MSVC_LANG >= 202004L #define MAX_CPP_20 #elif _MSVC_LANG >= 201705L diff --git a/Code/max/Hardware/CPU/Task.cpp b/Code/max/Hardware/CPU/Task.cpp new file mode 100644 index 0000000..2b5cb75 --- /dev/null +++ b/Code/max/Hardware/CPU/Task.cpp @@ -0,0 +1,15 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +namespace max { +namespace Hardware { +namespace CPU { + + Task::~Task() noexcept = default; + +} // namespace CPU +} // namespace Hardware +} // namespace max \ No newline at end of file diff --git a/Code/max/Hardware/CPU/Task.hpp b/Code/max/Hardware/CPU/Task.hpp new file mode 100644 index 0000000..5f7a81d --- /dev/null +++ b/Code/max/Hardware/CPU/Task.hpp @@ -0,0 +1,25 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_HARDWARE_CPU_TASK_HPP +#define MAX_HARDWARE_CPU_TASK_HPP + +namespace max { +namespace Hardware { +namespace CPU { + + class Task { + public: + + virtual ~Task() noexcept; + + virtual void Run() noexcept = 0; + + }; + +} // namespace CPU +} // namespace Hardware +} // namespace max + +#endif // #ifndef MAX_HARDWARE_CPU_TASK_HPP \ No newline at end of file diff --git a/Code/max/Hardware/CPU/TaskQueue.cpp b/Code/max/Hardware/CPU/TaskQueue.cpp new file mode 100644 index 0000000..b55a282 --- /dev/null +++ b/Code/max/Hardware/CPU/TaskQueue.cpp @@ -0,0 +1,124 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include + +namespace max { +namespace Hardware { +namespace CPU { + + TaskQueue::TaskQueue(HANDLE wake_event) noexcept + : task_queue_mutex_() + , task_queue_() + , wake_event_(std::move(wake_event)) + , shutting_down_(false) + { + } + + TaskQueue::~TaskQueue() noexcept { + BOOL result = CloseHandle(wake_event_); + if (result == 0) { + // GetLastError() + } + } + + TaskQueue::AddTaskError TaskQueue::AddTask(std::unique_ptr task) noexcept { + if (shutting_down_) { + return AddTaskError::ShuttingDown; + } + + { + std::lock_guard task_queue_guard(task_queue_mutex_); + task_queue_.push(std::move(task)); + BOOL result = SetEvent(wake_event_); + if (result == 0) { + // GetLastError() + return AddTaskError::CouldNotSetEvent; + } + } + + return AddTaskError::Okay; + } + + std::unique_ptr TaskQueue::TryPopTask() noexcept { + std::lock_guard task_queue_guard(task_queue_mutex_); + + BOOL result = ResetEvent(wake_event_); + if (result == 0) { + // GetLastError + return nullptr; + } + + if (task_queue_.empty()) { + return nullptr; + } + + std::unique_ptr task = std::move(task_queue_.front()); + task_queue_.pop(); + return task; + } + + TaskQueue::WaitForEventError TaskQueue::WaitForEvent() noexcept { + auto result = WaitForMultipleObjects(1, &wake_event_, TRUE, INFINITE); + if (result != WAIT_OBJECT_0) { + return WaitForEventError::CouldNotWait; + } else { + result = ResetEvent(wake_event_); + if (result == 0) { + // GetLastError() + return WaitForEventError::CouldNotResetEvent; + } + } + + return WaitForEventError::Okay; + } + + TaskQueue::ShutdownError TaskQueue::Shutdown() noexcept { + std::lock_guard task_queue_guard(task_queue_mutex_); + + shutting_down_ = true; + BOOL result = SetEvent(wake_event_); + if (result == 0) { + // GetLastError() + return ShutdownError::CouldNotSetEvent; + } + + return ShutdownError::Okay; + } + + std::expected, CreateTaskQueueError> CreateTaskQueue() noexcept { + HANDLE wake_event = CreateEvent(NULL, TRUE, FALSE, TEXT("wake_event_")); + if (wake_event == NULL) { + // GetLastError() + return std::unexpected(CreateTaskQueueError::CouldNotCreate); + } + + return std::make_unique(std::move(wake_event)); + } + + void TaskRunnerLoop(TaskQueue* task_queue) noexcept { + bool continue_looping = true; + do { + auto task = task_queue->TryPopTask(); + if (task) { + task->Run(); + } + else { + if (task_queue->shutting_down_) { + continue_looping = false; + } + else { + task_queue->WaitForEvent(); + } + } + } while (continue_looping); + } + +} // namespace CPU +} // namespace Hardware +} // namespace max \ No newline at end of file diff --git a/Code/max/Hardware/CPU/TaskQueue.hpp b/Code/max/Hardware/CPU/TaskQueue.hpp new file mode 100644 index 0000000..223e435 --- /dev/null +++ b/Code/max/Hardware/CPU/TaskQueue.hpp @@ -0,0 +1,89 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_HARDWARE_CPU_TASKQUEUE_HPP +#define MAX_HARDWARE_CPU_TASKQUEUE_HPP + +#include +#include +#include +#include + + +// TODO: Handle other platforms +// TODO: This is only needed for the definition of HANDLE. Can we remove this somehow? +#ifndef WIN32_LEAN_AND_MEAN +#define WIn32_LEAN_AND_MEAN +#endif +#include + +#include + +namespace max { +namespace Hardware { +namespace CPU { + + // TaskQueue uses std::mutex, which cannot be copied nor moved. + // This restriction has a major impact on the design of the class. + // Instead of the usual std::expected CreateT() function, + // we use std::expected CreateT(). + // + // The additional unique_ptr means the actual object doesn't have to move. + + // Assume a 64-byte cache line size, and align to that. + // This is so a vector of TaskQueues does not cause false sharing between threads. + // TODO: VC warns that alignas(64) did indeed pad. And we treat warnings as errors. + class /*alignas(64)*/ TaskQueue { + public: + + // TODO: This is only public so std::make_unique can call it + TaskQueue(HANDLE wake_event) noexcept; + ~TaskQueue() noexcept; + + enum class AddTaskError { + Okay, + ShuttingDown, + CouldNotSetEvent, + }; + AddTaskError AddTask(std::unique_ptr task) noexcept; + + // TODO: Should this return a std::expected so it can provide error values? + std::unique_ptr TryPopTask() noexcept; + + enum class WaitForEventError { + Okay, + CouldNotWait, + CouldNotResetEvent, + }; + WaitForEventError WaitForEvent() noexcept; + + enum class ShutdownError { + Okay, + CouldNotSetEvent, + }; + ShutdownError Shutdown() noexcept; + + volatile bool shutting_down_; + + private: + + std::mutex task_queue_mutex_; + std::queue> task_queue_; + HANDLE wake_event_; + + }; + + enum class CreateTaskQueueError { + CouldNotCreate, + }; + // TODO: Possibly provide an allocator, to allocate the TaskQueue at the right location + std::expected, CreateTaskQueueError> CreateTaskQueue() noexcept; + + void TaskRunnerLoop(TaskQueue* task_queue) noexcept; + +} // namespace CPU +} // namespace Hardware +} // namespace max + +#endif // #ifndef MAX_HARDWARE_CPU_TASKQUEUE_HPP \ No newline at end of file diff --git a/Code/max/Hardware/CPU/TaskThread.cpp b/Code/max/Hardware/CPU/TaskThread.cpp new file mode 100644 index 0000000..ae31518 --- /dev/null +++ b/Code/max/Hardware/CPU/TaskThread.cpp @@ -0,0 +1,33 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +namespace max { +namespace Hardware { +namespace CPU { + + TaskThread::TaskThread(std::unique_ptr task_queue, std::thread thread) noexcept + : task_queue_(std::move(task_queue)) + , thread_(std::move(thread)) + {} + + std::optional CreateTaskThread() noexcept { + auto create_task_queue_result = max::Hardware::CPU::CreateTaskQueue(); + if (!create_task_queue_result) { + return std::nullopt; + } + std::unique_ptr task_queue = std::move(*create_task_queue_result); + + auto thread = std::thread(max::Hardware::CPU::TaskRunnerLoop, task_queue.get()); + // TODO: Attempt to lock that thread to the preferred type of core. + + return TaskThread(std::move(task_queue), std::move(thread)); + } + +} // namespace CPU +} // namespace Hardware +} // namespace max \ No newline at end of file diff --git a/Code/max/Hardware/CPU/TaskThread.hpp b/Code/max/Hardware/CPU/TaskThread.hpp new file mode 100644 index 0000000..ce0f0e1 --- /dev/null +++ b/Code/max/Hardware/CPU/TaskThread.hpp @@ -0,0 +1,34 @@ +// Copyright 2025, The max Contributors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MAX_HARDWARE_CPU_TASKTHREAD_HPP +#define MAX_HARDWARE_CPU_TASKTHREAD_HPP + +#include +#include +#include + +#include + +namespace max { +namespace Hardware { +namespace CPU { + + class TaskThread { + public: + + explicit TaskThread(std::unique_ptr task_queue, std::thread thread) noexcept; + + std::unique_ptr task_queue_; + std::thread thread_; + + }; + + std::optional CreateTaskThread() noexcept; + +} // namespace CPU +} // namespace Hardware +} // namespace max + +#endif // #ifndef MAX_HARDWARE_CPU_TASKTHREAD_HPP \ No newline at end of file diff --git a/Projects/VisualStudio/max/max.vcxproj b/Projects/VisualStudio/max/max.vcxproj index c744d57..cfaca87 100644 --- a/Projects/VisualStudio/max/max.vcxproj +++ b/Projects/VisualStudio/max/max.vcxproj @@ -83,8 +83,6 @@ true true - - @@ -204,6 +202,9 @@ true + + + @@ -224,8 +225,6 @@ true true - - true true @@ -309,6 +308,9 @@ true + + + diff --git a/Projects/VisualStudio/max/max.vcxproj.filters b/Projects/VisualStudio/max/max.vcxproj.filters index eb3bdc0..9d20f27 100644 --- a/Projects/VisualStudio/max/max.vcxproj.filters +++ b/Projects/VisualStudio/max/max.vcxproj.filters @@ -393,11 +393,14 @@ Code\max\Compiling - - Code\max\Algorithms + + Code\max\Hardware\CPU - - Code\max\Algorithms + + Code\max\Hardware\CPU + + + Code\max\Hardware\CPU @@ -485,11 +488,14 @@ Code\max\Containers - - Code\max\Algorithms + + Code\max\Hardware\CPU - - Code\max\Algorithms + + Code\max\Hardware\CPU + + + Code\max\Hardware\CPU