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,
|