aboutsummaryrefslogtreecommitdiff
path: root/works/life/operating-system-experiment
diff options
context:
space:
mode:
Diffstat (limited to 'works/life/operating-system-experiment')
-rw-r--r--works/life/operating-system-experiment/.gitignore5
-rw-r--r--works/life/operating-system-experiment/Base.h18
-rw-r--r--works/life/operating-system-experiment/CMakeLists.txt37
-rw-r--r--works/life/operating-system-experiment/DataRaceDemo.cpp27
-rw-r--r--works/life/operating-system-experiment/DeadLockDetectionDemo.cpp113
-rw-r--r--works/life/operating-system-experiment/DeadLockTestData1.txt4
-rw-r--r--works/life/operating-system-experiment/DeadLockTestData2.txt4
-rw-r--r--works/life/operating-system-experiment/DeadLockTestData3.txt6
-rw-r--r--works/life/operating-system-experiment/DeadLockTestData4.txt9
-rw-r--r--works/life/operating-system-experiment/Interlocked.cpp16
-rw-r--r--works/life/operating-system-experiment/Interlocked.hpp10
-rw-r--r--works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp28
-rw-r--r--works/life/operating-system-experiment/Mutex.cpp100
-rw-r--r--works/life/operating-system-experiment/Mutex.h45
-rw-r--r--works/life/operating-system-experiment/MutexAvoidDataRaceDemo.cpp42
-rw-r--r--works/life/operating-system-experiment/ParallelCalculationDemo.cpp75
-rw-r--r--works/life/operating-system-experiment/Semaphore.cpp98
-rw-r--r--works/life/operating-system-experiment/Semaphore.h47
-rw-r--r--works/life/operating-system-experiment/SemaphoreAvoidDataRaceDemo.cpp36
-rw-r--r--works/life/operating-system-experiment/Thread.cpp158
-rw-r--r--works/life/operating-system-experiment/Thread.h83
-rw-r--r--works/life/operating-system-experiment/main.cpp16
22 files changed, 0 insertions, 977 deletions
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 <iostream>
-
-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 <iostream>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-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<Node> {
- std::size_t operator()(const Node &node) const {
- return std::hash<int>{}(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<const Node *, std::unordered_set<const Node *>> &edges,
- std::unordered_map<const Node *, bool> &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<int> 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<Node> nodes;
- std::unordered_map<const Node *, std::unordered_set<const Node *>> 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<const Node *, bool> 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 <Windows.h>
-#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 <iostream>
-
-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 <cassert>
-
-#ifndef CRU_WINDOWS
-#include <errno.h>
-#endif
-
-namespace cru {
-Mutex::Mutex() {
-#ifdef CRU_WINDOWS
- handle_ = CreateMutexW(nullptr, FALSE, nullptr);
- assert(handle_);
-#else
- mutex_ = std::make_unique<pthread_mutex_t>();
-
- 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 <memory>
-
-#ifdef CRU_WINDOWS
-#include <Windows.h>
-#else
-#include <pthread.h>
-#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<pthread_mutex_t> 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 <iostream>
-
-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 <iostream>
-
-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<cru::Thread> threads(thread_number);
- std::vector<long long> 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 <cassert>
-
-#ifndef CRU_WINDOWS
-#include <errno.h>
-#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<sem_t>();
- 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 <memory>
-
-#ifdef CRU_WINDOWS
-#include <Windows.h>
-#else
-#include <semaphore.h>
-#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<sem_t> 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 <iostream>
-
-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 <cassert>
-#include <exception>
-#include <utility>
-
-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<std::function<void()> *>(lpParameter);
- (*p)();
- delete p;
- return 0;
-}
-#else
-void *ThreadProc(void *data) {
- auto p = static_cast<std::function<void()> *>(data);
- (*p)();
- delete p;
- return nullptr;
-}
-
-#endif
-} // namespace
-
-void Thread::CreateThread(std::function<void()> *proc) {
-#ifdef CRU_WINDOWS
- thread_handle_ = ::CreateThread(nullptr, 0, ThreadProc,
- static_cast<void *>(proc), 0, &thread_id_);
- assert(thread_handle_);
-#else
- thread_.reset(new pthread_t());
- auto c = pthread_create(thread_.get(), nullptr, ThreadProc,
- static_cast<void *>(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 <Windows.h>
-#else
-#include <pthread.h>
-#endif
-
-#ifdef __cplusplus
-
-#include <cassert>
-#include <functional>
-#include <memory>
-#include <tuple>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-namespace cru {
-class CRU_API Thread {
-public:
- Thread() = default;
- template <typename Fn, typename... Args> 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<void()> *proc);
-
-private:
- bool detached_ = false;
- bool joined_ = false;
-
-#ifdef CRU_WINDOWS
- DWORD thread_id_ = 0;
- HANDLE thread_handle_ = nullptr;
-#else
- std::unique_ptr<pthread_t> thread_;
-#endif
-};
-
-template <typename Fn, typename... Args>
-Thread::Thread(Fn &&process, Args &&...args) {
- std::tuple<std::decay_t<Args>...> a{std::forward<Args>(args)...};
- auto p = new std::function<void()>(
- [process = std::forward<Fn>(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 <iostream>
-#include <string>
-
-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;
-}