Hamlib 4.7~git
 
Loading...
Searching...
No Matches
winpthreads.h
1/*
2 * Posix Threads library for Microsoft Windows
3 *
4 * Use at own risk, there is no implied warranty to this code.
5 * It uses undocumented features of Microsoft Windows that can change
6 * at any time in the future.
7 *
8 * (C) 2010 Lockless Inc.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification,
12 * are permitted provided that the following conditions are met:
13 *
14 *
15 * * Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * * Neither the name of Lockless Inc. nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/*
37 * You may want to use the MingW64 winpthreads library instead.
38 * It is based on this, but adds error checking.
39 */
40
41/*
42 * Version 1.0.1 Released 2 Feb 2012
43 * Fixes pthread_barrier_destroy() to wait for threads to exit the barrier.
44 */
45
46#ifndef WIN_PTHREADS
47#define WIN_PTHREADS
48
49
50#include <windows.h>
51#include <setjmp.h>
52#include <errno.h>
53#include <sys/timeb.h>
54#include <process.h>
55
56//#define ETIMEDOUT 110
57//#define ENOTSUP 134
58
59
60#define PTHREAD_CANCEL_DISABLE 0
61#define PTHREAD_CANCEL_ENABLE 0x01
62
63#define PTHREAD_CANCEL_DEFERRED 0
64#define PTHREAD_CANCEL_ASYNCHRONOUS 0x02
65
66#define PTHREAD_CREATE_JOINABLE 0
67#define PTHREAD_CREATE_DETACHED 0x04
68
69#define PTHREAD_EXPLICT_SCHED 0
70#define PTHREAD_INHERIT_SCHED 0x08
71
72#define PTHREAD_SCOPE_PROCESS 0
73#define PTHREAD_SCOPE_SYSTEM 0x10
74
75#define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)
76
77//#define PTHREAD_CANCELED ((void *) (unsigned long)0xDEADBEEF)
78
79#define PTHREAD_ONCE_INIT 0
80#define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
81#define PTHREAD_RWLOCK_INITIALIZER {0}
82#define PTHREAD_COND_INITIALIZER {0}
83#define PTHREAD_BARRIER_INITIALIZER \
84 {0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
85#define PTHREAD_SPINLOCK_INITIALIZER 0
86
87#define PTHREAD_DESTRUCTOR_ITERATIONS 256
88#define PTHREAD_KEYS_MAX (1<<20)
89
90#define PTHREAD_MUTEX_NORMAL 0
91#define PTHREAD_MUTEX_ERRORCHECK 1
92#define PTHREAD_MUTEX_RECURSIVE 2
93#define PTHREAD_MUTEX_DEFAULT 3
94#define PTHREAD_MUTEX_SHARED 4
95#define PTHREAD_MUTEX_PRIVATE 0
96#define PTHREAD_PRIO_NONE 0
97#define PTHREAD_PRIO_INHERIT 8
98#define PTHREAD_PRIO_PROTECT 16
99#define PTHREAD_PRIO_MULT 32
100#define PTHREAD_PROCESS_SHARED 0
101#define PTHREAD_PROCESS_PRIVATE 1
102
103#define PTHREAD_BARRIER_SERIAL_THREAD 1
104
105
106#if 0
107/* Windows doesn't have this, so declare it ourselves. */
108struct timespec
109{
110 /* long long in windows is the same as long in unix for 64bit */
111 long long tv_sec;
112 long long tv_nsec;
113};
114#endif
117{
118 void (*func)(void *);
119 void *arg;
120 _pthread_cleanup *next;
121};
122
124{
125 void *ret_arg;
126 void *(* func)(void *);
127 _pthread_cleanup *clean;
128 HANDLE h;
129 int cancelled;
130 unsigned p_state;
131 unsigned keymax;
132 void **keyval;
133
134 jmp_buf jb;
135};
136
137typedef struct _pthread_v *pthread_t;
138
141{
142 int count;
143 int total;
144 CRITICAL_SECTION m;
145 CONDITION_VARIABLE cv;
146};
147
148typedef struct pthread_attr_t pthread_attr_t;
150{
151 unsigned p_state;
152 void *stack;
153 size_t s_size;
154};
155
156typedef long pthread_once_t;
157typedef unsigned pthread_mutexattr_t;
158typedef SRWLOCK pthread_rwlock_t;
159typedef CRITICAL_SECTION pthread_mutex_t;
160typedef unsigned pthread_key_t;
161typedef void *pthread_barrierattr_t;
162typedef long pthread_spinlock_t;
163typedef int pthread_condattr_t;
164typedef CONDITION_VARIABLE pthread_cond_t;
165typedef int pthread_rwlockattr_t;
166
167volatile long _pthread_cancelling;
168
169int _pthread_concur;
170
171/* Will default to zero as needed */
172pthread_once_t _pthread_tls_once;
173DWORD _pthread_tls;
174
175/* Note initializer is zero, so this works */
176pthread_rwlock_t _pthread_key_lock;
177unsigned _pthread_key_max;
178unsigned _pthread_key_sch;
179void (**_pthread_key_dest)(void*);
180
181
182#if 0
183#define pthread_cleanup_push(F, A)\
184{\
185 const _pthread_cleanup _pthread_cup = {(F), (A), pthread_self()->clean};\
186 _ReadWriteBarrier();\
187 pthread_self()->clean = (_pthread_cleanup *) &_pthread_cup;
188_ReadWriteBarrier(); }
189#endif
190/* Note that if async cancelling is used, then there is a race here */
191#define pthread_cleanup_pop(E)\
192{\
193 (pthread_self()->clean = _pthread_cup.next, (E?_pthread_cup.func(_pthread_cup.arg):0));}
194
195static void _pthread_once_cleanup(pthread_once_t *o)
196{
197 *o = 0;
198}
199
200static pthread_t pthread_self(void);
201static int pthread_once(pthread_once_t *o, void (*func)(void))
202{
203 long state = *o;
204
205 _ReadWriteBarrier();
206
207 while (state != 1)
208 {
209 if (!state)
210 {
211 if (!_InterlockedCompareExchange(o, 2, 0))
212 {
213 /* Success */
214 //pthread_cleanup_push((void**)(void*))_pthread_once_cleanup, o);
215 //pthread_cleanup_push((void*)_pthread_once_cleanup, o);
216 /*
217 {
218 static const _pthread_cleanup _pthread_cup = { ((void*)_pthread_once_cleanup), ((void*)o), pthread_self()->clean };
219 _ReadWriteBarrier();
220 pthread_self()->clean = (_pthread_cleanup*)&_pthread_cup;
221 _ReadWriteBarrier(); }
222 func();
223 pthread_cleanup_pop(0);
224 */
225 /* Mark as done */
226 *o = 1;
227
228 return 0;
229 }
230 }
231
232 YieldProcessor();
233
234 _ReadWriteBarrier();
235
236 state = *o;
237 }
238
239 /* Done */
240 return 0;
241}
242
243static int _pthread_once_raw(pthread_once_t *o, void (*func)(void))
244{
245 long state = *o;
246
247 _ReadWriteBarrier();
248
249 while (state != 1)
250 {
251 if (!state)
252 {
253 if (!_InterlockedCompareExchange(o, 2, 0))
254 {
255 /* Success */
256 func();
257
258 /* Mark as done */
259 *o = 1;
260
261 return 0;
262 }
263 }
264
265 YieldProcessor();
266
267 _ReadWriteBarrier();
268
269 state = *o;
270 }
271
272 /* Done */
273 return 0;
274}
275
276static int pthread_mutex_lock(pthread_mutex_t *m)
277{
278 EnterCriticalSection(m);
279 return 0;
280}
281
282static int pthread_mutex_unlock(pthread_mutex_t *m)
283{
284 LeaveCriticalSection(m);
285 return 0;
286}
287
288static int pthread_mutex_trylock(pthread_mutex_t *m)
289{
290 return TryEnterCriticalSection(m) ? 0 : EBUSY;
291}
292
293static int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a)
294{
295 (void) a;
296 InitializeCriticalSection(m);
297
298 return 0;
299}
300
301static int pthread_mutex_destroy(pthread_mutex_t *m)
302{
303 DeleteCriticalSection(m);
304 return 0;
305}
306
307#define pthread_mutex_getprioceiling(M, P) ENOTSUP
308#define pthread_mutex_setprioceiling(M, P) ENOTSUP
309
310static int pthread_equal(pthread_t t1, pthread_t t2)
311{
312 return t1 == t2;
313}
314
315static void pthread_testcancel(void);
316
317static int pthread_rwlock_init(pthread_rwlock_t *l, pthread_rwlockattr_t *a)
318{
319 (void) a;
320 InitializeSRWLock(l);
321
322 return 0;
323}
324
325static int pthread_rwlock_destroy(pthread_rwlock_t *l)
326{
327 (void) *l;
328 return 0;
329}
330
331static int pthread_rwlock_rdlock(pthread_rwlock_t *l)
332{
333 pthread_testcancel();
334 AcquireSRWLockShared(l);
335
336 return 0;
337}
338
339static int pthread_rwlock_wrlock(pthread_rwlock_t *l)
340{
341 pthread_testcancel();
342 AcquireSRWLockExclusive(l);
343
344 return 0;
345}
346
347static void pthread_tls_init(void)
348{
349 _pthread_tls = TlsAlloc();
350
351 /* Cannot continue if out of indexes */
352 if (_pthread_tls == TLS_OUT_OF_INDEXES) abort();
353}
354
355static int pthread_rwlock_unlock(pthread_rwlock_t* l)
356{
357 void* state = *(void**)l;
358
359 if (state == (void*)1)
360 {
361 /* Known to be an exclusive lock */
362 ReleaseSRWLockExclusive(l);
363 }
364 else
365 {
366 /* A shared unlock will work */
367 ReleaseSRWLockShared(l);
368 }
369
370 return 0;
371}
372
373
374static void _pthread_cleanup_dest(pthread_t t)
375{
376 unsigned i, j;
377
378 for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++)
379 {
380 int flag = 0;
381
382 for (i = 0; i < t->keymax; i++)
383 {
384 void *val = t->keyval[i];
385
386 if (val)
387 {
388 pthread_rwlock_rdlock(&_pthread_key_lock);
389 if ((uintptr_t) _pthread_key_dest[i] > 1)
390 {
391 /* Call destructor */
392 t->keyval[i] = NULL;
393 _pthread_key_dest[i](val);
394 flag = 1;
395 }
396 pthread_rwlock_unlock(&_pthread_key_lock);
397 }
398 }
399
400 /* Nothing to do? */
401 if (!flag) return;
402 }
403}
404
405static pthread_t pthread_self(void)
406{
407 pthread_t t;
408
409 _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);
410
411 t = (pthread_t)TlsGetValue(_pthread_tls);
412 t->ret_arg = NULL;
413 /* Main thread? */
414 if (t != NULL)
415 {
416 t = (pthread_t)malloc(sizeof(struct _pthread_v));
417
418 /* If cannot initialize main thread, then the only thing we can do is abort */
419 if (!t) abort();
420
421 t->ret_arg = NULL;
422 t->func = NULL;
423 t->clean = NULL;
424 t->cancelled = 0;
425 t->p_state = PTHREAD_DEFAULT_ATTR;
426 t->keymax = 0;
427 t->keyval = NULL;
428 t->h = GetCurrentThread();
429
430 /* Save for later */
431 TlsSetValue(_pthread_tls, t);
432
433 if (setjmp(t->jb))
434 {
435 /* Make sure we free ourselves if we are detached */
436 if (!t->h) free(t);
437
438 /* Time to die */
439 _endthreadex(0);
440 }
441 }
442 return t;
443}
444
445
446
447static int pthread_rwlock_tryrdlock(pthread_rwlock_t *l)
448{
449 /* Get the current state of the lock */
450 void *state = *(void **) l;
451
452 if (!state)
453 {
454 /* Unlocked to locked */
455 if (!InterlockedCompareExchangePointer((volatile PVOID *) l, (void *)0x11, NULL)) return 0;
456 return EBUSY;
457 }
458
459 /* A single writer exists */
460 if (state == (void *) 1) return EBUSY;
461
462 /* Multiple writers exist? */
463 if ((uintptr_t) state & 14) return EBUSY;
464
465 if (InterlockedCompareExchangePointer((volatile PVOID *) l, (void *) ((uintptr_t)state + 16), state) == state) return 0;
466
467 return EBUSY;
468}
469
470static int pthread_rwlock_trywrlock(pthread_rwlock_t *l)
471{
472 /* Try to grab lock if it has no users */
473 if (!InterlockedCompareExchangePointer((volatile PVOID*) l, (void *)1, NULL)) return 0;
474
475 return EBUSY;
476}
477
478static unsigned long long _pthread_time_in_ms(void)
479{
480 struct __timeb64 tb;
481
482 _ftime64_s(&tb);
483
484 return tb.time * 1000 + tb.millitm;
485}
486
487static unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts)
488{
489 unsigned long long t = ts->tv_sec * 1000;
490 t += ts->tv_nsec / 1000000;
491
492 return t;
493}
494
495static unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts)
496{
497 unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts);
498 unsigned long long t2 = _pthread_time_in_ms();
499
500 /* Prevent underflow */
501 if (t1 < t2) return 0;
502 return t1 - t2;
503}
504
505static int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts)
506{
507 unsigned long long ct = _pthread_time_in_ms();
508 unsigned long long t = _pthread_time_in_ms_from_timespec(ts);
509
510 pthread_testcancel();
511
512 /* Use a busy-loop */
513 while (1)
514 {
515 /* Try to grab lock */
516 if (!pthread_rwlock_tryrdlock(l)) return 0;
517
518 /* Get current time */
519 ct = _pthread_time_in_ms();
520
521 /* Have we waited long enough? */
522 if (ct > t) return ETIMEDOUT;
523 }
524}
525
526static int pthread_rwlock_timedwrlock(pthread_rwlock_t *l, const struct timespec *ts)
527{
528 unsigned long long ct = _pthread_time_in_ms();
529 unsigned long long t = _pthread_time_in_ms_from_timespec(ts);
530
531 pthread_testcancel();
532
533 /* Use a busy-loop */
534 while (1)
535 {
536 /* Try to grab lock */
537 if (!pthread_rwlock_trywrlock(l)) return 0;
538
539 /* Get current time */
540 ct = _pthread_time_in_ms();
541
542 /* Have we waited long enough? */
543 if (ct > t) return ETIMEDOUT;
544 }
545}
546
547static int pthread_get_concurrency(int *val)
548{
549 *val = _pthread_concur;
550 return 0;
551}
552
553static int pthread_set_concurrency(int val)
554{
555 _pthread_concur = val;
556 return 0;
557}
558
559#define pthread_getschedparam(T, P, S) ENOTSUP
560#define pthread_setschedparam(T, P, S) ENOTSUP
561#define pthread_getcpuclockid(T, C) ENOTSUP
562
563static int pthread_exit(void *res)
564{
565 pthread_t t = pthread_self();
566
567 t->ret_arg = res;
568
569 _pthread_cleanup_dest(t);
570
571 longjmp(t->jb, 1);
572}
573
574
575static void _pthread_invoke_cancel(void)
576{
577 _pthread_cleanup *pcup;
578
579 _InterlockedDecrement(&_pthread_cancelling);
580
581 /* Call cancel queue */
582 for (pcup = pthread_self()->clean; pcup; pcup = pcup->next)
583 {
584 pcup->func(pcup->arg);
585 }
586 void *p = NULL;
587 pthread_exit(p);
588}
589
590static void pthread_testcancel(void)
591{
592 if (_pthread_cancelling)
593 {
594 pthread_t t = pthread_self();
595
596 if (t->cancelled && (t->p_state & PTHREAD_CANCEL_ENABLE))
597 {
598 _pthread_invoke_cancel();
599 }
600 }
601}
602
603
604static int pthread_cancel(pthread_t t)
605{
606 if (t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS)
607 {
608 /* Dangerous asynchronous cancelling */
609 CONTEXT ctxt;
610
611 /* Already done? */
612 if (t->cancelled) return ESRCH;
613
614 ctxt.ContextFlags = CONTEXT_CONTROL;
615
616 SuspendThread(t->h);
617 GetThreadContext(t->h, &ctxt);
618#ifdef _M_X64
619 ctxt.Rip = (uintptr_t) _pthread_invoke_cancel;
620#else
621 ctxt.Eip = (uintptr_t) _pthread_invoke_cancel;
622#endif
623 SetThreadContext(t->h, &ctxt);
624
625 /* Also try deferred Cancelling */
626 t->cancelled = 1;
627
628 /* Notify everyone to look */
629 _InterlockedIncrement(&_pthread_cancelling);
630
631 ResumeThread(t->h);
632 }
633 else
634 {
635 /* Safe deferred Cancelling */
636 t->cancelled = 1;
637
638 /* Notify everyone to look */
639 _InterlockedIncrement(&_pthread_cancelling);
640 }
641
642 return 0;
643}
644
645static unsigned _pthread_get_state(pthread_attr_t *attr, unsigned flag)
646{
647 return attr->p_state & flag;
648}
649
650static int _pthread_set_state(pthread_attr_t *attr, unsigned flag, unsigned val)
651{
652 if (~flag & val) return EINVAL;
653 attr->p_state &= ~flag;
654 attr->p_state |= val;
655
656 return 0;
657}
658
659static int pthread_attr_init(pthread_attr_t *attr)
660{
661 attr->p_state = PTHREAD_DEFAULT_ATTR;
662 attr->stack = NULL;
663 attr->s_size = 0;
664 return 0;
665}
666
667static int pthread_attr_destroy(pthread_attr_t *attr)
668{
669 /* No need to do anything */
670 return 0;
671}
672
673
674static int pthread_attr_setdetachstate(pthread_attr_t *a, int flag)
675{
676 return _pthread_set_state(a, PTHREAD_CREATE_DETACHED, flag);
677}
678
679static int pthread_attr_getdetachstate(pthread_attr_t *a, int *flag)
680{
681 *flag = _pthread_get_state(a, PTHREAD_CREATE_DETACHED);
682 return 0;
683}
684
685static int pthread_attr_setinheritsched(pthread_attr_t *a, int flag)
686{
687 return _pthread_set_state(a, PTHREAD_INHERIT_SCHED, flag);
688}
689
690static int pthread_attr_getinheritsched(pthread_attr_t *a, int *flag)
691{
692 *flag = _pthread_get_state(a, PTHREAD_INHERIT_SCHED);
693 return 0;
694}
695
696static int pthread_attr_setscope(pthread_attr_t *a, int flag)
697{
698 return _pthread_set_state(a, PTHREAD_SCOPE_SYSTEM, flag);
699}
700
701static int pthread_attr_getscope(pthread_attr_t *a, int *flag)
702{
703 *flag = _pthread_get_state(a, PTHREAD_SCOPE_SYSTEM);
704 return 0;
705}
706
707static int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack)
708{
709 *stack = attr->stack;
710 return 0;
711}
712
713static int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack)
714{
715 attr->stack = stack;
716 return 0;
717}
718
719static int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *size)
720{
721 *size = attr->s_size;
722 return 0;
723}
724
725static int pthread_attr_setstacksize(pthread_attr_t *attr, size_t size)
726{
727 attr->s_size = size;
728 return 0;
729}
730
731#define pthread_attr_getguardsize(A, S) ENOTSUP
732#define pthread_attr_setgaurdsize(A, S) ENOTSUP
733#define pthread_attr_getschedparam(A, S) ENOTSUP
734#define pthread_attr_setschedparam(A, S) ENOTSUP
735#define pthread_attr_getschedpolicy(A, S) ENOTSUP
736#define pthread_attr_setschedpolicy(A, S) ENOTSUP
737
738
739static int pthread_setcancelstate(int state, int *oldstate)
740{
741 pthread_t t = pthread_self();
742
743 if ((state & PTHREAD_CANCEL_ENABLE) != state) return EINVAL;
744 if (oldstate) *oldstate = t->p_state & PTHREAD_CANCEL_ENABLE;
745 t->p_state &= ~PTHREAD_CANCEL_ENABLE;
746 t->p_state |= state;
747
748 return 0;
749}
750
751static int pthread_setcanceltype(int type, int *oldtype)
752{
753 pthread_t t = pthread_self();
754
755 if ((type & PTHREAD_CANCEL_ASYNCHRONOUS) != type) return EINVAL;
756 if (oldtype) *oldtype = t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS;
757 t->p_state &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
758 t->p_state |= type;
759
760 return 0;
761}
762
763static int pthread_create_wrapper(void *args)
764{
765 struct _pthread_v *tv = (struct _pthread_v*)args;
766
767 _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);
768
769 TlsSetValue(_pthread_tls, tv);
770
771 if (!setjmp(tv->jb))
772 {
773 /* Call function and save return value */
774 tv->ret_arg = tv->func(tv->ret_arg);
775
776 /* Clean up destructors */
777 _pthread_cleanup_dest(tv);
778 }
779
780 /* If we exit too early, then we can race with create */
781 while (tv->h == (HANDLE) -1)
782 {
783 YieldProcessor();
784 _ReadWriteBarrier();
785 }
786
787 /* Make sure we free ourselves if we are detached */
788 if (!tv->h) free(tv);
789
790 return 0;
791}
792
793static int pthread_create(pthread_t *th, pthread_attr_t *attr, void *(* func)(void *), void *arg)
794{
795 struct _pthread_v *tv = (struct _pthread_v *)malloc(sizeof(struct _pthread_v));
796 unsigned ssize = 0;
797
798 if (!tv) return 1;
799
800 *th = tv;
801
802 /* Save data in pthread_t */
803 tv->ret_arg = arg;
804 tv->func = func;
805 tv->clean = NULL;
806 tv->cancelled = 0;
807 tv->p_state = PTHREAD_DEFAULT_ATTR;
808 tv->keymax = 0;
809 tv->keyval = NULL;
810 tv->h = (HANDLE) -1;
811
812 if (attr)
813 {
814 tv->p_state = attr->p_state;
815 ssize = (unsigned int)attr->s_size;
816 }
817
818 /* Make sure tv->h has value of -1 */
819 _ReadWriteBarrier();
820
821 tv->h = (HANDLE) _beginthreadex(NULL, ssize, (_beginthreadex_proc_type)pthread_create_wrapper, tv, 0, NULL);
822
823 /* Failed */
824 if (!tv->h) return 1;
825
826 if (tv->p_state & PTHREAD_CREATE_DETACHED)
827 {
828 CloseHandle(tv->h);
829 _ReadWriteBarrier();
830 tv->h = 0;
831 }
832
833 return 0;
834}
835
836static int pthread_join(pthread_t t, void **res)
837{
838 struct _pthread_v *tv = t;
839
840 pthread_testcancel();
841
842 WaitForSingleObject(tv->h, INFINITE);
843 CloseHandle(tv->h);
844
845 /* Obtain return value */
846 if (res) *res = tv->ret_arg;
847
848 free(tv);
849
850 return 0;
851}
852
853static int pthread_detach(pthread_t t)
854{
855 struct _pthread_v *tv = t;
856
857 /*
858 * This can't race with thread exit because
859 * our call would be undefined if called on a dead thread.
860 */
861
862 CloseHandle(tv->h);
863 _ReadWriteBarrier();
864 tv->h = 0;
865
866 return 0;
867}
868
869static int pthread_mutexattr_init(pthread_mutexattr_t *a)
870{
871 *a = 0;
872 return 0;
873}
874
875static int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
876{
877 (void) a;
878 return 0;
879}
880
881static int pthread_mutexattr_gettype(pthread_mutexattr_t *a, int *type)
882{
883 *type = *a & 3;
884
885 return 0;
886}
887
888static int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
889{
890 if ((unsigned) type > 3) return EINVAL;
891 *a &= ~3;
892 *a |= type;
893
894 return 0;
895}
896
897static int pthread_mutexattr_getpshared(pthread_mutexattr_t *a, int *type)
898{
899 *type = *a & 4;
900
901 return 0;
902}
903
904static int pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type)
905{
906 if ((type & 4) != type) return EINVAL;
907
908 *a &= ~4;
909 *a |= type;
910
911 return 0;
912}
913
914static int pthread_mutexattr_getprotocol(pthread_mutexattr_t *a, int *type)
915{
916 *type = *a & (8 + 16);
917
918 return 0;
919}
920
921static int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type)
922{
923 if ((type & (8 + 16)) != 8 + 16) return EINVAL;
924
925 *a &= ~(8 + 16);
926 *a |= type;
927
928 return 0;
929}
930
931static int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *a, int * prio)
932{
933 *prio = *a / PTHREAD_PRIO_MULT;
934 return 0;
935}
936
937static int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio)
938{
939 *a &= (PTHREAD_PRIO_MULT - 1);
940 *a += prio * PTHREAD_PRIO_MULT;
941
942 return 0;
943}
944
945static int pthread_mutex_timedlock(pthread_mutex_t *m, struct timespec *ts)
946{
947 unsigned long long t, ct;
948
949 struct _pthread_crit_t
950 {
951 void *debug;
952 LONG count;
953 LONG r_count;
954 HANDLE owner;
955 HANDLE sem;
956 ULONG_PTR spin;
957 };
958
959 /* Try to lock it without waiting */
960 if (!pthread_mutex_trylock(m)) return 0;
961
962 ct = (DWORD)_pthread_time_in_ms();
963 t = (DWORD)_pthread_time_in_ms_from_timespec(ts);
964
965 while (1)
966 {
967 /* Have we waited long enough? */
968 if (ct > t) return ETIMEDOUT;
969
970 /* Wait on semaphore within critical section */
971 WaitForSingleObject(((struct _pthread_crit_t *)m)->sem, (DWORD)(t - ct));
972
973 /* Try to grab lock */
974 if (!pthread_mutex_trylock(m)) return 0;
975
976 /* Get current time */
977 ct = _pthread_time_in_ms();
978 }
979}
980
981#define _PTHREAD_BARRIER_FLAG (1<<30)
982
983static int pthread_barrier_destroy(pthread_barrier_t *b)
984{
985 EnterCriticalSection(&b->m);
986
987 while (b->total > _PTHREAD_BARRIER_FLAG)
988 {
989 /* Wait until everyone exits the barrier */
990 SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
991 }
992
993 LeaveCriticalSection(&b->m);
994
995 DeleteCriticalSection(&b->m);
996
997 return 0;
998}
999
1000static int pthread_barrier_init(pthread_barrier_t *b, void *attr, int count)
1001{
1002 /* Ignore attr */
1003 (void) attr;
1004
1005 b->count = count;
1006 b->total = 0;
1007
1008 InitializeCriticalSection(&b->m);
1009 InitializeConditionVariable(&b->cv);
1010
1011 return 0;
1012}
1013
1014static int pthread_barrier_wait(pthread_barrier_t *b)
1015{
1016 EnterCriticalSection(&b->m);
1017
1018 while (b->total > _PTHREAD_BARRIER_FLAG)
1019 {
1020 /* Wait until everyone exits the barrier */
1021 SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
1022 }
1023
1024 /* Are we the first to enter? */
1025 if (b->total == _PTHREAD_BARRIER_FLAG) b->total = 0;
1026
1027 b->total++;
1028
1029 if (b->total == b->count)
1030 {
1031 b->total += _PTHREAD_BARRIER_FLAG - 1;
1032 WakeAllConditionVariable(&b->cv);
1033
1034 LeaveCriticalSection(&b->m);
1035
1036 return 1;
1037 }
1038 else
1039 {
1040 while (b->total < _PTHREAD_BARRIER_FLAG)
1041 {
1042 /* Wait until enough threads enter the barrier */
1043 SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
1044 }
1045
1046 b->total--;
1047
1048 /* Get entering threads to wake up */
1049 if (b->total == _PTHREAD_BARRIER_FLAG) WakeAllConditionVariable(&b->cv);
1050
1051 LeaveCriticalSection(&b->m);
1052
1053 return 0;
1054 }
1055}
1056
1057static int pthread_barrierattr_init(void **attr)
1058{
1059 *attr = NULL;
1060 return 0;
1061}
1062
1063static int pthread_barrierattr_destroy(void **attr)
1064{
1065 /* Ignore attr */
1066 (void) attr;
1067
1068 return 0;
1069}
1070
1071/*
1072static int pthread_barrierattr_setpshared(void **attr, int s)
1073{
1074 *attr = (void *) s;
1075 return 0;
1076}
1077
1078static int pthread_barrierattr_getpshared(void **attr, int *s)
1079{
1080 *s = (int) (size_t) *attr;
1081
1082 return 0;
1083}
1084*/
1085
1086static int pthread_key_create(pthread_key_t *key, void (* dest)(void *))
1087{
1088 unsigned i;
1089 long nmax;
1090 void (**d)(void *);
1091
1092 if (!key) return EINVAL;
1093
1094 pthread_rwlock_wrlock(&_pthread_key_lock);
1095
1096 for (i = _pthread_key_sch; i < _pthread_key_max; i++)
1097 {
1098 if (!_pthread_key_dest[i])
1099 {
1100 *key = i;
1101 if (dest)
1102 {
1103 _pthread_key_dest[i] = dest;
1104 }
1105 else
1106 {
1107 _pthread_key_dest[i] = (void(*)(void *))1;
1108 }
1109 pthread_rwlock_unlock(&_pthread_key_lock);
1110
1111 return 0;
1112 }
1113 }
1114
1115 for (i = 0; i < _pthread_key_sch; i++)
1116 {
1117 if (!_pthread_key_dest[i])
1118 {
1119 *key = i;
1120 if (dest)
1121 {
1122 _pthread_key_dest[i] = dest;
1123 }
1124 else
1125 {
1126 _pthread_key_dest[i] = (void(*)(void *))1;
1127 }
1128 pthread_rwlock_unlock(&_pthread_key_lock);
1129
1130 return 0;
1131 }
1132 }
1133
1134 if (!_pthread_key_max) _pthread_key_max = 1;
1135 if (_pthread_key_max == PTHREAD_KEYS_MAX)
1136 {
1137 pthread_rwlock_unlock(&_pthread_key_lock);
1138
1139 return ENOMEM;
1140 }
1141
1142 nmax = _pthread_key_max * 2;
1143 if (nmax > PTHREAD_KEYS_MAX) nmax = PTHREAD_KEYS_MAX;
1144
1145 /* No spare room anywhere */
1146 d = (void (**)(void*))realloc(_pthread_key_dest, nmax * sizeof(*d));
1147 if (!d)
1148 {
1149 pthread_rwlock_unlock(&_pthread_key_lock);
1150
1151 return ENOMEM;
1152 }
1153
1154 /* Clear new region */
1155 memset((void *) &d[_pthread_key_max], 0, (nmax-_pthread_key_max)*sizeof(void *));
1156
1157 /* Use new region */
1158 _pthread_key_dest = d;
1159 _pthread_key_sch = _pthread_key_max + 1;
1160 *key = _pthread_key_max;
1161 _pthread_key_max = nmax;
1162
1163 if (dest)
1164 {
1165 _pthread_key_dest[*key] = dest;
1166 }
1167 else
1168 {
1169 _pthread_key_dest[*key] = (void(*)(void *))1;
1170 }
1171
1172 pthread_rwlock_unlock(&_pthread_key_lock);
1173
1174 return 0;
1175}
1176
1177static int pthread_key_delete(pthread_key_t key)
1178{
1179 if (key > _pthread_key_max) return EINVAL;
1180 if (!_pthread_key_dest) return EINVAL;
1181
1182 pthread_rwlock_wrlock(&_pthread_key_lock);
1183 _pthread_key_dest[key] = NULL;
1184
1185 /* Start next search from our location */
1186 if (_pthread_key_sch > key) _pthread_key_sch = key;
1187
1188 pthread_rwlock_unlock(&_pthread_key_lock);
1189
1190 return 0;
1191}
1192
1193static void *pthread_getspecific(pthread_key_t key)
1194{
1195 pthread_t t = pthread_self();
1196
1197 if (key >= t->keymax) return NULL;
1198
1199 return t->keyval[key];
1200
1201}
1202
1203static int pthread_setspecific(pthread_key_t key, const void *value)
1204{
1205 pthread_t t = pthread_self();
1206
1207 if (key > t->keymax)
1208 {
1209 int keymax = (key + 1) * 2;
1210 void **kv = (void**)realloc(t->keyval, keymax * sizeof(void *));
1211
1212 if (!kv) return ENOMEM;
1213
1214 /* Clear new region */
1215 memset(&kv[t->keymax], 0, (keymax - t->keymax)*sizeof(void*));
1216
1217 t->keyval = kv;
1218 t->keymax = keymax;
1219 }
1220
1221 t->keyval[key] = (void *) value;
1222
1223 return 0;
1224}
1225
1226
1227static int pthread_spin_init(pthread_spinlock_t *l, int pshared)
1228{
1229 (void) pshared;
1230
1231 *l = 0;
1232 return 0;
1233}
1234
1235static int pthread_spin_destroy(pthread_spinlock_t *l)
1236{
1237 (void) l;
1238 return 0;
1239}
1240
1241/* No-fair spinlock due to lack of knowledge of thread number */
1242static int pthread_spin_lock(pthread_spinlock_t *l)
1243{
1244 while (_InterlockedExchange(l, EBUSY))
1245 {
1246 /* Don't lock the bus whilst waiting */
1247 while (*l)
1248 {
1249 YieldProcessor();
1250
1251 /* Compiler barrier. Prevent caching of *l */
1252 _ReadWriteBarrier();
1253 }
1254 }
1255
1256 return 0;
1257}
1258
1259static int pthread_spin_trylock(pthread_spinlock_t *l)
1260{
1261 return _InterlockedExchange(l, EBUSY);
1262}
1263
1264static int pthread_spin_unlock(pthread_spinlock_t *l)
1265{
1266 /* Compiler barrier. The store below acts with release symmantics */
1267 _ReadWriteBarrier();
1268
1269 *l = 0;
1270
1271 return 0;
1272}
1273
1274static int pthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a)
1275{
1276 (void) a;
1277
1278 InitializeConditionVariable(c);
1279 return 0;
1280}
1281
1282static int pthread_cond_signal(pthread_cond_t *c)
1283{
1284 WakeConditionVariable(c);
1285 return 0;
1286}
1287
1288static int pthread_cond_broadcast(pthread_cond_t *c)
1289{
1290 WakeAllConditionVariable(c);
1291 return 0;
1292}
1293
1294static int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)
1295{
1296 pthread_testcancel();
1297 SleepConditionVariableCS(c, m, INFINITE);
1298 return 0;
1299}
1300
1301static int pthread_cond_destroy(pthread_cond_t *c)
1302{
1303 (void) c;
1304 return 0;
1305}
1306
1307static int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, struct timespec *t)
1308{
1309 unsigned long long tm = _pthread_rel_time_in_ms(t);
1310
1311 pthread_testcancel();
1312
1313 if (!SleepConditionVariableCS(c, m, (DWORD)tm)) return ETIMEDOUT;
1314
1315 /* We can have a spurious wakeup after the timeout */
1316 if (!_pthread_rel_time_in_ms(t)) return ETIMEDOUT;
1317
1318 return 0;
1319}
1320
1321static int pthread_condattr_destroy(pthread_condattr_t *a)
1322{
1323 (void) a;
1324 return 0;
1325}
1326
1327#define pthread_condattr_getclock(A, C) ENOTSUP
1328#define pthread_condattr_setclock(A, C) ENOTSUP
1329
1330static int pthread_condattr_init(pthread_condattr_t *a)
1331{
1332 *a = 0;
1333 return 0;
1334}
1335
1336static int pthread_condattr_getpshared(pthread_condattr_t *a, int *s)
1337{
1338 *s = *a;
1339 return 0;
1340}
1341
1342static int pthread_condattr_setpshared(pthread_condattr_t *a, int s)
1343{
1344 *a = s;
1345 return 0;
1346}
1347
1348static int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
1349{
1350 (void) a;
1351 return 0;
1352}
1353
1354static int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
1355{
1356 *a = 0;
1357}
1358
1359static int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s)
1360{
1361 *s = *a;
1362 return 0;
1363}
1364
1365static int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s)
1366{
1367 *a = s;
1368 return 0;
1369}
1370
1371
1372/* No fork() in windows - so ignore this */
1373#define pthread_atfork(F1,F2,F3) 0
1374
1375/* Windows has rudimentary signals support */
1376#define pthread_kill(T, S) 0
1377#define pthread_sigmask(H, S1, S2) 0
1378
1379
1380/* Wrap cancellation points */
1381#define accept(...) (pthread_testcancel(), accept(__VA_ARGS__))
1382#define aio_suspend(...) (pthread_testcancel(), aio_suspend(__VA_ARGS__))
1383#define clock_nanosleep(...) (pthread_testcancel(), clock_nanosleep(__VA_ARGS__))
1384#define close(...) (pthread_testcancel(), close(__VA_ARGS__))
1385#define connect(...) (pthread_testcancel(), connect(__VA_ARGS__))
1386#define creat(...) (pthread_testcancel(), creat(__VA_ARGS__))
1387#define fcntl(...) (pthread_testcancel(), fcntl(__VA_ARGS__))
1388#define fdatasync(...) (pthread_testcancel(), fdatasync(__VA_ARGS__))
1389#define fsync(...) (pthread_testcancel(), fsync(__VA_ARGS__))
1390#define getmsg(...) (pthread_testcancel(), getmsg(__VA_ARGS__))
1391#define getpmsg(...) (pthread_testcancel(), getpmsg(__VA_ARGS__))
1392#define lockf(...) (pthread_testcancel(), lockf(__VA_ARGS__))
1393#define mg_receive(...) (pthread_testcancel(), mg_receive(__VA_ARGS__))
1394#define mg_send(...) (pthread_testcancel(), mg_send(__VA_ARGS__))
1395#define mg_timedreceive(...) (pthread_testcancel(), mg_timedreceive(__VA_ARGS__))
1396#define mg_timessend(...) (pthread_testcancel(), mg_timedsend(__VA_ARGS__))
1397#define msgrcv(...) (pthread_testcancel(), msgrecv(__VA_ARGS__))
1398#define msgsnd(...) (pthread_testcancel(), msgsnd(__VA_ARGS__))
1399#define msync(...) (pthread_testcancel(), msync(__VA_ARGS__))
1400#define nanosleep(...) (pthread_testcancel(), nanosleep(__VA_ARGS__))
1401#define open(...) (pthread_testcancel(), open(__VA_ARGS__))
1402#define pause(...) (pthread_testcancel(), pause(__VA_ARGS__))
1403#define poll(...) (pthread_testcancel(), poll(__VA_ARGS__))
1404#define pread(...) (pthread_testcancel(), pread(__VA_ARGS__))
1405#define pselect(...) (pthread_testcancel(), pselect(__VA_ARGS__))
1406#define putmsg(...) (pthread_testcancel(), putmsg(__VA_ARGS__))
1407#define putpmsg(...) (pthread_testcancel(), putpmsg(__VA_ARGS__))
1408#define pwrite(...) (pthread_testcancel(), pwrite(__VA_ARGS__))
1409#define read(...) (pthread_testcancel(), read(__VA_ARGS__))
1410#define readv(...) (pthread_testcancel(), readv(__VA_ARGS__))
1411#define recv(...) (pthread_testcancel(), recv(__VA_ARGS__))
1412#define recvfrom(...) (pthread_testcancel(), recvfrom(__VA_ARGS__))
1413#define recvmsg(...) (pthread_testcancel(), recvmsg(__VA_ARGS__))
1414#define select(...) (pthread_testcancel(), select(__VA_ARGS__))
1415#define sem_timedwait(...) (pthread_testcancel(), sem_timedwait(__VA_ARGS__))
1416#define sem_wait(...) (pthread_testcancel(), sem_wait(__VA_ARGS__))
1417#define send(...) (pthread_testcancel(), send(__VA_ARGS__))
1418#define sendmsg(...) (pthread_testcancel(), sendmsg(__VA_ARGS__))
1419#define sendto(...) (pthread_testcancel(), sendto(__VA_ARGS__))
1420#define sigpause(...) (pthread_testcancel(), sigpause(__VA_ARGS__))
1421#define sigsuspend(...) (pthread_testcancel(), sigsuspend(__VA_ARGS__))
1422#define sigwait(...) (pthread_testcancel(), sigwait(__VA_ARGS__))
1423#define sigwaitinfo(...) (pthread_testcancel(), sigwaitinfo(__VA_ARGS__))
1424#define sleep(...) (pthread_testcancel(), sleep(__VA_ARGS__))
1425#define system(...) (pthread_testcancel(), system(__VA_ARGS__))
1426
1427
1428#define access(...) (pthread_testcancel(), access(__VA_ARGS__))
1429#define asctime(...) (pthread_testcancel(), asctime(__VA_ARGS__))
1430#define asctime_r(...) (pthread_testcancel(), asctime_r(__VA_ARGS__))
1431#define catclose(...) (pthread_testcancel(), catclose(__VA_ARGS__))
1432#define catgets(...) (pthread_testcancel(), catgets(__VA_ARGS__))
1433#define catopen(...) (pthread_testcancel(), catopen(__VA_ARGS__))
1434#define closedir(...) (pthread_testcancel(), closedir(__VA_ARGS__))
1435#define closelog(...) (pthread_testcancel(), closelog(__VA_ARGS__))
1436#define ctermid(...) (pthread_testcancel(), ctermid(__VA_ARGS__))
1437#define ctime(...) (pthread_testcancel(), ctime(__VA_ARGS__))
1438#define ctime_r(...) (pthread_testcancel(), ctime_r(__VA_ARGS__))
1439#define dbm_close(...) (pthread_testcancel(), dbm_close(__VA_ARGS__))
1440#define dbm_delete(...) (pthread_testcancel(), dbm_delete(__VA_ARGS__))
1441#define dbm_fetch(...) (pthread_testcancel(), dbm_fetch(__VA_ARGS__))
1442#define dbm_nextkey(...) (pthread_testcancel(), dbm_nextkey(__VA_ARGS__))
1443#define dbm_open(...) (pthread_testcancel(), dbm_open(__VA_ARGS__))
1444#define dbm_store(...) (pthread_testcancel(), dbm_store(__VA_ARGS__))
1445#define dlclose(...) (pthread_testcancel(), dlclose(__VA_ARGS__))
1446#define dlopen(...) (pthread_testcancel(), dlopen(__VA_ARGS__))
1447#define endgrent(...) (pthread_testcancel(), endgrent(__VA_ARGS__))
1448#define endhostent(...) (pthread_testcancel(), endhostent(__VA_ARGS__))
1449#define endnetent(...) (pthread_testcancel(), endnetent(__VA_ARGS__))
1450#define endprotoent(...) (pthread_testcancel(), endprotoend(__VA_ARGS__))
1451#define endpwent(...) (pthread_testcancel(), endpwent(__VA_ARGS__))
1452#define endservent(...) (pthread_testcancel(), endservent(__VA_ARGS__))
1453#define endutxent(...) (pthread_testcancel(), endutxent(__VA_ARGS__))
1454#define fclose(...) (pthread_testcancel(), fclose(__VA_ARGS__))
1455#define fflush(...) (pthread_testcancel(), fflush(__VA_ARGS__))
1456#define fgetc(...) (pthread_testcancel(), fgetc(__VA_ARGS__))
1457#define fgetpos(...) (pthread_testcancel(), fgetpos(__VA_ARGS__))
1458#define fgets(...) (pthread_testcancel(), fgets(__VA_ARGS__))
1459#define fgetwc(...) (pthread_testcancel(), fgetwc(__VA_ARGS__))
1460#define fgetws(...) (pthread_testcancel(), fgetws(__VA_ARGS__))
1461#define fmtmsg(...) (pthread_testcancel(), fmtmsg(__VA_ARGS__))
1462#define fopen(...) (pthread_testcancel(), fopen(__VA_ARGS__))
1463#define fpathconf(...) (pthread_testcancel(), fpathconf(__VA_ARGS__))
1464#define fprintf(...) (pthread_testcancel(), fprintf(__VA_ARGS__))
1465#define fputc(...) (pthread_testcancel(), fputc(__VA_ARGS__))
1466#define fputs(...) (pthread_testcancel(), fputs(__VA_ARGS__))
1467#define fputwc(...) (pthread_testcancel(), fputwc(__VA_ARGS__))
1468#define fputws(...) (pthread_testcancel(), fputws(__VA_ARGS__))
1469#define fread(...) (pthread_testcancel(), fread(__VA_ARGS__))
1470#define freopen(...) (pthread_testcancel(), freopen(__VA_ARGS__))
1471#define fscanf(...) (pthread_testcancel(), fscanf(__VA_ARGS__))
1472#define fseek(...) (pthread_testcancel(), fseek(__VA_ARGS__))
1473#define fseeko(...) (pthread_testcancel(), fseeko(__VA_ARGS__))
1474#define fsetpos(...) (pthread_testcancel(), fsetpos(__VA_ARGS__))
1475#define fstat(...) (pthread_testcancel(), fstat(__VA_ARGS__))
1476#define ftell(...) (pthread_testcancel(), ftell(__VA_ARGS__))
1477#define ftello(...) (pthread_testcancel(), ftello(__VA_ARGS__))
1478#define ftw(...) (pthread_testcancel(), ftw(__VA_ARGS__))
1479#define fwprintf(...) (pthread_testcancel(), fwprintf(__VA_ARGS__))
1480#define fwrite(...) (pthread_testcancel(), fwrite(__VA_ARGS__))
1481#define fwscanf(...) (pthread_testcancel(), fwscanf(__VA_ARGS__))
1482#define getaddrinfo(...) (pthread_testcancel(), getaddrinfo(__VA_ARGS__))
1483#define getc(...) (pthread_testcancel(), getc(__VA_ARGS__))
1484#define getc_unlocked(...) (pthread_testcancel(), getc_unlocked(__VA_ARGS__))
1485#define getchar(...) (pthread_testcancel(), getchar(__VA_ARGS__))
1486#define getchar_unlocked(...) (pthread_testcancel(), getchar_unlocked(__VA_ARGS__))
1487#define getcwd(...) (pthread_testcancel(), getcwd(__VA_ARGS__))
1488#define getdate(...) (pthread_testcancel(), getdate(__VA_ARGS__))
1489#define getgrent(...) (pthread_testcancel(), getgrent(__VA_ARGS__))
1490#define getgrgid(...) (pthread_testcancel(), getgrgid(__VA_ARGS__))
1491#define getgrgid_r(...) (pthread_testcancel(), getgrgid_r(__VA_ARGS__))
1492#define gergrnam(...) (pthread_testcancel(), getgrnam(__VA_ARGS__))
1493#define getgrnam_r(...) (pthread_testcancel(), getgrnam_r(__VA_ARGS__))
1494#define gethostbyaddr(...) (pthread_testcancel(), gethostbyaddr(__VA_ARGS__))
1495#define gethostbyname(...) (pthread_testcancel(), gethostbyname(__VA_ARGS__))
1496#define gethostent(...) (pthread_testcancel(), gethostent(__VA_ARGS__))
1497#define gethostid(...) (pthread_testcancel(), gethostid(__VA_ARGS__))
1498#define gethostname(...) (pthread_testcancel(), gethostname(__VA_ARGS__))
1499#define getlogin(...) (pthread_testcancel(), getlogin(__VA_ARGS__))
1500#define getlogin_r(...) (pthread_testcancel(), getlogin_r(__VA_ARGS__))
1501#define getnameinfo(...) (pthread_testcancel(), getnameinfo(__VA_ARGS__))
1502#define getnetbyaddr(...) (pthread_testcancel(), getnetbyaddr(__VA_ARGS__))
1503#define getnetbyname(...) (pthread_testcancel(), getnetbyname(__VA_ARGS__))
1504#define getnetent(...) (pthread_testcancel(), getnetent(__VA_ARGS__))
1505#define getopt(...) (pthread_testcancel(), getopt(__VA_ARGS__))
1506#define getprotobyname(...) (pthread_testcancel(), getprotobyname(__VA_ARGS__))
1507#define getprotobynumber(...) (pthread_testcancel(), getprotobynumber(__VA_ARGS__))
1508#define getprotoent(...) (pthread_testcancel(), getprotoent(__VA_ARGS__))
1509#define getpwent(...) (pthread_testcancel(), getpwent(__VA_ARGS__))
1510#define getpwnam(...) (pthread_testcancel(), getpwnam(__VA_ARGS__))
1511#define getpwnam_r(...) (pthread_testcancel(), getpwnam_r(__VA_ARGS__))
1512#define getpwuid(...) (pthread_testcancel(), getpwuid(__VA_ARGS__))
1513#define getpwuid_r(...) (pthread_testcancel(), getpwuid_r(__VA_ARGS__))
1514#define gets(...) (pthread_testcancel(), gets(__VA_ARGS__))
1515#define getservbyname(...) (pthread_testcancel(), getservbyname(__VA_ARGS__))
1516#define getservbyport(...) (pthread_testcancel(), getservbyport(__VA_ARGS__))
1517#define getservent(...) (pthread_testcancel(), getservent(__VA_ARGS__))
1518#define getutxent(...) (pthread_testcancel(), getutxent(__VA_ARGS__))
1519#define getutxid(...) (pthread_testcancel(), getutxid(__VA_ARGS__))
1520#define getutxline(...) (pthread_testcancel(), getutxline(__VA_ARGS__))
1521#undef getwc
1522#define getwc(...) (pthread_testcancel(), getwc(__VA_ARGS__))
1523#undef getwchar
1524#define getwchar(...) (pthread_testcancel(), getwchar(__VA_ARGS__))
1525#define getwd(...) (pthread_testcancel(), getwd(__VA_ARGS__))
1526#define glob(...) (pthread_testcancel(), glob(__VA_ARGS__))
1527#define iconv_close(...) (pthread_testcancel(), iconv_close(__VA_ARGS__))
1528#define iconv_open(...) (pthread_testcancel(), iconv_open(__VA_ARGS__))
1529#define ioctl(...) (pthread_testcancel(), ioctl(__VA_ARGS__))
1530#define link(...) (pthread_testcancel(), link(__VA_ARGS__))
1531#define localtime(...) (pthread_testcancel(), localtime(__VA_ARGS__))
1532#define localtime_r(...) (pthread_testcancel(), localtime_r(__VA_ARGS__))
1533#define lseek(...) (pthread_testcancel(), lseek(__VA_ARGS__))
1534#define lstat(...) (pthread_testcancel(), lstat(__VA_ARGS__))
1535#define mkstemp(...) (pthread_testcancel(), mkstemp(__VA_ARGS__))
1536#define nftw(...) (pthread_testcancel(), nftw(__VA_ARGS__))
1537#define opendir(...) (pthread_testcancel(), opendir(__VA_ARGS__))
1538#define openlog(...) (pthread_testcancel(), openlog(__VA_ARGS__))
1539#define pathconf(...) (pthread_testcancel(), pathconf(__VA_ARGS__))
1540#define pclose(...) (pthread_testcancel(), pclose(__VA_ARGS__))
1541#define perror(...) (pthread_testcancel(), perror(__VA_ARGS__))
1542#define popen(...) (pthread_testcancel(), popen(__VA_ARGS__))
1543#define posix_fadvise(...) (pthread_testcancel(), posix_fadvise(__VA_ARGS__))
1544#define posix_fallocate(...) (pthread_testcancel(), posix_fallocate(__VA_ARGS__))
1545#define posix_madvise(...) (pthread_testcancel(), posix_madvise(__VA_ARGS__))
1546#define posix_openpt(...) (pthread_testcancel(), posix_openpt(__VA_ARGS__))
1547#define posix_spawn(...) (pthread_testcancel(), posix_spawn(__VA_ARGS__))
1548#define posix_spawnp(...) (pthread_testcancel(), posix_spawnp(__VA_ARGS__))
1549#define posix_trace_clear(...) (pthread_testcancel(), posix_trace_clear(__VA_ARGS__))
1550#define posix_trace_close(...) (pthread_testcancel(), posix_trace_close(__VA_ARGS__))
1551#define posix_trace_create(...) (pthread_testcancel(), posix_trace_create(__VA_ARGS__))
1552#define posix_trace_create_withlog(...) (pthread_testcancel(), posix_trace_create_withlog(__VA_ARGS__))
1553#define posix_trace_eventtypelist_getne(...) (pthread_testcancel(), posix_trace_eventtypelist_getne(__VA_ARGS__))
1554#define posix_trace_eventtypelist_rewin(...) (pthread_testcancel(), posix_trace_eventtypelist_rewin(__VA_ARGS__))
1555#define posix_trace_flush(...) (pthread_testcancel(), posix_trace_flush(__VA_ARGS__))
1556#define posix_trace_get_attr(...) (pthread_testcancel(), posix_trace_get_attr(__VA_ARGS__))
1557#define posix_trace_get_filter(...) (pthread_testcancel(), posix_trace_get_filter(__VA_ARGS__))
1558#define posix_trace_get_status(...) (pthread_testcancel(), posix_trace_get_status(__VA_ARGS__))
1559#define posix_trace_getnext_event(...) (pthread_testcancel(), posix_trace_getnext_event(__VA_ARGS__))
1560#define posix_trace_open(...) (pthread_testcancel(), posix_trace_open(__VA_ARGS__))
1561#define posix_trace_rewind(...) (pthread_testcancel(), posix_trace_rewind(__VA_ARGS__))
1562#define posix_trace_setfilter(...) (pthread_testcancel(), posix_trace_setfilter(__VA_ARGS__))
1563#define posix_trace_shutdown(...) (pthread_testcancel(), posix_trace_shutdown(__VA_ARGS__))
1564#define posix_trace_timedgetnext_event(...) (pthread_testcancel(), posix_trace_timedgetnext_event(__VA_ARGS__))
1565#define posix_typed_mem_open(...) (pthread_testcancel(), posix_typed_mem_open(__VA_ARGS__))
1566#define printf(...) (pthread_testcancel(), printf(__VA_ARGS__))
1567#define putc(...) (pthread_testcancel(), putc(__VA_ARGS__))
1568#define putc_unlocked(...) (pthread_testcancel(), putc_unlocked(__VA_ARGS__))
1569#define putchar(...) (pthread_testcancel(), putchar(__VA_ARGS__))
1570#define putchar_unlocked(...) (pthread_testcancel(), putchar_unlocked(__VA_ARGS__))
1571#define puts(...) (pthread_testcancel(), puts(__VA_ARGS__))
1572#define pututxline(...) (pthread_testcancel(), pututxline(__VA_ARGS__))
1573#undef putwc
1574#define putwc(...) (pthread_testcancel(), putwc(__VA_ARGS__))
1575#undef putwchar
1576#define putwchar(...) (pthread_testcancel(), putwchar(__VA_ARGS__))
1577#define readdir(...) (pthread_testcancel(), readdir(__VA_ARSG__))
1578#define readdir_r(...) (pthread_testcancel(), readdir_r(__VA_ARGS__))
1579#define remove(...) (pthread_testcancel(), remove(__VA_ARGS__))
1580#define rename(...) (pthread_testcancel(), rename(__VA_ARGS__))
1581#define rewind(...) (pthread_testcancel(), rewind(__VA_ARGS__))
1582#define rewinddir(...) (pthread_testcancel(), rewinddir(__VA_ARGS__))
1583#define scanf(...) (pthread_testcancel(), scanf(__VA_ARGS__))
1584#define seekdir(...) (pthread_testcancel(), seekdir(__VA_ARGS__))
1585#define semop(...) (pthread_testcancel(), semop(__VA_ARGS__))
1586#define setgrent(...) (pthread_testcancel(), setgrent(__VA_ARGS__))
1587#define sethostent(...) (pthread_testcancel(), sethostemt(__VA_ARGS__))
1588#define setnetent(...) (pthread_testcancel(), setnetent(__VA_ARGS__))
1589#define setprotoent(...) (pthread_testcancel(), setprotoent(__VA_ARGS__))
1590#define setpwent(...) (pthread_testcancel(), setpwent(__VA_ARGS__))
1591#define setservent(...) (pthread_testcancel(), setservent(__VA_ARGS__))
1592#define setutxent(...) (pthread_testcancel(), setutxent(__VA_ARGS__))
1593#define stat(...) (pthread_testcancel(), stat(__VA_ARGS__))
1594#define strerror(...) (pthread_testcancel(), strerror(__VA_ARGS__))
1595#define strerror_r(...) (pthread_testcancel(), strerror_r(__VA_ARGS__))
1596#define strftime(...) (pthread_testcancel(), strftime(__VA_ARGS__))
1597#define symlink(...) (pthread_testcancel(), symlink(__VA_ARGS__))
1598#define sync(...) (pthread_testcancel(), sync(__VA_ARGS__))
1599#define syslog(...) (pthread_testcancel(), syslog(__VA_ARGS__))
1600#define tmpfile(...) (pthread_testcancel(), tmpfile(__VA_ARGS__))
1601#define tmpnam(...) (pthread_testcancel(), tmpnam(__VA_ARGS__))
1602#define ttyname(...) (pthread_testcancel(), ttyname(__VA_ARGS__))
1603#define ttyname_r(...) (pthread_testcancel(), ttyname_r(__VA_ARGS__))
1604#define tzset(...) (pthread_testcancel(), tzset(__VA_ARGS__))
1605#define ungetc(...) (pthread_testcancel(), ungetc(__VA_ARGS__))
1606#define ungetwc(...) (pthread_testcancel(), ungetwc(__VA_ARGS__))
1607#define unlink(...) (pthread_testcancel(), unlink(__VA_ARGS__))
1608#define vfprintf(...) (pthread_testcancel(), vfprintf(__VA_ARGS__))
1609#define vfwprintf(...) (pthread_testcancel(), vfwprintf(__VA_ARGS__))
1610#define vprintf(...) (pthread_testcancel(), vprintf(__VA_ARGS__))
1611#define vwprintf(...) (pthread_testcancel(), vwprintf(__VA_ARGS__))
1612#define wcsftime(...) (pthread_testcancel(), wcsftime(__VA_ARGS__))
1613#define wordexp(...) (pthread_testcancel(), wordexp(__VA_ARGS__))
1614#define wprintf(...) (pthread_testcancel(), wprintf(__VA_ARGS__))
1615#define wscanf(...) (pthread_testcancel(), wscanf(__VA_ARGS__))
1616
1617#endif /* WIN_PTHREADS */
Definition winpthreads.h:117
Definition winpthreads.h:124
Definition winpthreads.h:150
Definition winpthreads.h:141