Refaktorace knihovny
[mirrors/Programs.git] / c / pthread_extra / pthread_multi.c
1 #include <pthread_extra.h>
2 #include <time.h>
3 #include <stdio.h>
4 #include <stdbool.h>
5
6 /*
7 //This is first prototype for two mutexes only, it is useful in order to understand how this all works
8 //Currently it was replaced by macro with the same name
9 int pthread_mutex_timedlock_two(pthread_mutex_t *a, pthread_mutex_t *b, const struct timespec *restrict abs_timeout) {
10 int ret;
11
12 while(1) {
13 //Wait for the first mutex
14 ret = (abs_timeout==NULL ? pthread_mutex_lock(a) : pthread_mutex_timedlock(a, abs_timeout));
15 if(ret) return ret; //Something is fishy about this mutex. Abort!
16
17 //Try to lock the second mutex
18 ret = pthread_mutex_trylock(b);
19 if(!ret) return ret; //Locked BOTH Hooray!
20
21 //Unlock first if second failed to prevent deadlocks
22 pthread_mutex_unlock(a);
23
24 //Swap mutexes, so we will try to block on the second mutex next time:
25 pthread_mutex_swap(a, b);
26 //printf("Retry!\n");
27 }
28 }
29 */
30
31 int pthread_mutex_timedlock_multi_generic(pthread_mutex_t **lck, int cnt, bool block, const struct timespec *restrict abs_timeout) {
32 int ret, locked;
33
34 while(1) {
35 //Try to lock all mutexes
36 for(int i = 0; i<cnt; i++) {
37 //Block only on the first one
38 if(block && i==0) {
39 ret = (abs_timeout==NULL ? pthread_mutex_lock(lck[i]) : pthread_mutex_timedlock(lck[i], abs_timeout));
40 if(ret) return ret; //Something went wrong
41 continue;
42 }
43 //Then try if we can lock the rest
44 ret = pthread_mutex_trylock(lck[i]);
45 if(ret) {
46 //Cannot lock this one
47 locked = i;
48 printf("Cannot lock #%d!\n", i);
49 break;
50 }
51 locked = i;
52 }
53
54 //Check if we managed to lock all locks
55 if(locked == cnt) return 0;
56
57 //Unlock all mutexes that we managed to lock so far
58 for(int i = 0;i<locked;i++) {
59 printf("Unlocking #%d\n", i);
60 pthread_mutex_unlock(lck[i]);
61 }
62 if(!block) return ret; //We do not want to block, just trying
63
64 //Try to block on locked mutex in next round
65 pthread_mutex_swap(lck[0],lck[locked]);
66 }
67 }
This page took 0.29198 seconds and 4 git commands to generate.