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 (at) 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 } 165