Mercurial > sdl-ios-xcode
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 |