aboutsummaryrefslogtreecommitdiff
path: root/tests/ptimer-test-stubs.c
blob: e935a1395e792ad8863d237d2f208564f36676ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Stubs for the ptimer-test
 *
 * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "sysemu/replay.h"
#include "migration/vmstate.h"
#include "sysemu/cpu-timers.h"

#include "ptimer-test.h"

const VMStateInfo vmstate_info_uint8;
const VMStateInfo vmstate_info_uint32;
const VMStateInfo vmstate_info_uint64;
const VMStateInfo vmstate_info_int64;
const VMStateInfo vmstate_info_timer;

struct QEMUBH {
    QEMUBHFunc *cb;
    void *opaque;
};

QEMUTimerListGroup main_loop_tlg;

int64_t ptimer_test_time_ns;

/* under qtest_enabled(), will not artificially limit period - see hw/core/ptimer.c. */
int use_icount;
bool qtest_allowed;

void timer_init_full(QEMUTimer *ts,
                     QEMUTimerListGroup *timer_list_group, QEMUClockType type,
                     int scale, int attributes,
                     QEMUTimerCB *cb, void *opaque)
{
    if (!timer_list_group) {
        timer_list_group = &main_loop_tlg;
    }
    ts->timer_list = timer_list_group->tl[type];
    ts->cb = cb;
    ts->opaque = opaque;
    ts->scale = scale;
    ts->attributes = attributes;
    ts->expire_time = -1;
}

void timer_mod(QEMUTimer *ts, int64_t expire_time)
{
    QEMUTimerList *timer_list = ts->timer_list;
    QEMUTimer *t = &timer_list->active_timers;

    while (t->next != NULL) {
        if (t->next == ts) {
            break;
        }

        t = t->next;
    }

    ts->expire_time = MAX(expire_time * ts->scale, 0);
    ts->next = NULL;
    t->next = ts;
}

void timer_del(QEMUTimer *ts)
{
    QEMUTimerList *timer_list = ts->timer_list;
    QEMUTimer *t = &timer_list->active_timers;

    while (t->next != NULL) {
        if (t->next == ts) {
            t->next = ts->next;
            return;
        }

        t = t->next;
    }
}

int64_t qemu_clock_get_ns(QEMUClockType type)
{
    return ptimer_test_time_ns;
}

int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask)
{
    QEMUTimerList *timer_list = main_loop_tlg.tl[QEMU_CLOCK_VIRTUAL];
    QEMUTimer *t = timer_list->active_timers.next;
    int64_t deadline = -1;

    while (t != NULL) {
        if (deadline == -1) {
            deadline = t->expire_time;
        } else {
            deadline = MIN(deadline, t->expire_time);
        }

        t = t->next;
    }

    return deadline;
}

QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
{
    QEMUBH *bh = g_new(QEMUBH, 1);

    bh->cb = cb;
    bh->opaque = opaque;

    return bh;
}

void qemu_bh_delete(QEMUBH *bh)
{
    g_free(bh);
}

void replay_bh_schedule_event(QEMUBH *bh)
{
    bh->cb(bh->opaque);
}