/[pcsx2_0.9.7]/trunk/3rdparty/w32pthreads/pthread_cond_signal.c
ViewVC logotype

Annotation of /trunk/3rdparty/w32pthreads/pthread_cond_signal.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years ago) by william
File MIME type: text/plain
File size: 6690 byte(s)
committing r3113 initial commit again...
1 william 31 /*
2     * pthread_cond_signal.c
3     *
4     * Description:
5     * This translation unit implements condition variables and their primitives.
6     *
7     *
8     * --------------------------------------------------------------------------
9     *
10     * Pthreads-win32 - POSIX Threads Library for Win32
11     * Copyright(C) 1998 John E. Bossom
12     * Copyright(C) 1999,2005 Pthreads-win32 contributors
13     *
14     * Contact Email: rpj@callisto.canberra.edu.au
15     *
16     * The current list of contributors is contained
17     * in the file CONTRIBUTORS included with the source
18     * code distribution. The list can also be seen at the
19     * following World Wide Web location:
20     * http://sources.redhat.com/pthreads-win32/contributors.html
21     *
22     * This library is free software; you can redistribute it and/or
23     * modify it under the terms of the GNU Lesser General Public
24     * License as published by the Free Software Foundation; either
25     * version 2 of the License, or (at your option) any later version.
26     *
27     * This library is distributed in the hope that it will be useful,
28     * but WITHOUT ANY WARRANTY; without even the implied warranty of
29     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30     * Lesser General Public License for more details.
31     *
32     * You should have received a copy of the GNU Lesser General Public
33     * License along with this library in the file COPYING.LIB;
34     * if not, write to the Free Software Foundation, Inc.,
35     * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36     *
37     * -------------------------------------------------------------
38     * Algorithm:
39     * See the comments at the top of pthread_cond_wait.c.
40     */
41    
42     #include "ptw32pch.h"
43    
44     static INLINE int
45     ptw32_cond_unblock (pthread_cond_t * cond, int unblockAll)
46     /*
47     * Notes.
48     *
49     * Does not use the external mutex for synchronisation,
50     * therefore semBlockLock is needed.
51     * mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the
52     * state where the external mutex is not necessarily locked by
53     * any thread, ie. between cond_wait unlocking and re-acquiring
54     * the lock after having been signaled or a timeout or
55     * cancellation.
56     *
57     * Uses the following CV elements:
58     * nWaitersBlocked
59     * nWaitersToUnblock
60     * nWaitersGone
61     * mtxUnblockLock
62     * semBlockLock
63     * semBlockQueue
64     */
65     {
66     int result;
67     pthread_cond_t cv;
68     int nSignalsToIssue;
69    
70     if (cond == NULL || *cond == NULL)
71     {
72     return EINVAL;
73     }
74    
75     cv = *cond;
76    
77     /*
78     * No-op if the CV is static and hasn't been initialised yet.
79     * Assuming that any race condition is harmless.
80     */
81     if (cv == PTHREAD_COND_INITIALIZER)
82     {
83     return 0;
84     }
85    
86     if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
87     {
88     return result;
89     }
90    
91     if (0 != cv->nWaitersToUnblock)
92     {
93     if (0 == cv->nWaitersBlocked)
94     {
95     return pthread_mutex_unlock (&(cv->mtxUnblockLock));
96     }
97     if (unblockAll)
98     {
99     cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked);
100     cv->nWaitersBlocked = 0;
101     }
102     else
103     {
104     nSignalsToIssue = 1;
105     cv->nWaitersToUnblock++;
106     cv->nWaitersBlocked--;
107     }
108     }
109     else if (cv->nWaitersBlocked > cv->nWaitersGone)
110     {
111     /* Use the non-cancellable version of sem_wait() */
112     if (ptw32_semwait (&(cv->semBlockLock)) != 0)
113     {
114     result = errno;
115     (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
116     return result;
117     }
118     if (0 != cv->nWaitersGone)
119     {
120     cv->nWaitersBlocked -= cv->nWaitersGone;
121     cv->nWaitersGone = 0;
122     }
123     if (unblockAll)
124     {
125     nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked;
126     cv->nWaitersBlocked = 0;
127     }
128     else
129     {
130     nSignalsToIssue = cv->nWaitersToUnblock = 1;
131     cv->nWaitersBlocked--;
132     }
133     }
134     else
135     {
136     return pthread_mutex_unlock (&(cv->mtxUnblockLock));
137     }
138    
139     if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
140     {
141     if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0)
142     {
143     result = errno;
144     }
145     }
146    
147     return result;
148    
149     } /* ptw32_cond_unblock */
150    
151     int
152     pthread_cond_signal (pthread_cond_t * cond)
153     /*
154     * ------------------------------------------------------
155     * DOCPUBLIC
156     * This function signals a condition variable, waking
157     * one waiting thread.
158     * If SCHED_FIFO or SCHED_RR policy threads are waiting
159     * the highest priority waiter is awakened; otherwise,
160     * an unspecified waiter is awakened.
161     *
162     * PARAMETERS
163     * cond
164     * pointer to an instance of pthread_cond_t
165     *
166     *
167     * DESCRIPTION
168     * This function signals a condition variable, waking
169     * one waiting thread.
170     * If SCHED_FIFO or SCHED_RR policy threads are waiting
171     * the highest priority waiter is awakened; otherwise,
172     * an unspecified waiter is awakened.
173     *
174     * NOTES:
175     *
176     * 1) Use when any waiter can respond and only one need
177     * respond (all waiters being equal).
178     *
179     * RESULTS
180     * 0 successfully signaled condition,
181     * EINVAL 'cond' is invalid,
182     *
183     * ------------------------------------------------------
184     */
185     {
186     /*
187     * The '0'(FALSE) unblockAll arg means unblock ONE waiter.
188     */
189     return (ptw32_cond_unblock (cond, 0));
190    
191     } /* pthread_cond_signal */
192    
193     int
194     pthread_cond_broadcast (pthread_cond_t * cond)
195     /*
196     * ------------------------------------------------------
197     * DOCPUBLIC
198     * This function broadcasts the condition variable,
199     * waking all current waiters.
200     *
201     * PARAMETERS
202     * cond
203     * pointer to an instance of pthread_cond_t
204     *
205     *
206     * DESCRIPTION
207     * This function signals a condition variable, waking
208     * all waiting threads.
209     *
210     * NOTES:
211     *
212     * 1) Use when more than one waiter may respond to
213     * predicate change or if any waiting thread may
214     * not be able to respond
215     *
216     * RESULTS
217     * 0 successfully signalled condition to all
218     * waiting threads,
219     * EINVAL 'cond' is invalid
220     * ENOSPC a required resource has been exhausted,
221     *
222     * ------------------------------------------------------
223     */
224     {
225     /*
226     * The TRUE unblockAll arg means unblock ALL waiters.
227     */
228     return (ptw32_cond_unblock (cond, PTW32_TRUE));
229    
230     } /* pthread_cond_broadcast */

  ViewVC Help
Powered by ViewVC 1.1.22