qemu-thread: add QemuSemaphore

The new thread pool will use semaphores instead of condition
variables, because QemuCond does not have qemu_cond_timedwait.
(I also like it more this way).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2011-08-08 14:36:41 +02:00
parent c90caf25e2
commit 38b14db34e
5 changed files with 131 additions and 0 deletions

View file

@ -17,6 +17,9 @@
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <sys/time.h>
#include "qemu-thread.h"
static void error_exit(int err, const char *msg)
@ -115,6 +118,83 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
error_exit(err, __func__);
}
void qemu_sem_init(QemuSemaphore *sem, int init)
{
int rc;
rc = sem_init(&sem->sem, 0, init);
if (rc < 0) {
error_exit(errno, __func__);
}
}
void qemu_sem_destroy(QemuSemaphore *sem)
{
int rc;
rc = sem_destroy(&sem->sem);
if (rc < 0) {
error_exit(errno, __func__);
}
}
void qemu_sem_post(QemuSemaphore *sem)
{
int rc;
rc = sem_post(&sem->sem);
if (rc < 0) {
error_exit(errno, __func__);
}
}
int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
{
int rc;
if (ms <= 0) {
/* This is cheaper than sem_timedwait. */
do {
rc = sem_trywait(&sem->sem);
} while (rc == -1 && errno == EINTR);
if (rc == -1 && errno == EAGAIN) {
return -1;
}
} else {
struct timeval tv;
struct timespec ts;
gettimeofday(&tv, NULL);
ts.tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000;
ts.tv_sec = tv.tv_sec + ms / 1000;
if (ts.tv_nsec >= 1000000000) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}
do {
rc = sem_timedwait(&sem->sem, &ts);
} while (rc == -1 && errno == EINTR);
if (rc == -1 && errno == ETIMEDOUT) {
return -1;
}
}
if (rc < 0) {
error_exit(errno, __func__);
}
return 0;
}
void qemu_sem_wait(QemuSemaphore *sem)
{
int rc;
do {
rc = sem_wait(&sem->sem);
} while (rc == -1 && errno == EINTR);
if (rc < 0) {
error_exit(errno, __func__);
}
}
void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg, int mode)