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