Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1144)

Side by Side Diff: nspr/pr/src/threads/combined/prucv.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nspr/pr/src/threads/combined/prucpu.c ('k') | nspr/pr/src/threads/combined/prulock.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
7 #include "primpl.h"
8 #include "prinrval.h"
9 #include "prtypes.h"
10
11 #if defined(WIN95)
12 /*
13 ** Some local variables report warnings on Win95 because the code paths
14 ** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
15 ** The pragma suppresses the warning.
16 **
17 */
18 #pragma warning(disable : 4101)
19 #endif
20
21
22 /*
23 ** Notify one thread that it has finished waiting on a condition variable
24 ** Caller must hold the _PR_CVAR_LOCK(cv)
25 */
26 PRBool _PR_NotifyThread (PRThread *thread, PRThread *me)
27 {
28 PRBool rv;
29
30 PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
31
32 _PR_THREAD_LOCK(thread);
33 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
34 if ( !_PR_IS_NATIVE_THREAD(thread) ) {
35 if (thread->wait.cvar != NULL) {
36 thread->wait.cvar = NULL;
37
38 _PR_SLEEPQ_LOCK(thread->cpu);
39 /* The notify and timeout can collide; in which case both may
40 * attempt to delete from the sleepQ; only let one do it.
41 */
42 if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
43 _PR_DEL_SLEEPQ(thread, PR_TRUE);
44 _PR_SLEEPQ_UNLOCK(thread->cpu);
45
46 if (thread->flags & _PR_SUSPENDING) {
47 /*
48 * set thread state to SUSPENDED; a Resume operation
49 * on the thread will move it to the runQ
50 */
51 thread->state = _PR_SUSPENDED;
52 _PR_MISCQ_LOCK(thread->cpu);
53 _PR_ADD_SUSPENDQ(thread, thread->cpu);
54 _PR_MISCQ_UNLOCK(thread->cpu);
55 _PR_THREAD_UNLOCK(thread);
56 } else {
57 /* Make thread runnable */
58 thread->state = _PR_RUNNABLE;
59 _PR_THREAD_UNLOCK(thread);
60
61 _PR_AddThreadToRunQ(me, thread);
62 _PR_MD_WAKEUP_WAITER(thread);
63 }
64
65 rv = PR_TRUE;
66 } else {
67 /* Thread has already been notified */
68 _PR_THREAD_UNLOCK(thread);
69 rv = PR_FALSE;
70 }
71 } else { /* If the thread is a native thread */
72 if (thread->wait.cvar) {
73 thread->wait.cvar = NULL;
74
75 if (thread->flags & _PR_SUSPENDING) {
76 /*
77 * set thread state to SUSPENDED; a Resume operation
78 * on the thread will enable the thread to run
79 */
80 thread->state = _PR_SUSPENDED;
81 } else
82 thread->state = _PR_RUNNING;
83 _PR_THREAD_UNLOCK(thread);
84 _PR_MD_WAKEUP_WAITER(thread);
85 rv = PR_TRUE;
86 } else {
87 _PR_THREAD_UNLOCK(thread);
88 rv = PR_FALSE;
89 }
90 }
91
92 return rv;
93 }
94
95 /*
96 * Notify thread waiting on cvar; called when thread is interrupted
97 * The thread lock is held on entry and released before return
98 */
99 void _PR_NotifyLockedThread (PRThread *thread)
100 {
101 PRThread *me = _PR_MD_CURRENT_THREAD();
102 PRCondVar *cvar;
103 PRThreadPriority pri;
104
105 if ( !_PR_IS_NATIVE_THREAD(me))
106 PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
107
108 cvar = thread->wait.cvar;
109 thread->wait.cvar = NULL;
110 _PR_THREAD_UNLOCK(thread);
111
112 _PR_CVAR_LOCK(cvar);
113 _PR_THREAD_LOCK(thread);
114
115 if (!_PR_IS_NATIVE_THREAD(thread)) {
116 _PR_SLEEPQ_LOCK(thread->cpu);
117 /* The notify and timeout can collide; in which case both may
118 * attempt to delete from the sleepQ; only let one do it.
119 */
120 if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
121 _PR_DEL_SLEEPQ(thread, PR_TRUE);
122 _PR_SLEEPQ_UNLOCK(thread->cpu);
123
124 /* Make thread runnable */
125 pri = thread->priority;
126 thread->state = _PR_RUNNABLE;
127
128 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
129
130 _PR_AddThreadToRunQ(me, thread);
131 _PR_THREAD_UNLOCK(thread);
132
133 _PR_MD_WAKEUP_WAITER(thread);
134 } else {
135 if (thread->flags & _PR_SUSPENDING) {
136 /*
137 * set thread state to SUSPENDED; a Resume operation
138 * on the thread will enable the thread to run
139 */
140 thread->state = _PR_SUSPENDED;
141 } else
142 thread->state = _PR_RUNNING;
143 _PR_THREAD_UNLOCK(thread);
144 _PR_MD_WAKEUP_WAITER(thread);
145 }
146
147 _PR_CVAR_UNLOCK(cvar);
148 return;
149 }
150
151 /*
152 ** Make the given thread wait for the given condition variable
153 */
154 PRStatus _PR_WaitCondVar(
155 PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
156 {
157 PRIntn is;
158 PRStatus rv = PR_SUCCESS;
159
160 PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
161 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
162
163 #ifdef _PR_GLOBAL_THREADS_ONLY
164 if (_PR_PENDING_INTERRUPT(thread)) {
165 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
166 thread->flags &= ~_PR_INTERRUPT;
167 return PR_FAILURE;
168 }
169
170 thread->wait.cvar = cvar;
171 lock->owner = NULL;
172 _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout);
173 thread->wait.cvar = NULL;
174 lock->owner = thread;
175 if (_PR_PENDING_INTERRUPT(thread)) {
176 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
177 thread->flags &= ~_PR_INTERRUPT;
178 return PR_FAILURE;
179 }
180
181 return PR_SUCCESS;
182 #else /* _PR_GLOBAL_THREADS_ONLY */
183
184 if ( !_PR_IS_NATIVE_THREAD(thread))
185 _PR_INTSOFF(is);
186
187 _PR_CVAR_LOCK(cvar);
188 _PR_THREAD_LOCK(thread);
189
190 if (_PR_PENDING_INTERRUPT(thread)) {
191 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
192 thread->flags &= ~_PR_INTERRUPT;
193 _PR_CVAR_UNLOCK(cvar);
194 _PR_THREAD_UNLOCK(thread);
195 if ( !_PR_IS_NATIVE_THREAD(thread))
196 _PR_INTSON(is);
197 return PR_FAILURE;
198 }
199
200 thread->state = _PR_COND_WAIT;
201 thread->wait.cvar = cvar;
202
203 /*
204 ** Put the caller thread on the condition variable's wait Q
205 */
206 PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ);
207
208 /* Note- for global scope threads, we don't put them on the
209 * global sleepQ, so each global thread must put itself
210 * to sleep only for the time it wants to.
211 */
212 if ( !_PR_IS_NATIVE_THREAD(thread) ) {
213 _PR_SLEEPQ_LOCK(thread->cpu);
214 _PR_ADD_SLEEPQ(thread, timeout);
215 _PR_SLEEPQ_UNLOCK(thread->cpu);
216 }
217 _PR_CVAR_UNLOCK(cvar);
218 _PR_THREAD_UNLOCK(thread);
219
220 /*
221 ** Release lock protecting the condition variable and thereby giving time
222 ** to the next thread which can potentially notify on the condition variable
223 */
224 PR_Unlock(lock);
225
226 PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
227 ("PR_Wait: cvar=%p waiting for %d", cvar, timeout));
228
229 rv = _PR_MD_WAIT(thread, timeout);
230
231 _PR_CVAR_LOCK(cvar);
232 PR_REMOVE_LINK(&thread->waitQLinks);
233 _PR_CVAR_UNLOCK(cvar);
234
235 PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
236 ("PR_Wait: cvar=%p done waiting", cvar));
237
238 if ( !_PR_IS_NATIVE_THREAD(thread))
239 _PR_INTSON(is);
240
241 /* Acquire lock again that we had just relinquished */
242 PR_Lock(lock);
243
244 if (_PR_PENDING_INTERRUPT(thread)) {
245 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
246 thread->flags &= ~_PR_INTERRUPT;
247 return PR_FAILURE;
248 }
249
250 return rv;
251 #endif /* _PR_GLOBAL_THREADS_ONLY */
252 }
253
254 void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me)
255 {
256 #ifdef _PR_GLOBAL_THREADS_ONLY
257 _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock);
258 #else /* _PR_GLOBAL_THREADS_ONLY */
259
260 PRCList *q;
261 PRIntn is;
262
263 if ( !_PR_IS_NATIVE_THREAD(me))
264 _PR_INTSOFF(is);
265 PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
266
267 _PR_CVAR_LOCK(cvar);
268 q = cvar->condQ.next;
269 while (q != &cvar->condQ) {
270 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));
271 if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) {
272 if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)
273 break;
274 }
275 q = q->next;
276 }
277 _PR_CVAR_UNLOCK(cvar);
278
279 if ( !_PR_IS_NATIVE_THREAD(me))
280 _PR_INTSON(is);
281
282 #endif /* _PR_GLOBAL_THREADS_ONLY */
283 }
284
285 /*
286 ** Cndition variable debugging log info.
287 */
288 PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen)
289 {
290 PRUint32 nb;
291
292 if (cvar->lock->owner) {
293 nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]",
294 cvar, cvar->lock->owner->id, cvar->lock->owner);
295 } else {
296 nb = PR_snprintf(buf, buflen, "[%p]", cvar);
297 }
298 return nb;
299 }
300
301 /*
302 ** Expire condition variable waits that are ready to expire. "now" is the curren t
303 ** time.
304 */
305 void _PR_ClockInterrupt(void)
306 {
307 PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
308 _PRCPU *cpu = me->cpu;
309 PRIntervalTime elapsed, now;
310
311 PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
312 /* Figure out how much time elapsed since the last clock tick */
313 now = PR_IntervalNow();
314 elapsed = now - cpu->last_clock;
315 cpu->last_clock = now;
316
317 PR_LOG(_pr_clock_lm, PR_LOG_MAX,
318 ("ExpireWaits: elapsed=%lld usec", elapsed));
319
320 while(1) {
321 _PR_SLEEPQ_LOCK(cpu);
322 if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) {
323 _PR_SLEEPQ_UNLOCK(cpu);
324 break;
325 }
326
327 thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next);
328 PR_ASSERT(thread->cpu == cpu);
329
330 if (elapsed < thread->sleep) {
331 thread->sleep -= elapsed;
332 _PR_SLEEPQMAX(thread->cpu) -= elapsed;
333 _PR_SLEEPQ_UNLOCK(cpu);
334 break;
335 }
336 _PR_SLEEPQ_UNLOCK(cpu);
337
338 PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
339
340 _PR_THREAD_LOCK(thread);
341
342 if (thread->cpu != cpu) {
343 /*
344 ** The thread was switched to another CPU
345 ** between the time we unlocked the sleep
346 ** queue and the time we acquired the thread
347 ** lock, so it is none of our business now.
348 */
349 _PR_THREAD_UNLOCK(thread);
350 continue;
351 }
352
353 /*
354 ** Consume this sleeper's amount of elapsed time from the elapsed
355 ** time value. The next remaining piece of elapsed time will be
356 ** available for the next sleeping thread's timer.
357 */
358 _PR_SLEEPQ_LOCK(cpu);
359 PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ));
360 if (thread->flags & _PR_ON_SLEEPQ) {
361 _PR_DEL_SLEEPQ(thread, PR_FALSE);
362 elapsed -= thread->sleep;
363 _PR_SLEEPQ_UNLOCK(cpu);
364 } else {
365 /* Thread was already handled; Go get another one */
366 _PR_SLEEPQ_UNLOCK(cpu);
367 _PR_THREAD_UNLOCK(thread);
368 continue;
369 }
370
371 /* Notify the thread waiting on the condition variable */
372 if (thread->flags & _PR_SUSPENDING) {
373 PR_ASSERT((thread->state == _PR_IO_WAIT) ||
374 (thread->state == _PR_COND_WAIT));
375 /*
376 ** Thread is suspended and its condition timeout
377 ** expired. Transfer thread from sleepQ to suspendQ.
378 */
379 thread->wait.cvar = NULL;
380 _PR_MISCQ_LOCK(cpu);
381 thread->state = _PR_SUSPENDED;
382 _PR_ADD_SUSPENDQ(thread, cpu);
383 _PR_MISCQ_UNLOCK(cpu);
384 } else {
385 if (thread->wait.cvar) {
386 PRThreadPriority pri;
387
388 /* Do work very similar to what _PR_NotifyThread does */
389 PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
390
391 /* Make thread runnable */
392 pri = thread->priority;
393 thread->state = _PR_RUNNABLE;
394 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
395
396 PR_ASSERT(thread->cpu == cpu);
397 _PR_RUNQ_LOCK(cpu);
398 _PR_ADD_RUNQ(thread, cpu, pri);
399 _PR_RUNQ_UNLOCK(cpu);
400
401 if (pri > me->priority)
402 _PR_SET_RESCHED_FLAG();
403
404 thread->wait.cvar = NULL;
405
406 _PR_MD_WAKEUP_WAITER(thread);
407
408 } else if (thread->io_pending == PR_TRUE) {
409 /* Need to put IO sleeper back on runq */
410 int pri = thread->priority;
411
412 thread->io_suspended = PR_TRUE;
413 #ifdef WINNT
414 /*
415 * For NT, record the cpu on which I/O was issue d
416 * I/O cancellation is done on the same cpu
417 */
418 thread->md.thr_bound_cpu = cpu;
419 #endif
420
421 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
422 PR_ASSERT(thread->cpu == cpu);
423 thread->state = _PR_RUNNABLE;
424 _PR_RUNQ_LOCK(cpu);
425 _PR_ADD_RUNQ(thread, cpu, pri);
426 _PR_RUNQ_UNLOCK(cpu);
427 }
428 }
429 _PR_THREAD_UNLOCK(thread);
430 }
431 }
432
433 /************************************************************************/
434
435 /*
436 ** Create a new condition variable.
437 ** "lock" is the lock to use with the condition variable.
438 **
439 ** Condition variables are synchronization objects that threads can use
440 ** to wait for some condition to occur.
441 **
442 ** This may fail if memory is tight or if some operating system resource
443 ** is low.
444 */
445 PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
446 {
447 PRCondVar *cvar;
448
449 cvar = PR_NEWZAP(PRCondVar);
450 if (cvar) {
451 if (_PR_InitCondVar(cvar, lock) != PR_SUCCESS) {
452 PR_DELETE(cvar);
453 return NULL;
454 }
455 } else {
456 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
457 }
458 return cvar;
459 }
460
461 PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock)
462 {
463 PR_ASSERT(lock != NULL);
464
465 #ifdef _PR_GLOBAL_THREADS_ONLY
466 if(_PR_MD_NEW_CV(&cvar->md)) {
467 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
468 return PR_FAILURE;
469 }
470 #endif
471 if (_PR_MD_NEW_LOCK(&(cvar->ilock)) != PR_SUCCESS) {
472 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
473 return PR_FAILURE;
474 }
475 cvar->lock = lock;
476 PR_INIT_CLIST(&cvar->condQ);
477 return PR_SUCCESS;
478 }
479
480 /*
481 ** Destroy a condition variable. There must be no thread
482 ** waiting on the condvar. The caller is responsible for guaranteeing
483 ** that the condvar is no longer in use.
484 **
485 */
486 PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
487 {
488 _PR_FreeCondVar(cvar);
489 PR_DELETE(cvar);
490 }
491
492 void _PR_FreeCondVar(PRCondVar *cvar)
493 {
494 PR_ASSERT(cvar->condQ.next == &cvar->condQ);
495
496 #ifdef _PR_GLOBAL_THREADS_ONLY
497 _PR_MD_FREE_CV(&cvar->md);
498 #endif
499 _PR_MD_FREE_LOCK(&(cvar->ilock));
500 }
501
502 /*
503 ** Wait for a notify on the condition variable. Sleep for "tiemout" amount
504 ** of ticks (if "timeout" is zero then the sleep is indefinite). While
505 ** the thread is waiting it unlocks lock. When the wait has
506 ** finished the thread regains control of the condition variable after
507 ** locking the associated lock.
508 **
509 ** The thread waiting on the condvar will be resumed when the condvar is
510 ** notified (assuming the thread is the next in line to receive the
511 ** notify) or when the timeout elapses.
512 **
513 ** Returns PR_FAILURE if the caller has not locked the lock associated
514 ** with the condition variable or the thread has been interrupted.
515 */
516 extern PRThread *suspendAllThread;
517 PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
518 {
519 PRThread *me = _PR_MD_CURRENT_THREAD();
520
521 PR_ASSERT(cvar->lock->owner == me);
522 PR_ASSERT(me != suspendAllThread);
523 if (cvar->lock->owner != me) return PR_FAILURE;
524
525 return _PR_WaitCondVar(me, cvar, cvar->lock, timeout);
526 }
527
528 /*
529 ** Notify the highest priority thread waiting on the condition
530 ** variable. If a thread is waiting on the condition variable (using
531 ** PR_Wait) then it is awakened and begins waiting on the lock.
532 */
533 PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar)
534 {
535 PRThread *me = _PR_MD_CURRENT_THREAD();
536
537 PR_ASSERT(cvar->lock->owner == me);
538 PR_ASSERT(me != suspendAllThread);
539 if (cvar->lock->owner != me) return PR_FAILURE;
540
541 _PR_NotifyCondVar(cvar, me);
542 return PR_SUCCESS;
543 }
544
545 /*
546 ** Notify all of the threads waiting on the condition variable. All of
547 ** threads are notified in turn. The highest priority thread will
548 ** probably acquire the lock.
549 */
550 PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
551 {
552 PRCList *q;
553 PRIntn is;
554 PRThread *me = _PR_MD_CURRENT_THREAD();
555
556 PR_ASSERT(cvar->lock->owner == me);
557 if (cvar->lock->owner != me) return PR_FAILURE;
558
559 #ifdef _PR_GLOBAL_THREADS_ONLY
560 _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock);
561 return PR_SUCCESS;
562 #else /* _PR_GLOBAL_THREADS_ONLY */
563 if ( !_PR_IS_NATIVE_THREAD(me))
564 _PR_INTSOFF(is);
565 _PR_CVAR_LOCK(cvar);
566 q = cvar->condQ.next;
567 while (q != &cvar->condQ) {
568 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)) ;
569 _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
570 q = q->next;
571 }
572 _PR_CVAR_UNLOCK(cvar);
573 if (!_PR_IS_NATIVE_THREAD(me))
574 _PR_INTSON(is);
575
576 return PR_SUCCESS;
577 #endif /* _PR_GLOBAL_THREADS_ONLY */
578 }
579
580
581 /*********************************************************************/
582 /*********************************************************************/
583 /********************ROUTINES FOR DCE EMULATION***********************/
584 /*********************************************************************/
585 /*********************************************************************/
586 #include "prpdce.h"
587
588 PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
589 {
590 PRCondVar *cvar = PR_NEWZAP(PRCondVar);
591 if (NULL != cvar)
592 {
593 if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE)
594 {
595 PR_DELETE(cvar); cvar = NULL;
596 }
597 else
598 {
599 PR_INIT_CLIST(&cvar->condQ);
600 cvar->lock = _PR_NAKED_CV_LOCK;
601 }
602
603 }
604 return cvar;
605 }
606
607 PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar)
608 {
609 PR_ASSERT(cvar->condQ.next == &cvar->condQ);
610 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
611
612 _PR_MD_FREE_LOCK(&(cvar->ilock));
613
614 PR_DELETE(cvar);
615 }
616
617 PR_IMPLEMENT(PRStatus) PRP_NakedWait(
618 PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
619 {
620 PRThread *me = _PR_MD_CURRENT_THREAD();
621 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
622 return _PR_WaitCondVar(me, cvar, lock, timeout);
623 } /* PRP_NakedWait */
624
625 PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar)
626 {
627 PRThread *me = _PR_MD_CURRENT_THREAD();
628 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
629
630 _PR_NotifyCondVar(cvar, me);
631
632 return PR_SUCCESS;
633 } /* PRP_NakedNotify */
634
635 PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
636 {
637 PRCList *q;
638 PRIntn is;
639 PRThread *me = _PR_MD_CURRENT_THREAD();
640 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
641
642 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
643 _PR_MD_LOCK( &(cvar->ilock) );
644 q = cvar->condQ.next;
645 while (q != &cvar->condQ) {
646 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)) ;
647 _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
648 q = q->next;
649 }
650 _PR_MD_UNLOCK( &(cvar->ilock) );
651 if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
652
653 return PR_SUCCESS;
654 } /* PRP_NakedBroadcast */
655
OLDNEW
« no previous file with comments | « nspr/pr/src/threads/combined/prucpu.c ('k') | nspr/pr/src/threads/combined/prulock.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698