pthreads_cross.c
Go to the documentation of this file.
1 
23 #include "common/pthreads_cross.h"
24 
25 #ifdef _WIN32
26 
27 typedef struct {
28  SRWLOCK lock;
29  bool exclusive;
30 } pthread_rwlock_t;
31 
32 int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
33 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
34 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
35 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
36 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
37 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
38 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
39 
40 int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
41 {
42  (void) attr;
43 
44  if (thread == NULL || start_routine == NULL)
45  return 1;
46 
47 #pragma GCC diagnostic push
48 #pragma GCC diagnostic ignored "-Wcast-function-type"
49  *thread = (HANDLE) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
50 #pragma GCC diagnostic pop
51  if (*thread == NULL)
52  return 1;
53  return 0;
54 }
55 
56 int pthread_join(pthread_t thread, void **value_ptr)
57 {
58  (void)value_ptr;
59  WaitForSingleObject(thread, INFINITE);
60  CloseHandle(thread);
61  return 0;
62 }
63 
64 int pthread_detach(pthread_t thread)
65 {
66  CloseHandle(thread);
67  return 0;
68 }
69 
70 int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
71 {
72  (void)attr;
73 
74  if (mutex == NULL)
75  return 1;
76 
77  InitializeCriticalSection(mutex);
78  return 0;
79 }
80 
81 int pthread_mutex_destroy(pthread_mutex_t *mutex)
82 {
83  if (mutex == NULL)
84  return 1;
85  DeleteCriticalSection(mutex);
86  return 0;
87 }
88 
89 int pthread_mutex_lock(pthread_mutex_t *mutex)
90 {
91  if (mutex == NULL)
92  return 1;
93  EnterCriticalSection(mutex);
94  return 0;
95 }
96 
97 int pthread_mutex_unlock(pthread_mutex_t *mutex)
98 {
99  if (mutex == NULL)
100  return 1;
101  LeaveCriticalSection(mutex);
102  return 0;
103 }
104 
105 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr)
106 {
107  (void)attr;
108  if (cond == NULL)
109  return 1;
110  InitializeConditionVariable(cond);
111  return 0;
112 }
113 
114 int pthread_cond_destroy(pthread_cond_t *cond)
115 {
116  /* Windows does not have a destroy for conditionals */
117  (void)cond;
118  return 0;
119 }
120 
121 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
122 {
123  if (cond == NULL || mutex == NULL)
124  return 1;
125  return pthread_cond_timedwait(cond, mutex, NULL);
126 }
127 
128 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
129  const struct timespec *abstime)
130 {
131  if (cond == NULL || mutex == NULL)
132  return 1;
133  if (!SleepConditionVariableCS(cond, mutex, timespec_to_ms(abstime)))
134  return 1;
135  return 0;
136 }
137 
138 int pthread_cond_signal(pthread_cond_t *cond)
139 {
140  if (cond == NULL)
141  return 1;
142  WakeConditionVariable(cond);
143  return 0;
144 }
145 
146 int pthread_cond_broadcast(pthread_cond_t *cond)
147 {
148  if (cond == NULL)
149  return 1;
150  WakeAllConditionVariable(cond);
151  return 0;
152 }
153 
154 int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
155 {
156  (void)attr;
157  if (rwlock == NULL)
158  return 1;
159  InitializeSRWLock(&(rwlock->lock));
160  rwlock->exclusive = false;
161  return 0;
162 }
163 
164 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
165 {
166  (void)rwlock;
167  return 0;
168 }
169 
170 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
171 {
172  if (rwlock == NULL)
173  return 1;
174  AcquireSRWLockShared(&(rwlock->lock));
175  return 0;
176 }
177 
178 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
179 {
180  if (rwlock == NULL)
181  return 1;
182  return !TryAcquireSRWLockShared(&(rwlock->lock));
183 }
184 
185 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
186 {
187  if (rwlock == NULL)
188  return 1;
189  AcquireSRWLockExclusive(&(rwlock->lock));
190  rwlock->exclusive = true;
191  return 0;
192 }
193 
194 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
195 {
196  BOOLEAN ret;
197 
198  if (rwlock == NULL)
199  return 1;
200 
201  ret = TryAcquireSRWLockExclusive(&(rwlock->lock));
202  if (ret)
203  rwlock->exclusive = true;
204  return ret;
205 }
206 
207 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
208 {
209  if (rwlock == NULL)
210  return 1;
211 
212  if (rwlock->exclusive) {
213  rwlock->exclusive = false;
214  ReleaseSRWLockExclusive(&(rwlock->lock));
215  } else {
216  ReleaseSRWLockShared(&(rwlock->lock));
217  }
218  return 0;
219 }
220 
221 int sched_yield() {
222  return (int)SwitchToThread();
223 }
224 
225 void ms_to_timespec(struct timespec *ts, unsigned int ms)
226 {
227  if (ts == NULL)
228  return;
229  ts->tv_sec = (ms / 1000) + time(NULL);
230  ts->tv_nsec = (ms % 1000) * 1000000;
231 }
232 
233 unsigned int timespec_to_ms(const struct timespec *abstime)
234 {
235  if (abstime == NULL)
236  return INFINITE;
237 
238  return ((abstime->tv_sec - time(NULL)) * 1000) + (abstime->tv_nsec / 1000000);
239 }
240 
241 unsigned int pcthread_get_num_procs()
242 {
243  SYSTEM_INFO sysinfo;
244 
245  GetSystemInfo(&sysinfo);
246  return sysinfo.dwNumberOfProcessors;
247 }
248 
249 #else
250 
251 #include <unistd.h>
253 {
254  return (unsigned int)sysconf(_SC_NPROCESSORS_ONLN);
255 }
256 #endif
ms_to_timespec
void ms_to_timespec(struct timespec *ts, unsigned int ms)
timespec_to_ms
unsigned int timespec_to_ms(const struct timespec *abstime)
pcthread_get_num_procs
unsigned int pcthread_get_num_procs()
Definition: pthreads_cross.c:252
pthreads_cross.h


apriltag
Author(s): Edwin Olson , Max Krogius
autogenerated on Sun Apr 20 2025 02:08:19