From 735a6b4380962bc81246c4ae036354208c682898 Mon Sep 17 00:00:00 2001 From: Tomas Mudrunka Date: Tue, 22 Jun 2021 17:23:46 +0200 Subject: [PATCH] Pthread multi --- c/pthread_multi.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 c/pthread_multi.c diff --git a/c/pthread_multi.c b/c/pthread_multi.c new file mode 100644 index 0000000..95c581c --- /dev/null +++ b/c/pthread_multi.c @@ -0,0 +1,106 @@ +/* + * CFLAGS=-lpthread make pthread_multi + */ + +#include +#include +#include +#include + +#define pthread_mutex_swap(a, b) ({ pthread_mutex_t *s; s = (a); a = (b); b = s; }) + +#define pthread_mutex_lock_two(a,b) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, true, NULL) +#define pthread_mutex_timedlock_two(a,b,tm) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, true, (tm)) +#define pthread_mutex_trylock_two(a,b) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, false, NULL) + +#define pthread_mutex_lock_multi(lcks,cnt) pthread_mutex_timedlock_multi_generic((lcks),(cnt),true,NULL) +#define pthread_mutex_timedlock_multi(lcks,cnt,tm) pthread_mutex_timedlock_multi_generic((lcks),(cnt),true,(tm)) +#define pthread_mutex_trylock_multi(lcks,cnt) pthread_mutex_timedlock_multi_generic((lcks),(cnt),false,NULL) + +/* +//This is first prototype for two mutexes only, it is useful in order to understand how this all works +//Currently it was replaced by macro with the same name +int pthread_mutex_timedlock_two(pthread_mutex_t *a, pthread_mutex_t *b, const struct timespec *restrict abs_timeout) { + int ret; + + while(1) { + //Wait for the first mutex + ret = (abs_timeout==NULL ? pthread_mutex_lock(a) : pthread_mutex_timedlock(a, abs_timeout)); + if(ret) return ret; //Something is fishy about this mutex. Abort! + + //Try to lock the second mutex + ret = pthread_mutex_trylock(b); + if(!ret) return ret; //Locked BOTH Hooray! + + //Unlock first if second failed to prevent deadlocks + pthread_mutex_unlock(a); + + //Swap mutexes, so we will try to block on the second mutex next time: + pthread_mutex_swap(a, b); + //printf("Retry!\n"); + } +} +*/ + +int pthread_mutex_timedlock_multi_generic(pthread_mutex_t **lck, int cnt, bool block, const struct timespec *restrict abs_timeout) { + int ret, locked; + + while(1) { + //Try to lock all mutexes + for(int i = 0; i