diff options
author | crupest <crupest@outlook.com> | 2021-06-10 11:55:27 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-06-10 11:55:27 +0800 |
commit | 5018c2b40009258ed0691cbbb1dcc4d8ac4a809b (patch) | |
tree | 1c4269b73b0473f47b98ca260676dbec1460791f | |
parent | 06c91dd3a3d17bd1f884c7e322fd7701a95ce7a9 (diff) | |
download | crupest-5018c2b40009258ed0691cbbb1dcc4d8ac4a809b.tar.gz crupest-5018c2b40009258ed0691cbbb1dcc4d8ac4a809b.tar.bz2 crupest-5018c2b40009258ed0691cbbb1dcc4d8ac4a809b.zip |
import(life): ...
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
|