Revision c166cb72 qemu-thread-posix.c
b/qemu-thread-posix.c | ||
---|---|---|
122 | 122 |
{ |
123 | 123 |
int rc; |
124 | 124 |
|
125 |
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) |
|
126 |
rc = pthread_mutex_init(&sem->lock, NULL); |
|
127 |
if (rc != 0) { |
|
128 |
error_exit(rc, __func__); |
|
129 |
} |
|
130 |
rc = pthread_cond_init(&sem->cond, NULL); |
|
131 |
if (rc != 0) { |
|
132 |
error_exit(rc, __func__); |
|
133 |
} |
|
134 |
if (init < 0) { |
|
135 |
error_exit(EINVAL, __func__); |
|
136 |
} |
|
137 |
sem->count = init; |
|
138 |
#else |
|
125 | 139 |
rc = sem_init(&sem->sem, 0, init); |
126 | 140 |
if (rc < 0) { |
127 | 141 |
error_exit(errno, __func__); |
128 | 142 |
} |
143 |
#endif |
|
129 | 144 |
} |
130 | 145 |
|
131 | 146 |
void qemu_sem_destroy(QemuSemaphore *sem) |
132 | 147 |
{ |
133 | 148 |
int rc; |
134 | 149 |
|
150 |
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) |
|
151 |
rc = pthread_cond_destroy(&sem->cond); |
|
152 |
if (rc < 0) { |
|
153 |
error_exit(rc, __func__); |
|
154 |
} |
|
155 |
rc = pthread_mutex_destroy(&sem->lock); |
|
156 |
if (rc < 0) { |
|
157 |
error_exit(rc, __func__); |
|
158 |
} |
|
159 |
#else |
|
135 | 160 |
rc = sem_destroy(&sem->sem); |
136 | 161 |
if (rc < 0) { |
137 | 162 |
error_exit(errno, __func__); |
138 | 163 |
} |
164 |
#endif |
|
139 | 165 |
} |
140 | 166 |
|
141 | 167 |
void qemu_sem_post(QemuSemaphore *sem) |
142 | 168 |
{ |
143 | 169 |
int rc; |
144 | 170 |
|
171 |
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) |
|
172 |
pthread_mutex_lock(&sem->lock); |
|
173 |
if (sem->count == INT_MAX) { |
|
174 |
rc = EINVAL; |
|
175 |
} else if (sem->count++ < 0) { |
|
176 |
rc = pthread_cond_signal(&sem->cond); |
|
177 |
} else { |
|
178 |
rc = 0; |
|
179 |
} |
|
180 |
pthread_mutex_unlock(&sem->lock); |
|
181 |
if (rc != 0) { |
|
182 |
error_exit(rc, __func__); |
|
183 |
} |
|
184 |
#else |
|
145 | 185 |
rc = sem_post(&sem->sem); |
146 | 186 |
if (rc < 0) { |
147 | 187 |
error_exit(errno, __func__); |
148 | 188 |
} |
189 |
#endif |
|
190 |
} |
|
191 |
|
|
192 |
static void compute_abs_deadline(struct timespec *ts, int ms) |
|
193 |
{ |
|
194 |
struct timeval tv; |
|
195 |
gettimeofday(&tv, NULL); |
|
196 |
ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000; |
|
197 |
ts->tv_sec = tv.tv_sec + ms / 1000; |
|
198 |
if (ts->tv_nsec >= 1000000000) { |
|
199 |
ts->tv_sec++; |
|
200 |
ts->tv_nsec -= 1000000000; |
|
201 |
} |
|
149 | 202 |
} |
150 | 203 |
|
151 | 204 |
int qemu_sem_timedwait(QemuSemaphore *sem, int ms) |
152 | 205 |
{ |
153 | 206 |
int rc; |
154 |
|
|
207 |
struct timespec ts; |
|
208 |
|
|
209 |
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) |
|
210 |
compute_abs_deadline(&ts, ms); |
|
211 |
pthread_mutex_lock(&sem->lock); |
|
212 |
--sem->count; |
|
213 |
while (sem->count < 0) { |
|
214 |
rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts); |
|
215 |
if (rc == ETIMEDOUT) { |
|
216 |
break; |
|
217 |
} |
|
218 |
if (rc != 0) { |
|
219 |
error_exit(rc, __func__); |
|
220 |
} |
|
221 |
} |
|
222 |
pthread_mutex_unlock(&sem->lock); |
|
223 |
return (rc == ETIMEDOUT ? -1 : 0); |
|
224 |
#else |
|
155 | 225 |
if (ms <= 0) { |
156 | 226 |
/* This is cheaper than sem_timedwait. */ |
157 | 227 |
do { |
... | ... | |
161 | 231 |
return -1; |
162 | 232 |
} |
163 | 233 |
} else { |
164 |
struct timeval tv; |
|
165 |
struct timespec ts; |
|
166 |
gettimeofday(&tv, NULL); |
|
167 |
ts.tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000; |
|
168 |
ts.tv_sec = tv.tv_sec + ms / 1000; |
|
169 |
if (ts.tv_nsec >= 1000000000) { |
|
170 |
ts.tv_sec++; |
|
171 |
ts.tv_nsec -= 1000000000; |
|
172 |
} |
|
234 |
compute_abs_deadline(&ts, ms); |
|
173 | 235 |
do { |
174 | 236 |
rc = sem_timedwait(&sem->sem, &ts); |
175 | 237 |
} while (rc == -1 && errno == EINTR); |
... | ... | |
181 | 243 |
error_exit(errno, __func__); |
182 | 244 |
} |
183 | 245 |
return 0; |
246 |
#endif |
|
184 | 247 |
} |
185 | 248 |
|
186 | 249 |
void qemu_sem_wait(QemuSemaphore *sem) |
187 | 250 |
{ |
251 |
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) |
|
252 |
pthread_mutex_lock(&sem->lock); |
|
253 |
--sem->count; |
|
254 |
while (sem->count < 0) { |
|
255 |
pthread_cond_wait(&sem->cond, &sem->lock); |
|
256 |
} |
|
257 |
pthread_mutex_unlock(&sem->lock); |
|
258 |
#else |
|
188 | 259 |
int rc; |
189 | 260 |
|
190 | 261 |
do { |
... | ... | |
193 | 264 |
if (rc < 0) { |
194 | 265 |
error_exit(errno, __func__); |
195 | 266 |
} |
267 |
#endif |
|
196 | 268 |
} |
197 | 269 |
|
198 | 270 |
void qemu_thread_create(QemuThread *thread, |
Also available in: Unified diff