diff options
Diffstat (limited to 'works/life/operating-system-experiment')
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;
 -}
  | 
