aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-06-10 11:55:27 +0800
committercrupest <crupest@outlook.com>2021-06-10 11:55:27 +0800
commit5018c2b40009258ed0691cbbb1dcc4d8ac4a809b (patch)
tree1c4269b73b0473f47b98ca260676dbec1460791f /works/life
parent06c91dd3a3d17bd1f884c7e322fd7701a95ce7a9 (diff)
downloadcrupest-5018c2b40009258ed0691cbbb1dcc4d8ac4a809b.tar.gz
crupest-5018c2b40009258ed0691cbbb1dcc4d8ac4a809b.tar.bz2
crupest-5018c2b40009258ed0691cbbb1dcc4d8ac4a809b.zip
import(life): ...
Diffstat (limited to 'works/life')
-rw-r--r--works/life/operating-system-experiment/CMakeLists.txt3
-rw-r--r--works/life/operating-system-experiment/Interlocked.cpp2
-rw-r--r--works/life/operating-system-experiment/Interlocked.hpp2
-rw-r--r--works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp28
-rw-r--r--works/life/operating-system-experiment/Thread.cpp18
-rw-r--r--works/life/operating-system-experiment/Thread.h12
6 files changed, 51 insertions, 14 deletions
diff --git a/works/life/operating-system-experiment/CMakeLists.txt b/works/life/operating-system-experiment/CMakeLists.txt
index bd50319..8b4617f 100644
--- a/works/life/operating-system-experiment/CMakeLists.txt
+++ b/works/life/operating-system-experiment/CMakeLists.txt
@@ -24,3 +24,6 @@ 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)
diff --git a/works/life/operating-system-experiment/Interlocked.cpp b/works/life/operating-system-experiment/Interlocked.cpp
index 1c0f638..7fc8c6b 100644
--- a/works/life/operating-system-experiment/Interlocked.cpp
+++ b/works/life/operating-system-experiment/Interlocked.cpp
@@ -6,7 +6,7 @@
#endif
namespace cru {
-void InterlockedAdd(volatile long long *v, long long a) {
+void CruInterlockedAdd(volatile long long *v, long long a) {
#ifdef CRU_WINDOWS
InterlockedAdd64(v, a);
#else
diff --git a/works/life/operating-system-experiment/Interlocked.hpp b/works/life/operating-system-experiment/Interlocked.hpp
index aa5dbfc..7e09b60 100644
--- a/works/life/operating-system-experiment/Interlocked.hpp
+++ b/works/life/operating-system-experiment/Interlocked.hpp
@@ -4,7 +4,7 @@
#include "Base.h"
namespace cru {
-CRU_API void InterlockedAdd(volatile long long *v, long long a);
+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
new file mode 100644
index 0000000..91d6d50
--- /dev/null
+++ b/works/life/operating-system-experiment/InterlockedAvoidDataRaceDemo.cpp
@@ -0,0 +1,28 @@
+#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/Thread.cpp b/works/life/operating-system-experiment/Thread.cpp
index a5f526d..657c69f 100644
--- a/works/life/operating-system-experiment/Thread.cpp
+++ b/works/life/operating-system-experiment/Thread.cpp
@@ -122,7 +122,7 @@ void Thread::Destroy() noexcept {
}
}
-namespace details {
+namespace {
#ifdef CRU_WINDOWS
DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) {
auto p = static_cast<std::function<void()> *>(lpParameter);
@@ -139,5 +139,19 @@ void *ThreadProc(void *data) {
}
#endif
-} // namespace details
+} // 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
index 56fdcb0..735407c 100644
--- a/works/life/operating-system-experiment/Thread.h
+++ b/works/life/operating-system-experiment/Thread.h
@@ -52,6 +52,7 @@ public:
private:
void Destroy() noexcept;
+ void CreateThread(std::function<void()> *proc);
private:
bool detached_ = false;
@@ -81,16 +82,7 @@ Thread::Thread(Fn &&process, Args &&...args) {
std::apply(process, std::move(args));
});
-#ifdef CRU_WINDOWS
- thread_handle_ = ::CreateThread(nullptr, 0, &::cru::details::ThreadProc,
- static_cast<void *>(p), 0, &thread_id_);
- assert(thread_handle_);
-#else
- thread_.reset(new pthread_t());
- auto c = pthread_create(thread_.get(), nullptr, details::ThreadProc,
- static_cast<void *>(p));
- assert(c == 0);
-#endif
+ CreateThread(p);
};
} // namespace cru