SDL-1.2.14
[sdl_omap.git] / src / thread / pth / SDL_syscond.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This 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.
9
10     This 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.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 /*
25  *      GNU pth conditions variables
26  *
27  *      Patrice Mandin
28  */
29
30 #include <pth.h>
31
32 #include "SDL_thread.h"
33 #include "SDL_sysmutex_c.h"
34
35 struct SDL_cond
36 {
37         pth_cond_t      condpth_p;
38 };
39
40 /* Create a condition variable */
41 SDL_cond * SDL_CreateCond(void)
42 {
43         SDL_cond *cond;
44
45         cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
46         if ( cond ) {
47                 if ( pth_cond_init(&(cond->condpth_p)) < 0 ) {
48                         SDL_SetError("pthread_cond_init() failed");
49                         SDL_free(cond);
50                         cond = NULL;
51                 }
52         } else {
53                 SDL_OutOfMemory();
54         }
55         return(cond);
56 }
57
58 /* Destroy a condition variable */
59 void SDL_DestroyCond(SDL_cond *cond)
60 {
61         if ( cond ) {
62                 SDL_free(cond);
63         }
64 }
65
66 /* Restart one of the threads that are waiting on the condition variable */
67 int SDL_CondSignal(SDL_cond *cond)
68 {
69         int retval;
70
71         if ( ! cond ) {
72                 SDL_SetError("Passed a NULL condition variable");
73                 return -1;
74         }
75
76         retval = 0;
77         if ( pth_cond_notify(&(cond->condpth_p), FALSE) != 0 ) {
78                 SDL_SetError("pth_cond_notify() failed");
79                 retval = -1;
80         }
81         return retval;
82 }
83
84 /* Restart all threads that are waiting on the condition variable */
85 int SDL_CondBroadcast(SDL_cond *cond)
86 {
87         int retval;
88
89         if ( ! cond ) {
90                 SDL_SetError("Passed a NULL condition variable");
91                 return -1;
92         }
93
94         retval = 0;
95         if ( pth_cond_notify(&(cond->condpth_p), TRUE) != 0 ) {
96                 SDL_SetError("pth_cond_notify() failed");
97                 retval = -1;
98         }
99         return retval;
100 }
101
102 /* Wait on the condition variable for at most 'ms' milliseconds.
103    The mutex must be locked before entering this function!
104    The mutex is unlocked during the wait, and locked again after the wait.
105
106 Typical use:
107
108 Thread A:
109         SDL_LockMutex(lock);
110         while ( ! condition ) {
111                 SDL_CondWait(cond);
112         }
113         SDL_UnlockMutex(lock);
114
115 Thread B:
116         SDL_LockMutex(lock);
117         ...
118         condition = true;
119         ...
120         SDL_UnlockMutex(lock);
121  */
122 int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
123 {
124         int retval;
125         pth_event_t ev;
126         int sec;
127
128         if ( ! cond ) {
129                 SDL_SetError("Passed a NULL condition variable");
130                 return -1;
131         }
132
133         retval = 0;
134
135         sec = ms/1000;
136         ev = pth_event(PTH_EVENT_TIME, pth_timeout(sec,(ms-sec*1000)*1000));
137
138         if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), ev) != 0 ) {
139                 SDL_SetError("pth_cond_await() failed");
140                 retval = -1;
141         }
142
143     pth_event_free(ev, PTH_FREE_ALL);
144
145         return retval;
146 }
147
148 /* Wait on the condition variable forever */
149 int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
150 {
151         int retval;
152
153         if ( ! cond ) {
154                 SDL_SetError("Passed a NULL condition variable");
155                 return -1;
156         }
157
158         retval = 0;
159         if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), NULL) != 0 ) {
160                 SDL_SetError("pth_cond_await() failed");
161                 retval = -1;
162         }
163         return retval;
164 }