From 861976fc69a8a5d20322178f03ce52d0fcb32e2e Mon Sep 17 00:00:00 2001 From: Hizenberg Date: Sat, 13 Apr 2024 13:24:19 +0530 Subject: [PATCH] rwlock of pthread demo --- .gitignore | 2 + rwlock_example/CMakeLists.txt | 21 +++++++ rwlock_example/CMakePresets.json | 101 ++++++++++++++++++++++++++++++ rwlock_example/rwlock_example.c | 103 +++++++++++++++++++++++++++++++ 4 files changed, 227 insertions(+) create mode 100644 rwlock_example/CMakeLists.txt create mode 100644 rwlock_example/CMakePresets.json create mode 100644 rwlock_example/rwlock_example.c diff --git a/.gitignore b/.gitignore index 868debf..3914244 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *vsidx *.opendb +.vs +out diff --git a/rwlock_example/CMakeLists.txt b/rwlock_example/CMakeLists.txt new file mode 100644 index 0000000..cb56d91 --- /dev/null +++ b/rwlock_example/CMakeLists.txt @@ -0,0 +1,21 @@ +# CMakeList.txt : CMake project for rwlock_example, include source and define +# project specific logic here. +# +cmake_minimum_required (VERSION 3.8) + +# Enable Hot Reload for MSVC compilers if supported. +if (POLICY CMP0141) + cmake_policy(SET CMP0141 NEW) + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") +endif() + +project ("rwlock_example") + +# Add source to this project's executable. +add_executable (rwlock_example "rwlock_example.c" ) + +if (CMAKE_VERSION VERSION_GREATER 3.12) + set_property(TARGET rwlock_example PROPERTY CXX_STANDARD 20) +endif() + +# TODO: Add tests and install targets if needed. diff --git a/rwlock_example/CMakePresets.json b/rwlock_example/CMakePresets.json new file mode 100644 index 0000000..f4bc98b --- /dev/null +++ b/rwlock_example/CMakePresets.json @@ -0,0 +1,101 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "windows-base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "x64-debug", + "displayName": "x64 Debug", + "inherits": "windows-base", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "x64-release", + "displayName": "x64 Release", + "inherits": "x64-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "x86-debug", + "displayName": "x86 Debug", + "inherits": "windows-base", + "architecture": { + "value": "x86", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "x86-release", + "displayName": "x86 Release", + "inherits": "x86-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "linux-debug", + "displayName": "Linux Debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + }, + { + "name": "macos-debug", + "displayName": "macOS Debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + } + ] +} diff --git a/rwlock_example/rwlock_example.c b/rwlock_example/rwlock_example.c new file mode 100644 index 0000000..46776e0 --- /dev/null +++ b/rwlock_example/rwlock_example.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +static pthread_rwlock_t rw_lock; +static int n_r = 0; +static int n_w = 0; +pthread_mutex_t state_check_mutex; + +static void +cs_static_check() { + + pthread_mutex_lock(&state_check_mutex); + assert(n_r >= 0 && n_w >= 0); /* cannot be negative */ + + if (n_r == 0 && n_w == 0) { + //valid condition + } + else if (n_r > 0 && n_w == 0) { + //valid condition + } + else if (n_r == 0 && n_w == 1) { + //valid condition + } + else + assert(0); + + printf("n_r = %d, n_w = %d\n", n_r, n_w); + pthread_mutex_unlock(&state_check_mutex); +} + +static void +execute_cs() { + + cs_status_check(); +} + +static void +reader_enter_cs() { + pthread_mutex_lock(&state_check_mutex); + n_r++; + pthread_mutex_unlock(&state_check_mutex); +} + +static void +reader_leaves_cs() { + pthread_mutex_lock(&state_check_mutex); + n_r--; + pthread_mutex_unlock(&state_check_mutex); +} + + +static void +writer_enter_cs() { + n_w++; +} + +static void +writer_leaves_cs() { + n_w--; +} + +void* +read_thread_fn(void* arg) { + while (1) { + pthread_rwlock_rdlock(&rw_lock); + + reader_enter_cs(); + execute_cs(); + reader_leaves_cs(); + + pthread_rwlock_unlock(&rw_lock); + } +} + +void* +write_thread_fn(void* arg) { + + while (1) { + pthread_rwlock_wrlock(&rw_lock); + writer_enter_cs(); + execute_cs(); + writer_leaves_cs(); + pthread_rwlock_unlock(&rw_lock); + } +} + +int +main(int argc, char* argv[]) { + + static pthread_t th1, th2, th3, th4, th5, th6; + pthread_rwlock_init(&rw_lock, NULL); + pthread_mutex_init(&state_check_mutex, NULL); + pthread_create(&th1, NULL, read_thread_fn, NULL); + pthread_create(&th2, NULL, read_thread_fn, NULL); + pthread_create(&th3, NULL, read_thread_fn, NULL); + pthread_create(&th4, NULL, write_thread_fn, NULL); + pthread_create(&th5, NULL, write_thread_fn, NULL); + pthread_create(&th6, NULL, write_thread_fn, NULL); + pthread_exit(0); + return 0; +} \ No newline at end of file