Initial revision
[glibc.git] / nptl / pthread_cond_wait.c
blob37c5ffe8469475434d1812cd517699e839e76f4f
1 /* Copyright (C) 2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include "pthreadP.h"
21 #include <lowlevellock.h>
24 int
25 pthread_cond_wait (cond, mutex)
26 pthread_cond_t *cond;
27 pthread_mutex_t *mutex;
29 int err;
31 /* This function is a cancellation point. Test before we potentially
32 go to sleep. */
33 CANCELLATION_P (THREAD_SELF);
35 /* Make sure the condition is modified atomically. */
36 lll_mutex_lock (cond->__data.__lock);
38 /* Release the mutex. This might fail. */
39 err = pthread_mutex_unlock (mutex);
40 if (__builtin_expect (err != 0, 0))
42 lll_mutex_unlock (cond->__data.__lock);
43 return err;
46 /* One more tread waiting. */
47 ++cond->__data.__nr_sleepers;
49 /* The actual conditional variable implementation. */
50 lll_cond_wait (cond);
52 if (--cond->__data.__nr_sleepers == 0)
53 /* Forget about the current wakeups now that they are done. */
54 cond->__data.__nr_wakers = 0;
56 /* Lose the condvar lock. */
57 lll_mutex_unlock (cond->__data.__lock);
59 /* We have to get the mutex before returning. */
60 err = pthread_mutex_lock (mutex);
62 /* Cancellation handling. */
63 CANCELLATION_P (THREAD_SELF);
65 return err;