From 5fd2a3da76229d55308bc050948e8b0248cbc214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Tue, 19 Nov 2019 00:00:00 +0000 Subject: [PATCH] pthread_mutex: move in from cpp-cheat --- README.adoc | 24 +++++++++++++++- path_properties.py | 3 ++ userland/posix/pthread_mutex.c | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 userland/posix/pthread_mutex.c diff --git a/README.adoc b/README.adoc index f47d261..d213fd9 100644 --- a/README.adoc +++ b/README.adoc @@ -13674,6 +13674,11 @@ time ./std_atomic.out 4 100000000 time ./mutex.out 4 100000000 .... +Related examples: + +* POSIX <> +* C11 link:userland/c/atomic.c[] documented at <> + Bibliography: * https://stackoverflow.com/questions/31978324/what-exactly-is-stdatomic/58904448#58904448 "What exactly is std::atomic?" @@ -13754,6 +13759,23 @@ This was for a looong time the only "portable" multithreading alternative, until * link:userland/posix/pthread_deadlock.c[] * link:userland/posix/pthread_self.c[] +[[pthread-mutex]] +===== pthread_mutex + +link:userland/posix/pthread_count.c[] exemplifies the functions: + +* `pthread_mutex_lock` +* pthread_mutex_unlock + +That example that the same interface as: <>. +There are no non-locking atomic types or atomic primitives in POSIX: http://stackoverflow.com/questions/1130018/unix-portable-atomic-operations + +`pthread_mutex_lock` and `pthread_mutex_unlock` and many other pthread functions already enforce cross thread memory synchronization: + +* https://stackoverflow.com/questions/78172/using-c-pthreads-do-shared-variables-need-to-be-volatile/58935671#58935671 +* https://stackoverflow.com/questions/3208060/does-guarding-a-variable-with-a-pthread-mutex-guarantee-its-also-not-cached +* https://stackoverflow.com/questions/24137964/does-pthread-mutex-lock-contains-memory-fence-instruction + ==== sysconf https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html @@ -13937,7 +13959,7 @@ It is also possible to the algorithm tests normally from emulators in < +#include +#include +#include +#include + +unsigned long long niters; +unsigned long long global = 0; +pthread_mutex_t main_thread_mutex = PTHREAD_MUTEX_INITIALIZER; + +void* main_thread(void *arg) { + (void)arg; + unsigned long long i; + for (i = 0; i < niters; ++i) { + pthread_mutex_lock(&main_thread_mutex); + global++; + pthread_mutex_unlock(&main_thread_mutex); + } + return NULL; +} + +int main(int argc, char **argv) { + pthread_t *threads; + unsigned long long i, nthreads; + + /* CLI arguments. */ + if (argc > 1) { + nthreads = strtoull(argv[1], NULL, 0); + } else { + nthreads = 2; + } + if (argc > 2) { + niters = strtoull(argv[2], NULL, 0); + } else { + niters = 10; + } + threads = malloc(sizeof(pthread_t) * nthreads); + + /* Action */ + for (i = 0; i < nthreads; ++i) + pthread_create(&threads[i], NULL, main_thread, NULL); + for (i = 0; i < nthreads; ++i) + pthread_join(threads[i], NULL); + assert(global == nthreads * niters); + + /* Cleanup. */ + free(threads); + return EXIT_SUCCESS; +}