• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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