Revision cb365646

b/cpus.c
37 37
#include "sysemu/qtest.h"
38 38
#include "qemu/main-loop.h"
39 39
#include "qemu/bitmap.h"
40
#include "qemu/seqlock.h"
40 41

  
41 42
#ifndef _WIN32
42 43
#include "qemu/compatfd.h"
......
110 111
static int64_t qemu_icount;
111 112

  
112 113
typedef struct TimersState {
114
    /* Protected by BQL.  */
113 115
    int64_t cpu_ticks_prev;
114 116
    int64_t cpu_ticks_offset;
117

  
118
    /* cpu_clock_offset can be read out of BQL, so protect it with
119
     * this lock.
120
     */
121
    QemuSeqLock vm_clock_seqlock;
115 122
    int64_t cpu_clock_offset;
116 123
    int32_t cpu_ticks_enabled;
117 124
    int64_t dummy;
......
137 144
}
138 145

  
139 146
/* return the host CPU cycle counter and handle stop/restart */
147
/* Caller must hold the BQL */
140 148
int64_t cpu_get_ticks(void)
141 149
{
142 150
    if (use_icount) {
......
157 165
    }
158 166
}
159 167

  
160
/* return the host CPU monotonic timer and handle stop/restart */
161
int64_t cpu_get_clock(void)
168
static int64_t cpu_get_clock_locked(void)
162 169
{
163 170
    int64_t ti;
171

  
164 172
    if (!timers_state.cpu_ticks_enabled) {
165
        return timers_state.cpu_clock_offset;
173
        ti = timers_state.cpu_clock_offset;
166 174
    } else {
167 175
        ti = get_clock();
168
        return ti + timers_state.cpu_clock_offset;
176
        ti += timers_state.cpu_clock_offset;
169 177
    }
178

  
179
    return ti;
170 180
}
171 181

  
172
/* enable cpu_get_ticks() */
182
/* return the host CPU monotonic timer and handle stop/restart */
183
int64_t cpu_get_clock(void)
184
{
185
    int64_t ti;
186
    unsigned start;
187

  
188
    do {
189
        start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
190
        ti = cpu_get_clock_locked();
191
    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
192

  
193
    return ti;
194
}
195

  
196
/* enable cpu_get_ticks()
197
 * Caller must hold BQL which server as mutex for vm_clock_seqlock.
198
 */
173 199
void cpu_enable_ticks(void)
174 200
{
201
    /* Here, the really thing protected by seqlock is cpu_clock_offset. */
202
    seqlock_write_lock(&timers_state.vm_clock_seqlock);
175 203
    if (!timers_state.cpu_ticks_enabled) {
176 204
        timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
177 205
        timers_state.cpu_clock_offset -= get_clock();
178 206
        timers_state.cpu_ticks_enabled = 1;
179 207
    }
208
    seqlock_write_unlock(&timers_state.vm_clock_seqlock);
180 209
}
181 210

  
182 211
/* disable cpu_get_ticks() : the clock is stopped. You must not call
183
   cpu_get_ticks() after that.  */
212
 * cpu_get_ticks() after that.
213
 * Caller must hold BQL which server as mutex for vm_clock_seqlock.
214
 */
184 215
void cpu_disable_ticks(void)
185 216
{
217
    /* Here, the really thing protected by seqlock is cpu_clock_offset. */
218
    seqlock_write_lock(&timers_state.vm_clock_seqlock);
186 219
    if (timers_state.cpu_ticks_enabled) {
187 220
        timers_state.cpu_ticks_offset = cpu_get_ticks();
188
        timers_state.cpu_clock_offset = cpu_get_clock();
221
        timers_state.cpu_clock_offset = cpu_get_clock_locked();
189 222
        timers_state.cpu_ticks_enabled = 0;
190 223
    }
224
    seqlock_write_unlock(&timers_state.vm_clock_seqlock);
191 225
}
192 226

  
193 227
/* Correlation between real and virtual time is always going to be
......
371 405

  
372 406
void configure_icount(const char *option)
373 407
{
408
    seqlock_init(&timers_state.vm_clock_seqlock, NULL);
374 409
    vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
375 410
    if (!option) {
376 411
        return;
b/include/qemu/timer.h
653 653
void init_clocks(void);
654 654

  
655 655
int64_t cpu_get_ticks(void);
656
/* Caller must hold BQL */
656 657
void cpu_enable_ticks(void);
658
/* Caller must hold BQL */
657 659
void cpu_disable_ticks(void);
658 660

  
659 661
static inline int64_t get_ticks_per_sec(void)

Also available in: Unified diff