1: #line 432 "./lpsrc/flx_pthread.pak"
2:
3:
4:
5:
6:
7:
8:
9:
10:
11: typedef HANDLE pthread_mutex_t;
12: typedef void pthread_mutexattr_t;
13: typedef void pthread_condattr_t;
14:
15: struct pthread_cond_t
16: {
17: int waiters_count_;
18:
19:
20: CRITICAL_SECTION waiters_count_lock_;
21:
22:
23: HANDLE sema_;
24:
25:
26:
27: HANDLE waiters_done_;
28:
29:
30:
31:
32: size_t was_broadcast_;
33:
34:
35: };
36:
37:
38:
39:
40:
41:
42:
43:
44: int PTHREAD_EXTERN pthread_mutex_init (pthread_mutex_t*, const pthread_mutexattr_t*);
45: int PTHREAD_EXTERN pthread_mutex_lock(pthread_mutex_t*);
46: int PTHREAD_EXTERN pthread_mutex_unlock(pthread_mutex_t*);
47: int PTHREAD_EXTERN pthread_mutex_destroy(pthread_mutex_t*);
48:
49: int PTHREAD_EXTERN pthread_cond_init (pthread_cond_t*, const pthread_condattr_t*);
50: int PTHREAD_EXTERN pthread_cond_destroy(pthread_cond_t*);
51: int PTHREAD_EXTERN pthread_cond_wait (pthread_cond_t*, pthread_mutex_t*);
52: int PTHREAD_EXTERN pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, struct timespec const*);
53: int PTHREAD_EXTERN pthread_cond_uswait(pthread_cond_t*, pthread_mutex_t*, unsigned long us);
54: int PTHREAD_EXTERN pthread_cond_signal (pthread_cond_t*);
55: int PTHREAD_EXTERN pthread_cond_broadcast (pthread_cond_t*);
56:
57:
58: typedef HANDLE sem_t;
59:
60: int PTHREAD_EXTERN sem_init(sem_t *sem, int pshared, unsigned int value);
61: int PTHREAD_EXTERN sem_wait(sem_t * sem);
62: int PTHREAD_EXTERN sem_trywait(sem_t * sem);
63: int PTHREAD_EXTERN sem_post(sem_t * sem);
64: int PTHREAD_EXTERN sem_getvalue(sem_t * sem, int * sval);
65: int PTHREAD_EXTERN sem_destroy(sem_t * sem);
66:
67:
68:
69:
70:
71:
72: int PTHREAD_EXTERN pthread_cond_uswait( pthread_cond_t*, pthread_mutex_t*, unsigned long us);
73:
74:
75:
1: #line 508 "./lpsrc/flx_pthread.pak"
2:
3:
4:
5:
6:
7: struct timespec {
8: unsigned long tv_sec;
9: unsigned long tv_nsec;
10: };
11:
12:
13:
14:
15: int pthread_mutex_init (pthread_mutex_t *m, const pthread_mutexattr_t*)
16: {
17: *m = CreateMutex(NULL,FALSE,NULL);
18: return 0;
19: }
20:
21: int pthread_mutex_lock(pthread_mutex_t *m)
22: {
23: WaitForSingleObject(*m,INFINITE);
24: return 0;
25: }
26:
27: int pthread_mutex_unlock(pthread_mutex_t *m)
28: {
29: ReleaseMutex(*m);
30: return 0;
31: }
32:
33: int pthread_mutex_destroy(pthread_mutex_t *m)
34: {
35: CloseHandle(*m);
36: return 0;
37: }
38:
39: int
40: pthread_cond_init
41: (
42: pthread_cond_t *cv,
43: const pthread_condattr_t *
44: )
45: {
46: cv->waiters_count_ = 0;
47: cv->was_broadcast_ = 0;
48: cv->sema_ = CreateSemaphore
49: (
50: NULL,
51: 0,
52: 0x7fffffff,
53: NULL
54: );
55: InitializeCriticalSection (&cv->waiters_count_lock_);
56: cv->waiters_done_ = CreateEvent
57: (
58: NULL,
59: FALSE,
60: FALSE,
61: NULL
62: );
63: return 0;
64: }
65:
66: int
67: pthread_cond_destroy(pthread_cond_t *cv)
68: {
69: CloseHandle(cv->sema_);
70: CloseHandle(cv->waiters_done_);
71: return 0;
72: }
73:
74:
75: static int
76: private_cond_wait
77: (
78: pthread_cond_t *cv,
79: pthread_mutex_t *external_mutex,
80: unsigned long ms
81: )
82: {
83:
84: EnterCriticalSection (&cv->waiters_count_lock_);
85: cv->waiters_count_++;
86: LeaveCriticalSection (&cv->waiters_count_lock_);
87:
88:
89:
90:
91: int res = SignalObjectAndWait (*external_mutex, cv->sema_, ms, FALSE);
92:
93:
94: EnterCriticalSection (&cv->waiters_count_lock_);
95:
96:
97: cv->waiters_count_--;
98:
99:
100: int last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0;
101:
102: LeaveCriticalSection (&cv->waiters_count_lock_);
103:
104:
105:
106: if (last_waiter)
107:
108:
109: SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE);
110: else
111:
112:
113: WaitForSingleObject (*external_mutex, INFINITE);
114: return res;
115: }
116:
117: int
118: pthread_cond_wait
119: (
120: pthread_cond_t *cv,
121: pthread_mutex_t *external_mutex
122: )
123: {
124: return private_cond_wait(cv,external_mutex,INFINITE);
125: }
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137: int
138: pthread_cond_uswait
139: (
140: pthread_cond_t *cv,
141: pthread_mutex_t *external_mutex,
142: unsigned long us
143: )
144: {
145:
146:
147: return private_cond_wait(cv,external_mutex,us * 1000);
148: }
149:
150: int
151: pthread_cond_timedwait
152: (
153: pthread_cond_t *cv,
154: pthread_mutex_t *external_mutex,
155: struct timespec const *abstime
156: )
157: {
158: unsigned long t1 = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000;
159: SYSTEMTIME tod;
160: GetSystemTime(&tod);
161: FILETIME ft;
162: SystemTimeToFileTime(&tod,&ft);
163: ULARGE_INTEGER now;
164: assert(sizeof(now) == sizeof(ft));
165: memcpy(&now, &ft, sizeof(now));
166: unsigned long t0 = now.QuadPart / 10;
167: unsigned long timeout = t1>t0 ? t1 - t0 : 0;
168: return private_cond_wait(cv,external_mutex,timeout);
169: }
170:
171: int
172: pthread_cond_signal (pthread_cond_t *cv)
173: {
174: EnterCriticalSection (&cv->waiters_count_lock_);
175: int have_waiters = cv->waiters_count_ > 0;
176: LeaveCriticalSection (&cv->waiters_count_lock_);
177:
178:
179: if (have_waiters)
180: ReleaseSemaphore (cv->sema_, 1, 0);
181: return 0;
182: }
183:
184: int
185: pthread_cond_broadcast (pthread_cond_t *cv)
186: {
187:
188:
189: EnterCriticalSection (&cv->waiters_count_lock_);
190: int have_waiters = 0;
191:
192: if (cv->waiters_count_ > 0) {
193:
194:
195:
196: cv->was_broadcast_ = 1;
197: have_waiters = 1;
198: }
199:
200: if (have_waiters) {
201:
202: ReleaseSemaphore (cv->sema_, cv->waiters_count_, 0);
203:
204: LeaveCriticalSection (&cv->waiters_count_lock_);
205:
206:
207:
208: WaitForSingleObject (cv->waiters_done_, INFINITE);
209:
210:
211: cv->was_broadcast_ = 0;
212: }
213: else
214: LeaveCriticalSection (&cv->waiters_count_lock_);
215: return 0;
216: }
217:
218: int sem_init(sem_t *sem, int pshared, unsigned int value)
219: {
220: *sem = CreateSemaphore(NULL,value,0x7FFFFFFF,NULL);
221: return 0;
222: }
223:
224: int sem_wait(sem_t * sem)
225: {
226: return WaitForSingleObject(*sem,INFINITE);
227: }
228:
229: int sem_trywait(sem_t * sem)
230: {
231: return WaitForSingleObject(*sem,0);
232: }
233:
234: int sem_post(sem_t * sem)
235: {
236: return ReleaseSemaphore(*sem,1,NULL);
237: }
238:
239: int sem_getvalue(sem_t * sem, int * sval)
240: {
241: LONG x;
242: ReleaseSemaphore(*sem,0,&x);
243: *sval = x;
244: return 0;
245: }
246:
247: int sem_destroy(sem_t * sem)
248: {
249: return CloseHandle(*sem);
250: }
251:
252:
253:
254:
255:
256:
257:
258:
259: int pthread_cond_uswait(
260: pthread_cond_t *cv,
261: pthread_mutex_t *m,
262: unsigned long us
263: )
264: {
265: timeval tv;
266: gettimeofday(&tv,NULL);
267: unsigned long t0 = tv.tv_sec * 1000000uL + tv.tv_usec;
268: unsigned long t1 = t0 + us;
269: timespec ts;
270: ts.tv_sec = t1 / 1000000uL;
271: ts.tv_nsec = (t1 % 1000000uL) * 1000;
272: return pthread_cond_timedwait(cv,m,&ts);
273: }
274:
275:
276: