pthread_helpers.h
3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* pthread_helpers.h
*
* Created on: 11 sty 2019
* Author: mariuszo
*/
#ifndef PTHREAD_HELPERS_H_
#define PTHREAD_HELPERS_H_
/*
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#include <math.h>
//#include <string.h>
//#include <stdio.h>
#include <stdint.h>
#include <time.h>
*/
#ifndef NS_IN_S
#define NS_IN_S 1000000000
#endif
inline bool semPost(sem_t& sem){
return sem_post(&sem)==0;
}
inline bool semWait(sem_t& sem, const uint64_t& timeoutns=UINT64_MAX){
if (timeoutns==0) {
while(1){
if (sem_trywait(&sem)!=0){
if (errno==EINTR)
continue;
else if (errno==EAGAIN)
errno=ETIMEDOUT;
return false;
}
return true;
}
} else if (timeoutns==UINT64_MAX){
while (1) {
if (sem_wait(&sem)!=0){
if (errno==EINTR)
continue;
return false;
}
return true;
};
} else {
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_nsec+=timeoutns;
time.tv_sec+=(time.tv_nsec/NS_IN_S);
time.tv_nsec%=NS_IN_S;
while (1) {
if (sem_timedwait(&(sem),&time)!=0){
if (errno==EINTR)
continue;
return false;
}
return true;
}
}
}
inline int wrLock(pthread_rwlock_t& lock, const uint64_t& timeoutns=UINT64_MAX){
if (timeoutns==0) {
return pthread_rwlock_trywrlock(&lock);
} else if (timeoutns==UINT64_MAX){
while (1) {
if (pthread_rwlock_wrlock(&lock)==0)
return 0;
};
} else {
int err;
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_nsec+=timeoutns;
time.tv_sec+=(time.tv_nsec/NS_IN_S);
time.tv_nsec%=NS_IN_S;
while (1) {
if ((err=pthread_rwlock_timedwrlock(&lock,&time))==0)
return 0;
else if (err==ETIMEDOUT)
return err;
}
}
}
inline int rdLock(pthread_rwlock_t& lock, const uint64_t& timeoutns=UINT64_MAX){
if (timeoutns==0) {
return pthread_rwlock_tryrdlock(&lock);
} else if (timeoutns==UINT64_MAX){
while (1) {
if (pthread_rwlock_rdlock(&lock)==0)
return 0;
};
} else {
int err;
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_nsec+=timeoutns;
time.tv_sec+=(time.tv_nsec/NS_IN_S);
time.tv_nsec%=NS_IN_S;
while (1) {
if ((err=pthread_rwlock_timedrdlock(&lock,&time))==0)
return 0;
else if (err==ETIMEDOUT)
return err;
}
}
}
inline int rwUnlock(pthread_rwlock_t& lock){
return pthread_rwlock_unlock(&lock);
}
inline int mutexLock(pthread_mutex_t& lock, const uint64_t& timeoutns=UINT64_MAX){
if (timeoutns==0) {
int err;
if ((err=pthread_mutex_trylock(&lock))==EOWNERDEAD)
pthread_mutex_consistent(&lock);
return err;
} else if (timeoutns==UINT64_MAX){
int err;
while (1) {
if ((err=pthread_mutex_lock(&lock))==0)
return 0;
if (err==EOWNERDEAD){
pthread_mutex_consistent(&lock);
return err;
}
};
} else {
int err;
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_nsec+=timeoutns;
time.tv_sec+=(time.tv_nsec/NS_IN_S);
time.tv_nsec%=NS_IN_S;
while (1) {
if ((err=pthread_mutex_timedlock(&lock,&time))==0)
return 0;
else if (err==ETIMEDOUT)
return err;
else if (err==EOWNERDEAD){
pthread_mutex_consistent(&lock);
return err;
}
}
}
}
inline int mutexUnlock(pthread_mutex_t& lock){
return pthread_mutex_unlock(&lock);
}
#endif /* PTHREAD_HELPERS_H_ */