1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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 */
SDL_CreateCond(void)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 */
SDL_DestroyCond(SDL_cond * cond)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 */
SDL_CondSignal(SDL_cond * cond)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 */
SDL_CondBroadcast(SDL_cond * cond)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 */
SDL_CondWaitTimeout(SDL_cond * cond,SDL_mutex * mutex,Uint32 ms)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 */
SDL_CondWait(SDL_cond * cond,SDL_mutex * mutex)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 }
165