qemu-thread: add QemuEvent

This emulates Win32 manual-reset events using futexes or conditional
variables.  Typical ways to use them are with multi-producer,
single-consumer data structures, to test for a complex condition whose
elements come from different threads:

    for (;;) {
        qemu_event_reset(ev);
        ... test complex condition ...
        if (condition is true) {
            break;
        }
        qemu_event_wait(ev);
    }

Or more efficiently (but with some duplication):

    ... evaluate condition ...
    while (!condition) {
        qemu_event_reset(ev);
        ... evaluate condition ...
        if (!condition) {
            qemu_event_wait(ev);
            ... evaluate condition ...
        }
    }

QemuEvent provides a very fast userspace path in the common case when
no other thread is waiting, or the event is not changing state.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2013-09-25 14:20:59 +08:00
parent cb365646a9
commit c7c4d063f5
5 changed files with 161 additions and 0 deletions

View file

@ -227,6 +227,32 @@ void qemu_sem_wait(QemuSemaphore *sem)
}
}
void qemu_event_init(QemuEvent *ev, bool init)
{
/* Manual reset. */
ev->event = CreateEvent(NULL, TRUE, init, NULL);
}
void qemu_event_destroy(QemuEvent *ev)
{
CloseHandle(ev->event);
}
void qemu_event_set(QemuEvent *ev)
{
SetEvent(ev->event);
}
void qemu_event_reset(QemuEvent *ev)
{
ResetEvent(ev->event);
}
void qemu_event_wait(QemuEvent *ev)
{
WaitForSingleObject(ev->event, INFINITE);
}
struct QemuThreadData {
/* Passed to win32_start_routine. */
void *(*start_routine)(void *);