qemu/tests/test-rfifolock.c
<<
>>
Prefs
   1/*
   2 * RFifoLock tests
   3 *
   4 * Copyright Red Hat, Inc. 2013
   5 *
   6 * Authors:
   7 *  Stefan Hajnoczi    <stefanha@redhat.com>
   8 *
   9 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
  10 * See the COPYING.LIB file in the top-level directory.
  11 */
  12
  13#include <glib.h>
  14#include "qemu-common.h"
  15#include "qemu/rfifolock.h"
  16
  17static void test_nesting(void)
  18{
  19    RFifoLock lock;
  20
  21    /* Trivial test, ensure the lock is recursive */
  22    rfifolock_init(&lock, NULL, NULL);
  23    rfifolock_lock(&lock);
  24    rfifolock_lock(&lock);
  25    rfifolock_lock(&lock);
  26    rfifolock_unlock(&lock);
  27    rfifolock_unlock(&lock);
  28    rfifolock_unlock(&lock);
  29    rfifolock_destroy(&lock);
  30}
  31
  32typedef struct {
  33    RFifoLock lock;
  34    int fd[2];
  35} CallbackTestData;
  36
  37static void rfifolock_cb(void *opaque)
  38{
  39    CallbackTestData *data = opaque;
  40    int ret;
  41    char c = 0;
  42
  43    ret = write(data->fd[1], &c, sizeof(c));
  44    g_assert(ret == 1);
  45}
  46
  47static void *callback_thread(void *opaque)
  48{
  49    CallbackTestData *data = opaque;
  50
  51    /* The other thread holds the lock so the contention callback will be
  52     * invoked...
  53     */
  54    rfifolock_lock(&data->lock);
  55    rfifolock_unlock(&data->lock);
  56    return NULL;
  57}
  58
  59static void test_callback(void)
  60{
  61    CallbackTestData data;
  62    QemuThread thread;
  63    int ret;
  64    char c;
  65
  66    rfifolock_init(&data.lock, rfifolock_cb, &data);
  67    ret = qemu_pipe(data.fd);
  68    g_assert(ret == 0);
  69
  70    /* Hold lock but allow the callback to kick us by writing to the pipe */
  71    rfifolock_lock(&data.lock);
  72    qemu_thread_create(&thread, "callback_thread",
  73                       callback_thread, &data, QEMU_THREAD_JOINABLE);
  74    ret = read(data.fd[0], &c, sizeof(c));
  75    g_assert(ret == 1);
  76    rfifolock_unlock(&data.lock);
  77    /* If we got here then the callback was invoked, as expected */
  78
  79    qemu_thread_join(&thread);
  80    close(data.fd[0]);
  81    close(data.fd[1]);
  82    rfifolock_destroy(&data.lock);
  83}
  84
  85int main(int argc, char **argv)
  86{
  87    g_test_init(&argc, &argv, NULL);
  88    g_test_add_func("/nesting", test_nesting);
  89    g_test_add_func("/callback", test_callback);
  90    return g_test_run();
  91}
  92