comparison src/thread/pthread/SDL_syssem.c @ 5108:d547877e355e

Colin Leroy 2011-01-26 04:24:20 PST the pthread implementation of SDL_SemWaitTimeout() uses busy waiting, while pthread's sem_timedwait() does work. Attached are patches that make use of it
author Sam Lantinga <slouken@libsdl.org>
date Thu, 27 Jan 2011 00:34:12 -0800
parents f7b03b6838cb
children b530ef003506
comparison
equal deleted inserted replaced
5106:5fe0330b0fd6 5108:d547877e355e
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21 */ 21 */
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #include <errno.h>
24 #include <pthread.h> 25 #include <pthread.h>
25 #include <semaphore.h> 26 #include <semaphore.h>
26 27
27 #include "SDL_thread.h" 28 #include "SDL_thread.h"
28 #include "SDL_timer.h" 29 #include "SDL_timer.h"
100 101
101 int 102 int
102 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) 103 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
103 { 104 {
104 int retval; 105 int retval;
106 struct timeval now;
107 struct timespec ts_timeout;
105 108
106 if (!sem) { 109 if (!sem) {
107 SDL_SetError("Passed a NULL semaphore"); 110 SDL_SetError("Passed a NULL semaphore");
108 return -1; 111 return -1;
109 } 112 }
114 } 117 }
115 if (timeout == SDL_MUTEX_MAXWAIT) { 118 if (timeout == SDL_MUTEX_MAXWAIT) {
116 return SDL_SemWait(sem); 119 return SDL_SemWait(sem);
117 } 120 }
118 121
119 /* Ack! We have to busy wait... */ 122 /* Setup the timeout. sem_timedwait doesn't wait for
120 /* FIXME: Use sem_timedwait()? */ 123 * a lapse of time, but until we reach a certain time.
121 timeout += SDL_GetTicks(); 124 * This time is now plus the timeout.
125 */
126 gettimeofday(&now, NULL);
127
128 /* Add our timeout to current time */
129 now.tv_usec += (timeout % 1000) * 1000;
130 now.tv_sec += timeout / 1000;
131
132 /* Wrap the second if needed */
133 if ( now.tv_usec >= 1000000 ) {
134 now.tv_usec -= 1000000;
135 now.tv_sec ++;
136 }
137
138 /* Convert to timespec */
139 ts_timeout.tv_sec = now.tv_sec;
140 ts_timeout.tv_nsec = now.tv_usec * 1000;
141
142 /* Wait. */
122 do { 143 do {
123 retval = SDL_SemTryWait(sem); 144 retval = sem_timedwait(&sem->sem, &ts_timeout);
124 if (retval == 0) { 145 } while (retval < 0 && errno == EINTR);
125 break; 146
126 } 147 if (retval < 0) {
127 SDL_Delay(1); 148 SDL_SetError("sem_timedwait() failed");
128 } while (SDL_GetTicks() < timeout); 149 }
129 150
130 return retval; 151 return retval;
131 } 152 }
132 153
133 Uint32 154 Uint32