From 99e2e923d0c77b02f3fb4ff648ea916954868606 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Fri, 28 Feb 2025 23:13:39 +0800 Subject: chore(store): move everything to store. --- works/life/operating-system-experiment/.gitignore | 5 - works/life/operating-system-experiment/Base.h | 18 --- .../operating-system-experiment/CMakeLists.txt | 37 ----- .../operating-system-experiment/DataRaceDemo.cpp | 27 ---- .../DeadLockDetectionDemo.cpp | 113 --------------- .../DeadLockTestData1.txt | 4 - .../DeadLockTestData2.txt | 4 - .../DeadLockTestData3.txt | 6 - .../DeadLockTestData4.txt | 9 -- .../operating-system-experiment/Interlocked.cpp | 16 --- .../operating-system-experiment/Interlocked.hpp | 10 -- .../InterlockedAvoidDataRaceDemo.cpp | 28 ---- works/life/operating-system-experiment/Mutex.cpp | 100 ------------- works/life/operating-system-experiment/Mutex.h | 45 ------ .../MutexAvoidDataRaceDemo.cpp | 42 ------ .../ParallelCalculationDemo.cpp | 75 ---------- .../life/operating-system-experiment/Semaphore.cpp | 98 ------------- works/life/operating-system-experiment/Semaphore.h | 47 ------ .../SemaphoreAvoidDataRaceDemo.cpp | 36 ----- works/life/operating-system-experiment/Thread.cpp | 158 --------------------- works/life/operating-system-experiment/Thread.h | 83 ----------- works/life/operating-system-experiment/main.cpp | 16 --- 22 files changed, 977 deletions(-) delete mode 100644 works/life/operating-system-experiment/.gitignore delete mode 100644 works/life/operating-system-experiment/Base.h delete mode 100644 works/life/operating-system-experiment/CMakeLists.txt delete mode 100644 works/life/operating-system-experiment/DataRaceDemo.cpp delete mode 100644 works/life/operating-system-experiment/DeadLockDetectionDemo.cpp delete mode 100644 works/life/operating-system-experiment/DeadLockTestData1.txt delete mode 100644 works/life/operating-system-experiment/DeadLockTestData2.txt delete mode 100644 works/life/operating-system-experiment/DeadLockTestData3.txt delete mode 100644 works/life/operating-system-experiment/DeadLockTestData4.txt delete mode 100644 works/life/operating-system-experiment/Interlocked.cpp delete mode 100644 works/life/operating-system-experiment/Interlocked.hpp delete mode 100644 works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp delete mode 100644 works/life/operating-system-experiment/Mutex.cpp delete mode 100644 works/life/operating-system-experiment/Mutex.h delete mode 100644 works/life/operating-system-experiment/MutexAvoidDataRaceDemo.cpp delete mode 100644 works/life/operating-system-experiment/ParallelCalculationDemo.cpp delete mode 100644 works/life/operating-system-experiment/Semaphore.cpp delete mode 100644 works/life/operating-system-experiment/Semaphore.h delete mode 100644 works/life/operating-system-experiment/SemaphoreAvoidDataRaceDemo.cpp delete mode 100644 works/life/operating-system-experiment/Thread.cpp delete mode 100644 works/life/operating-system-experiment/Thread.h delete mode 100644 works/life/operating-system-experiment/main.cpp (limited to 'works/life/operating-system-experiment') diff --git a/works/life/operating-system-experiment/.gitignore b/works/life/operating-system-experiment/.gitignore deleted file mode 100644 index 502724c..0000000 --- a/works/life/operating-system-experiment/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.exe -*.pdb -.cache -build -compile_commands.json \ No newline at end of file diff --git a/works/life/operating-system-experiment/Base.h b/works/life/operating-system-experiment/Base.h deleted file mode 100644 index 6964c1c..0000000 --- a/works/life/operating-system-experiment/Base.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef HEADER_BASE_H -#define HEADER_BASE_H - -#ifdef _WIN32 -#define CRU_WINDOWS 1 -#endif - -#ifdef CRU_WINDOWS -#ifdef CRU_EXPORT_API -#define CRU_API __declspec(dllexport) -#else -#define CRU_API __declspec(dllimport) -#endif -#else -#define CRU_API -#endif - -#endif \ No newline at end of file diff --git a/works/life/operating-system-experiment/CMakeLists.txt b/works/life/operating-system-experiment/CMakeLists.txt deleted file mode 100644 index 79fe786..0000000 --- a/works/life/operating-system-experiment/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -cmake_minimum_required(VERSION 3.20) - -set(CMAKE_TOOLCHAIN_FILE $ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake - CACHE STRING "Vcpkg toolchain file") - -project(operating-system-experiment) - -set(CMAKE_CXX_STANDARD 17) - -find_package(fmt CONFIG REQUIRED) -find_package(Microsoft.GSL CONFIG REQUIRED) -add_library(cru_system SHARED Thread.cpp Mutex.cpp Interlocked.cpp Semaphore.cpp) -target_link_libraries(cru_system PUBLIC Microsoft.GSL::GSL fmt::fmt) -target_compile_definitions(cru_system PUBLIC CRU_EXPORT_API) -if(UNIX) -target_link_libraries(cru_system PUBLIC pthread) -endif() - -add_executable(main main.cpp) -target_link_libraries(main PRIVATE cru_system) - -add_executable(data_race_demo DataRaceDemo.cpp) -target_link_libraries(data_race_demo PRIVATE cru_system) - -add_executable(mutex_avoid_data_race_demo MutexAvoidDataRaceDemo.cpp) -target_link_libraries(mutex_avoid_data_race_demo PRIVATE cru_system) - -add_executable(interlocked_avoid_data_race_demo InterlockedAvoidDataRaceDemo.cpp) -target_link_libraries(interlocked_avoid_data_race_demo PRIVATE cru_system) - -add_executable(semaphore_avoid_data_race_demo SemaphoreAvoidDataRaceDemo.cpp) -target_link_libraries(semaphore_avoid_data_race_demo PRIVATE cru_system) - -add_executable(parallel_calculation_demo ParallelCalculationDemo.cpp) -target_link_libraries(parallel_calculation_demo PRIVATE cru_system) - -add_executable(dead_lock_detection_demo DeadLockDetectionDemo.cpp) diff --git a/works/life/operating-system-experiment/DataRaceDemo.cpp b/works/life/operating-system-experiment/DataRaceDemo.cpp deleted file mode 100644 index a2f98d9..0000000 --- a/works/life/operating-system-experiment/DataRaceDemo.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "Thread.h" - -#include - -int main() { - unsigned data = 0; - - cru::Thread t1([&data] { - for (int i = 0; i < 100000; i++) - data += 10; - }); - - cru::Thread t2([&data] { - for (int i = 0; i < 100000; i++) - data += 10; - }); - - std::cout << "Created thread: " << t1.GetNativeID() << '\n'; - std::cout << "Created thread: " << t2.GetNativeID() << '\n'; - - t1.Join(); - t2.Join(); - std::cout << "Answer is " << data << ", which is " - << (data == 2000000 ? "correct" : "false") << '\n'; - - return 0; -} diff --git a/works/life/operating-system-experiment/DeadLockDetectionDemo.cpp b/works/life/operating-system-experiment/DeadLockDetectionDemo.cpp deleted file mode 100644 index bea2b43..0000000 --- a/works/life/operating-system-experiment/DeadLockDetectionDemo.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Demo使用方法: -// 本程序采用标准C++11代码写成,请使用支持C++11的编译器编译。 -// -// 程序接受的输入为n个整数对,其中1-10000表示进程,10001及以上表示锁,顺序很重要: -// 1 10001 -> process 1 is acquiring or waiting for lock 1 -// 10001 1 -> lock 1 is owned by process 1 -// -// 建议采用重定向输入至文件的方式输入,提供4个典型情况的测试数据。 -// - -#include -#include -#include -#include - -const int LOCK_START_INDEX = 10000; - -struct Node { - int id; -}; - -bool operator==(const Node &left, const Node &right) { - return left.id == right.id; -} - -template <> struct std::hash { - std::size_t operator()(const Node &node) const { - return std::hash{}(node.id); - } -}; - -std::ostream &operator<<(std::ostream &left, const Node &right) { - left << (right.id > LOCK_START_INDEX ? "lock" : "process") << ' ' - << (right.id > LOCK_START_INDEX ? right.id - LOCK_START_INDEX - : right.id); - return left; -} - -bool dfs( - const Node *root, - std::unordered_map> &edges, - std::unordered_map &visited) { - - if (visited[root]) { - std::cout << "Ohhhhhh, it is already visited!\n"; - return true; - } - - visited[root] = true; - auto r = edges.find(root); - if (r != edges.cend()) - for (auto n : r->second) { - std::cout << "from " << *root << " go to " << *n << "\n"; - if (dfs(n, edges, visited)) - return true; - std::cout << "from " << *n << " back to " << *root << "\n"; - } - - edges.erase(root); - return false; -} - -int main() { - std::vector ns; - - while (std::cin) { - int n; - std::cin >> n; - if (std::cin) - ns.push_back(n); - } - - if (!std::cin.eof()) { - std::cerr << "Failed to parse input.\n"; - return -1; - } - - if (ns.size() % 2 != 0) { - std::cerr << "Input integer number must be even.\n"; - return -1; - } - - std::unordered_set nodes; - std::unordered_map> edges; - - for (int i = 0; i < ns.size(); i += 2) { - int p = ns[i]; - int l = ns[i + 1]; - auto r1 = nodes.insert({p}); - auto r2 = nodes.insert({l}); - edges[&(*r1.first)].insert(&(*r2.first)); - } - - bool h = false; - - while (!edges.empty()) { - auto n = edges.cbegin()->first; - std::unordered_map visited; - std::cout << "Begin to detect child graph containing '" << *n << "'.\n"; - if (dfs(n, edges, visited)) { - h = true; - break; - } - } - - if (h) { - std::cout << "Cycle, aka dead lock, detected.\n"; - } else { - std::cout << "You are free of dead lock!!!\n"; - } - - return 0; -} diff --git a/works/life/operating-system-experiment/DeadLockTestData1.txt b/works/life/operating-system-experiment/DeadLockTestData1.txt deleted file mode 100644 index 0c8dd14..0000000 --- a/works/life/operating-system-experiment/DeadLockTestData1.txt +++ /dev/null @@ -1,4 +0,0 @@ -1 10001 -2 10001 -3 10001 -4 10001 diff --git a/works/life/operating-system-experiment/DeadLockTestData2.txt b/works/life/operating-system-experiment/DeadLockTestData2.txt deleted file mode 100644 index d632f2a..0000000 --- a/works/life/operating-system-experiment/DeadLockTestData2.txt +++ /dev/null @@ -1,4 +0,0 @@ -10001 1 -1 10002 -2 10001 -10002 2 diff --git a/works/life/operating-system-experiment/DeadLockTestData3.txt b/works/life/operating-system-experiment/DeadLockTestData3.txt deleted file mode 100644 index 1e1692d..0000000 --- a/works/life/operating-system-experiment/DeadLockTestData3.txt +++ /dev/null @@ -1,6 +0,0 @@ -1 10001 -10001 2 -2 10002 -10002 3 -3 10003 -10003 1 diff --git a/works/life/operating-system-experiment/DeadLockTestData4.txt b/works/life/operating-system-experiment/DeadLockTestData4.txt deleted file mode 100644 index d124102..0000000 --- a/works/life/operating-system-experiment/DeadLockTestData4.txt +++ /dev/null @@ -1,9 +0,0 @@ -1 10001 -2 10001 -3 10002 -3 10004 -10001 3 -4 10001 -4 10005 -10004 5 -10005 5 diff --git a/works/life/operating-system-experiment/Interlocked.cpp b/works/life/operating-system-experiment/Interlocked.cpp deleted file mode 100644 index 7fc8c6b..0000000 --- a/works/life/operating-system-experiment/Interlocked.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "Interlocked.hpp" - -#ifdef CRU_WINDOWS -#include -#else -#endif - -namespace cru { -void CruInterlockedAdd(volatile long long *v, long long a) { -#ifdef CRU_WINDOWS - InterlockedAdd64(v, a); -#else - __sync_fetch_and_add(v, a); -#endif -} -} // namespace cru diff --git a/works/life/operating-system-experiment/Interlocked.hpp b/works/life/operating-system-experiment/Interlocked.hpp deleted file mode 100644 index 7e09b60..0000000 --- a/works/life/operating-system-experiment/Interlocked.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HRADER_INTERLOCKED_H -#define HRADER_INTERLOCKED_H - -#include "Base.h" - -namespace cru { -CRU_API void CruInterlockedAdd(volatile long long *v, long long a); -} - -#endif diff --git a/works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp b/works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp deleted file mode 100644 index 91d6d50..0000000 --- a/works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "Interlocked.hpp" -#include "Thread.h" - -#include - -int main() { - volatile long long data = 0; - - cru::Thread t1([&data] { - for (int i = 0; i < 100000; i++) - cru::CruInterlockedAdd(&data, 10); - }); - - cru::Thread t2([&data] { - for (int i = 0; i < 100000; i++) - cru::CruInterlockedAdd(&data, 10); - }); - - std::cout << "Created thread: " << t1.GetNativeID() << '\n'; - std::cout << "Created thread: " << t2.GetNativeID() << '\n'; - - t1.Join(); - t2.Join(); - std::cout << "Answer is " << data << ", which is " - << (data == 2000000 ? "correct" : "false") << '\n'; - - return 0; -} diff --git a/works/life/operating-system-experiment/Mutex.cpp b/works/life/operating-system-experiment/Mutex.cpp deleted file mode 100644 index 8acfdc5..0000000 --- a/works/life/operating-system-experiment/Mutex.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "Mutex.h" - -#include - -#ifndef CRU_WINDOWS -#include -#endif - -namespace cru { -Mutex::Mutex() { -#ifdef CRU_WINDOWS - handle_ = CreateMutexW(nullptr, FALSE, nullptr); - assert(handle_); -#else - mutex_ = std::make_unique(); - - auto c = pthread_mutex_init(mutex_.get(), nullptr); - assert(c == 0); -#endif -} - -Mutex::Mutex(Mutex &&other) -#ifdef CRU_WINDOWS - : handle_(other.handle_) -#else - : mutex_(std::move(other.mutex_)) -#endif -{ -#ifdef CRU_WINDOWS - other.handle_ = nullptr; -#endif -} - -Mutex &Mutex::operator=(Mutex &&other) { - if (this != &other) { - Destroy(); -#ifdef CRU_WINDOWS - handle_ = other.handle_; - other.handle_ = nullptr; -#else - mutex_ = std::move(other.mutex_); -#endif - } - return *this; -} - -Mutex::~Mutex() { Destroy(); } - -void Mutex::Lock() { -#ifdef CRU_WINDOWS - auto c = WaitForSingleObject(handle_, INFINITE); - assert(c == WAIT_OBJECT_0); -#else - assert(mutex_); - auto c = pthread_mutex_lock(mutex_.get()); - assert(c == 0); -#endif -} - -bool Mutex::TryLock() { -#ifdef CRU_WINDOWS - auto c = WaitForSingleObject(handle_, 0); - assert(c == WAIT_OBJECT_0 || c == WAIT_TIMEOUT); - return c == WAIT_OBJECT_0 ? true : false; -#else - assert(mutex_); - auto c = pthread_mutex_trylock(mutex_.get()); - assert(c == 0 || c == EBUSY); - return c == 0 ? true : false; -#endif -} - -void Mutex::Unlock() { -#ifdef CRU_WINDOWS - auto c = ReleaseMutex(handle_); - assert(c); -#else - assert(mutex_); - auto c = pthread_mutex_unlock(mutex_.get()); - assert(c == 0); -#endif -} - -void Mutex::Destroy() { -#ifdef CRU_WINDOWS - if (handle_ != nullptr) { - auto c = CloseHandle(handle_); - assert(c); - handle_ = nullptr; - } -#else - if (mutex_ != nullptr) { - auto c = pthread_mutex_destroy(mutex_.get()); - assert(c == 0); - mutex_ = nullptr; - } -#endif -} - -} // namespace cru diff --git a/works/life/operating-system-experiment/Mutex.h b/works/life/operating-system-experiment/Mutex.h deleted file mode 100644 index d561f1a..0000000 --- a/works/life/operating-system-experiment/Mutex.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_MUTEX_H -#define HEADER_MUTEX_H - -#include "Base.h" - -#include - -#ifdef CRU_WINDOWS -#include -#else -#include -#endif - -namespace cru { -class CRU_API Mutex { -public: - Mutex(); - - Mutex(const Mutex &other) = delete; - Mutex &operator=(const Mutex &other) = delete; - - Mutex(Mutex &&other); - Mutex &operator=(Mutex &&other); - - ~Mutex(); - -public: - void Lock(); - bool TryLock(); - - void Unlock(); - -private: - void Destroy(); - -private: -#ifdef CRU_WINDOWS - HANDLE handle_; -#else - std::unique_ptr mutex_; -#endif -}; -} // namespace cru - -#endif \ No newline at end of file diff --git a/works/life/operating-system-experiment/MutexAvoidDataRaceDemo.cpp b/works/life/operating-system-experiment/MutexAvoidDataRaceDemo.cpp deleted file mode 100644 index 81a7aa1..0000000 --- a/works/life/operating-system-experiment/MutexAvoidDataRaceDemo.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "Mutex.h" -#include "Thread.h" - -#include - -int main() { - - unsigned data = 0; - cru::Mutex mutex; - mutex.Lock(); - - cru::Thread t1([&data, &mutex] { - for (int i = 0; i < 100000; i++) { - mutex.Lock(); - data += 10; - //std::cout << "Data is now: " << data << '\n'; - mutex.Unlock(); - } - }); - - cru::Thread t2([&data, &mutex] { - for (int i = 0; i < 100000; i++) { - mutex.Lock(); - data += 10; - //std::cout << "Data is now: " << data << '\n'; - mutex.Unlock(); - } - }); - - std::cout << "Created thread: " << t1.GetNativeID() << '\n'; - std::cout << "Created thread: " << t2.GetNativeID() << '\n'; - - mutex.Unlock(); - - t1.Join(); - t2.Join(); - - std::cout << "Answer is " << data << ", which is " - << (data == 2000000 ? "correct" : "false") << '\n'; - - return 0; -} diff --git a/works/life/operating-system-experiment/ParallelCalculationDemo.cpp b/works/life/operating-system-experiment/ParallelCalculationDemo.cpp deleted file mode 100644 index 0174c55..0000000 --- a/works/life/operating-system-experiment/ParallelCalculationDemo.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "Thread.h" - -#include - -const long long N = 1e9; - -int main(int argc, char **argv) { - int thread_number; - if (argc == 1) { - thread_number = 1; - } else if (argc == 2) { - thread_number = std::atoi(argv[1]); - if (thread_number <= 0) { - std::cerr << "Argument must be a positive integer.\n"; - return -1; - } - } else { - std::cerr << "Too many arguments.\n"; - return -1; - } - - std::cout << "Use " << thread_number << " threads to calculate sum of 1-" << N - << ".\n"; - - if (thread_number == 1) { - long long sum = 0; - for (long long i = 1; i <= 1e9; i++) { - sum += i; - } - std::cout << "Sum of 1-" << N << " is " << sum << '\n'; - } else { - std::vector threads(thread_number); - std::vector partial_sum(thread_number); - - long long step = N / thread_number; - - for (int i = 0; i < thread_number; i++) { - long long start = step * i; - long long end = step * (i + 1); - - long long &ps = partial_sum[i]; - - if (i == thread_number - 1) { - threads[i] = cru::Thread([&ps, start] { - long long sum = 0; - for (long long j = start; j <= N; j++) { - sum += j; - } - ps = sum; - }); - } else { - threads[i] = cru::Thread([&ps, start, end] { - long long sum = 0; - for (int j = start; j < end; j++) { - sum += j; - } - ps = sum; - }); - } - } - - for (auto &thread : threads) { - thread.Join(); - } - - long long sum = 0; - for (auto ps : partial_sum) { - sum += ps; - } - - std::cout << "Sum of 1-" << N << " is " << sum << '\n'; - } - - return 0; -} diff --git a/works/life/operating-system-experiment/Semaphore.cpp b/works/life/operating-system-experiment/Semaphore.cpp deleted file mode 100644 index aceef4d..0000000 --- a/works/life/operating-system-experiment/Semaphore.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "Semaphore.h" - -#include - -#ifndef CRU_WINDOWS -#include -#endif - -namespace cru { -Semaphore::Semaphore(unsigned init_value) { -#ifdef CRU_WINDOWS - handle_ = CreateSemaphoreW(nullptr, init_value, 100, nullptr); - assert(handle_); -#else - semaphore_ = std::make_unique(); - auto c = sem_init(semaphore_.get(), 0, init_value); - assert(c == 0); -#endif -} - -Semaphore::Semaphore(Semaphore &&other) -#ifdef CRU_WINDOWS - : handle_(other.handle_) -#else - : semaphore_(std::move(other.semaphore_)) -#endif -{ -#ifdef CRU_WINDOWS - other.handle_ = nullptr; -#endif -} - -Semaphore &Semaphore::operator=(Semaphore &&other) { - if (this != &other) { - Destroy(); -#ifdef CRU_WINDOWS - handle_ = other.handle_; - other.handle_ = nullptr; -#else - semaphore_ = std::move(other.semaphore_); -#endif - } - return *this; -} - -Semaphore::~Semaphore() { Destroy(); } - -void Semaphore::P() { Acquire(); } -void Semaphore::V() { Release(); } - -void Semaphore::Acquire() { -#ifdef CRU_WINDOWS - auto c = WaitForSingleObject(handle_, INFINITE); - assert(c == WAIT_OBJECT_0); -#else - auto c = sem_wait(semaphore_.get()); - assert(c == 0); -#endif -} - -bool Semaphore::TryAcquire() { -#ifdef CRU_WINDOWS - auto c = WaitForSingleObject(handle_, 0); - assert(c == WAIT_OBJECT_0 || c == WAIT_TIMEOUT); - return c == WAIT_OBJECT_0 ? true : false; -#else - auto c = sem_trywait(semaphore_.get()); - assert((c == 0) || (c == -1 && errno == EAGAIN)); - return c == 0 ? true : false; -#endif -} - -void Semaphore::Release() { -#ifdef CRU_WINDOWS - auto c = ReleaseSemaphore(handle_, 1, nullptr); - assert(c); -#else - auto c = sem_post(semaphore_.get()); - assert(c == 0); -#endif -} - -void Semaphore::Destroy() { -#ifdef CRU_WINDOWS - if (handle_ != nullptr) { - auto c = CloseHandle(handle_); - assert(c); - handle_ = nullptr; - } -#else - if (semaphore_ != nullptr) { - auto c = sem_destroy(semaphore_.get()); - assert(c == 0); - semaphore_ = nullptr; - } -#endif -} -} // namespace cru \ No newline at end of file diff --git a/works/life/operating-system-experiment/Semaphore.h b/works/life/operating-system-experiment/Semaphore.h deleted file mode 100644 index 430c036..0000000 --- a/works/life/operating-system-experiment/Semaphore.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef HEADER_SEMAPHORE_H -#define HEADER_SEMAPHORE_H - -#include "Base.h" - -#include - -#ifdef CRU_WINDOWS -#include -#else -#include -#endif - -namespace cru { -class CRU_API Semaphore { -public: - explicit Semaphore(unsigned init_value = 1); - - Semaphore(const Semaphore &other) = delete; - Semaphore &operator=(const Semaphore &other) = delete; - - Semaphore(Semaphore &&other); - Semaphore &operator=(Semaphore &&other); - - ~Semaphore(); - -public: - void P(); - void V(); - - void Acquire(); - bool TryAcquire(); - void Release(); - -private: - void Destroy(); - -private: -#ifdef CRU_WINDOWS - HANDLE handle_ = nullptr; -#else - std::unique_ptr semaphore_; -#endif -}; -} // namespace cru - -#endif \ No newline at end of file diff --git a/works/life/operating-system-experiment/SemaphoreAvoidDataRaceDemo.cpp b/works/life/operating-system-experiment/SemaphoreAvoidDataRaceDemo.cpp deleted file mode 100644 index 0068082..0000000 --- a/works/life/operating-system-experiment/SemaphoreAvoidDataRaceDemo.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "Semaphore.h" -#include "Thread.h" - -#include - -int main() { - unsigned data = 0; - - cru::Semaphore semaphore; - - cru::Thread t1([&data, &semaphore] { - for (int i = 0; i < 100000; i++) { - semaphore.P(); - data += 10; - semaphore.V(); - } - }); - - cru::Thread t2([&data, &semaphore] { - for (int i = 0; i < 100000; i++) { - semaphore.P(); - data += 10; - semaphore.V(); - } - }); - - std::cout << "Created thread: " << t1.GetNativeID() << '\n'; - std::cout << "Created thread: " << t2.GetNativeID() << '\n'; - - t1.Join(); - t2.Join(); - std::cout << "Answer is " << data << ", which is " - << (data == 2000000 ? "correct" : "false") << '\n'; - - return 0; -} diff --git a/works/life/operating-system-experiment/Thread.cpp b/works/life/operating-system-experiment/Thread.cpp deleted file mode 100644 index 0bc4c18..0000000 --- a/works/life/operating-system-experiment/Thread.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "Thread.h" - -#include -#include -#include - -namespace cru { -Thread::Thread(Thread &&other) noexcept - : detached_(other.detached_), joined_(other.joined_), -#ifdef CRU_WINDOWS - thread_handle_(other.thread_handle_) -#else - thread_(std::move(other.thread_)) -#endif -{ - other.joined_ = false; -#ifdef CRU_WINDOWS - other.thread_handle_ = nullptr; -#endif -} // namespace cru - -Thread &Thread::operator=(Thread &&other) noexcept { - if (this != &other) { - detached_ = other.detached_; - joined_ = other.joined_; -#ifdef CRU_WINDOWS - thread_handle_ = other.thread_handle_; - other.thread_handle_ = nullptr; -#else - thread_ = std::move(other.thread_); -#endif - other.detached_ = false; - other.joined_ = false; - } - - return *this; -} - -Thread::~Thread() { Destroy(); } - -void Thread::Join() { - joined_ = true; -#ifdef CRU_WINDOWS - assert(thread_handle_); - WaitForSingleObject(thread_handle_, INFINITE); -#else - assert(thread_); - auto c = pthread_join(*thread_, nullptr); - assert(c == 0); -#endif -} - -void Thread::Detach() { -#ifdef CRU_WINDOWS - assert(thread_handle_); -#else - assert(thread_); -#endif - detached_ = true; -} - -#ifdef CRU_WINDOWS -DWORD -#else -pthread_t -#endif -Thread::GetNativeID() { -#ifdef CRU_WINDOWS - assert(thread_handle_); - return thread_id_; -#else - assert(thread_); - return *thread_; -#endif -} - -#ifdef CRU_WINDOWS -HANDLE -#else -pthread_t -#endif -Thread::GetNativeHandle() { -#ifdef CRU_WINDOWS - assert(thread_handle_); - return thread_handle_; -#else - assert(thread_); - return *thread_; -#endif -} - -void Thread::swap(Thread &other) noexcept { -#ifdef CRU_WINDOWS - Thread temp = std::move(*this); - *this = std::move(other); - other = std::move(temp); -#else -#endif -} - -void Thread::Destroy() noexcept { - if (!detached_ && !joined_ && -#ifdef CRU_WINDOWS - thread_handle_ != nullptr -#else - thread_ != nullptr -#endif - ) { - std::terminate(); - } else { - detached_ = false; - joined_ = false; -#ifdef CRU_WINDOWS - thread_id_ = 0; - if (thread_handle_ != nullptr) { - auto c = CloseHandle(thread_handle_); - assert(c); - thread_handle_ = nullptr; - } -#else - thread_ = nullptr; -#endif - } -} - -namespace { -#ifdef CRU_WINDOWS -DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) { - auto p = static_cast *>(lpParameter); - (*p)(); - delete p; - return 0; -} -#else -void *ThreadProc(void *data) { - auto p = static_cast *>(data); - (*p)(); - delete p; - return nullptr; -} - -#endif -} // namespace - -void Thread::CreateThread(std::function *proc) { -#ifdef CRU_WINDOWS - thread_handle_ = ::CreateThread(nullptr, 0, ThreadProc, - static_cast(proc), 0, &thread_id_); - assert(thread_handle_); -#else - thread_.reset(new pthread_t()); - auto c = pthread_create(thread_.get(), nullptr, ThreadProc, - static_cast(proc)); - assert(c == 0); -#endif -}; - -} // namespace cru \ No newline at end of file diff --git a/works/life/operating-system-experiment/Thread.h b/works/life/operating-system-experiment/Thread.h deleted file mode 100644 index 4ad1ef4..0000000 --- a/works/life/operating-system-experiment/Thread.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef HEADER_THREAD_H -#define HEADER_THREAD_H - -#include "Base.h" - -#ifdef CRU_WINDOWS -#include -#else -#include -#endif - -#ifdef __cplusplus - -#include -#include -#include -#include -#include -#include -#include - -namespace cru { -class CRU_API Thread { -public: - Thread() = default; - template Thread(Fn &&process, Args &&...args); - Thread(const Thread &other) = delete; - Thread(Thread &&other) noexcept; - Thread &operator=(const Thread &other) = delete; - Thread &operator=(Thread &&other) noexcept; - ~Thread(); - -public: - void Join(); - void Detach(); - -#ifdef CRU_WINDOWS - DWORD -#else - pthread_t -#endif - GetNativeID(); - -#ifdef CRU_WINDOWS - HANDLE -#else - pthread_t -#endif - GetNativeHandle(); - - void swap(Thread &other) noexcept; - -private: - void Destroy() noexcept; - void CreateThread(std::function *proc); - -private: - bool detached_ = false; - bool joined_ = false; - -#ifdef CRU_WINDOWS - DWORD thread_id_ = 0; - HANDLE thread_handle_ = nullptr; -#else - std::unique_ptr thread_; -#endif -}; - -template -Thread::Thread(Fn &&process, Args &&...args) { - std::tuple...> a{std::forward(args)...}; - auto p = new std::function( - [process = std::forward(process), args = std::move(a)]() { - std::apply(process, std::move(args)); - }); - - CreateThread(p); -}; -} // namespace cru - -#endif - -#endif diff --git a/works/life/operating-system-experiment/main.cpp b/works/life/operating-system-experiment/main.cpp deleted file mode 100644 index ada8c85..0000000 --- a/works/life/operating-system-experiment/main.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "Thread.h" - -#include -#include - -int main() { - cru::Thread thread1([](const std::string &s) { std::cout << s; }, - "Hello world! 1\n"); - thread1.Join(); - - cru::Thread thread2([](const std::string &s) { std::cout << s; }, - "Hello world! 2\n"); - thread2.Join(); - - return 0; -} -- cgit v1.2.3