/
thr_windows.h
143 lines (121 loc) · 3.66 KB
/
thr_windows.h
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
/* thread.h
* Copyright (C) 2001-2003, Parrot Foundation.
* SVN Info
* $Id$
* Overview:
* This is the api header for the windows thread primitives
* Data Structure and Algorithms:
* History:
* Notes:
* References:
*/
#ifndef PARROT_THR_WINDOWS_H_GUARD
#define PARROT_THR_WINDOWS_H_GUARD
# undef CONST
# include <windows.h>
# undef FASTCALL
# include <process.h>
# include <limits.h>
# define PARROT_SYNC_PRIMITIVES_DEFINED
typedef CRITICAL_SECTION Parrot_mutex;
typedef struct Windows_cond
{
HANDLE m_hSema;
LONG m_lWaiters;
} Parrot_cond;
typedef HANDLE Parrot_thread;
# define MUTEX_INIT(m) InitializeCriticalSection((PCRITICAL_SECTION)&(m))
# define MUTEX_DESTROY(m) DeleteCriticalSection((PCRITICAL_SECTION)&(m))
# define COND_INIT(c) \
do { \
(c).m_hSema = CreateSemaphore(NULL, 0, LONG_MAX, NULL); \
(c).m_lWaiters = 0; \
} while (0)
# define COND_DESTROY(c) CloseHandle((c).m_hSema)
# define LOCK(m) EnterCriticalSection((PCRITICAL_SECTION)&(m))
# define UNLOCK(m) LeaveCriticalSection((PCRITICAL_SECTION)&(m))
# define COND_WAIT(c, m) \
do { \
++(c).m_lWaiters; \
UNLOCK(m); \
WaitForSingleObject((c).m_hSema, INFINITE); \
LOCK(m); \
--(c).m_lWaiters; \
} while (0)
# define COND_TIMED_WAIT(c, m, t) \
do { \
FLOATVAL now; \
time_t sec; \
LONG nsec; \
DWORD diff; \
now = Parrot_floatval_time(); \
sec = (time_t)now; \
nsec = (LONG)((now - sec)*1000.0f)*1000000L; \
if ((t)->tv_sec > sec || ((t)->tv_sec == sec && (t)->tv_nsec > nsec)) \
{ \
++(c).m_lWaiters; \
UNLOCK(m); \
diff = (DWORD)(((t)->tv_sec - sec)*1000L + ((t)->tv_nsec - nsec)/1000000L); \
WaitForSingleObject((c).m_hSema, diff); \
LOCK(m); \
--(c).m_lWaiters; \
} \
} while (0)
# define COND_SIGNAL(c) \
do { \
if ((c).m_lWaiters > 0) \
ReleaseSemaphore((c).m_hSema, 1, NULL); \
} while (0)
# define COND_BROADCAST(c) \
do { \
if ((c).m_lWaiters > 0) \
ReleaseSemaphore((c).m_hSema, (c).m_lWaiters, NULL); \
} while (0)
# define JOIN(t, ret) \
do { \
WaitForSingleObject((t), INFINITE); \
GetExitCodeThread((t), (LPDWORD)&(ret)); \
CloseHandle(t); \
} while (0)
# define DETACH(t) CloseHandle(t)
/* If the compiler CRT library has a good _beginthreadXX() routine, use it instead of
the Win32 API CreateThread(). _beginthreadXX guards call to the thread start routine
with SEH to implement runtime errors and signal support. Also it frees calloc-ed
per-thread data block at exit */
#ifdef _MCS_VER1
# define THREAD_CREATE_JOINABLE(t, func, arg) \
do { \
unsigned tid; \
(t) = (HANDLE)_beginthreadex(NULL, 0, unsigned (__stdcall * (func)) (void*), \
(void*)(arg), 0, &tid); \
} while (0)
#else
# define THREAD_CREATE_JOINABLE(t, func, arg) \
do { \
DWORD tid; \
(t) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(func), (PVOID)(arg), 0, &tid); \
} while (0)
#endif
# define THREAD_CREATE_DETACHED(t, func, arg) \
do { \
THREAD_CREATE_JOINABLE((t), (func), (arg)); \
DETACH(t); \
} while (0)
# define CLEANUP_PUSH(f, a)
# define CLEANUP_POP(a)
typedef void (*Cleanup_Handler)(void *);
#ifndef _STRUCT_TIMESPEC
# define _STRUCT_TIMESPEC
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#endif /* _STRUCT_TIMESPEC */
# undef CONST
#endif /* PARROT_THR_WINDOWS_H_GUARD */
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/