3 typedef struct win32_cond { LONG waiters; HANDLE sem; } perl_cond;
4 typedef DWORD perl_key;
5 typedef HANDLE perl_thread;
7 /* XXX Critical Sections used instead of mutexes: lightweight,
8 * but can't be communicated to child processes, and can't get
9 * HANDLE to it for use elsewhere
12 #ifndef DONT_USE_CRITICAL_SECTION
13 typedef CRITICAL_SECTION perl_mutex;
14 #define MUTEX_INIT(m) InitializeCriticalSection(m)
15 #define MUTEX_LOCK(m) EnterCriticalSection(m)
16 #define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
17 #define MUTEX_DESTROY(m) DeleteCriticalSection(m)
19 typedef HANDLE perl_mutex;
21 #define MUTEX_INIT(m) \
23 if ((*(m) = CreateMutex(NULL,FALSE,NULL)) == NULL) \
24 croak("panic: MUTEX_INIT"); \
26 #define MUTEX_LOCK(m) \
28 if (WaitForSingleObject(*(m),INFINITE) == WAIT_FAILED) \
29 croak("panic: MUTEX_LOCK"); \
31 #define MUTEX_UNLOCK(m) \
33 if (ReleaseMutex(*(m)) == 0) \
34 croak("panic: MUTEX_UNLOCK"); \
36 #define MUTEX_DESTROY(m) \
38 if (CloseHandle(*(m)) == 0) \
39 croak("panic: MUTEX_DESTROY"); \
44 /* These macros assume that the mutex associated with the condition
45 * will always be held before COND_{SIGNAL,BROADCAST,WAIT,DESTROY},
46 * so there's no separate mutex protecting access to (c)->waiters
48 #define COND_INIT(c) \
51 (c)->sem = CreateSemaphore(NULL,0,LONG_MAX,NULL); \
52 if ((c)->sem == NULL) \
53 croak("panic: COND_INIT (%ld)",GetLastError()); \
56 #define COND_SIGNAL(c) \
58 if (ReleaseSemaphore((c)->sem,1,NULL) == 0) \
59 croak("panic: COND_SIGNAL (%ld)",GetLastError()); \
62 #define COND_BROADCAST(c) \
64 if ((c)->waiters > 0 && \
65 ReleaseSemaphore((c)->sem,(c)->waiters,NULL) == 0) \
66 croak("panic: COND_BROADCAST (%ld)",GetLastError());\
69 #define COND_WAIT(c, m) \
73 /* Note that there's no race here, since a \
74 * COND_BROADCAST() on another thread will have seen the\
75 * right number of waiters (i.e. including this one) */ \
76 if (WaitForSingleObject((c)->sem,INFINITE)==WAIT_FAILED)\
77 croak("panic: COND_WAIT (%ld)",GetLastError()); \
82 #define COND_DESTROY(c) \
85 if (CloseHandle((c)->sem) == 0) \
86 croak("panic: COND_DESTROY (%ld)",GetLastError()); \
91 if (CloseHandle((t)->self) == 0) { \
92 MUTEX_UNLOCK(&(t)->mutex); \
93 croak("panic: DETACH"); \
97 #define THR ((struct thread *) TlsGetValue(thr_key))
98 #define THREAD_CREATE(t, f) Perl_thread_create(t, f)
99 #define THREAD_POST_CREATE(t) NOOP
100 #define THREAD_RET_TYPE DWORD WINAPI
101 #define THREAD_RET_CAST(p) ((DWORD)(p))
103 typedef THREAD_RET_TYPE thread_func_t(void *);
106 void Perl_alloc_thread_key _((void));
107 int Perl_thread_create _((struct thread *thr, thread_func_t *fn));
108 void Perl_set_thread_self _((struct thread *thr));
111 #define INIT_THREADS NOOP
112 #define ALLOC_THREAD_KEY Perl_alloc_thread_key()
113 #define SET_THREAD_SELF(thr) Perl_set_thread_self(thr)
115 #define JOIN(t, avp) \
117 if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED) \
118 || (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0)) \
119 croak("panic: JOIN"); \
124 if (TlsSetValue(thr_key, (void *) (t)) == 0) \
125 croak("panic: TlsSetValue"); \
128 #define YIELD Sleep(0)
130 #endif /* _WIN32THREAD_H */