gerrard2461
gerrard2461

Reputation: 304

time of executing block in qemu

i want to ask a question about getting time information when executing a translation block in QEMU

in fact im using this function

qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

but i'm not sure that it returns the time of executing a translation block in the guest processor.

So can someone give me some hints ?

thanx

Upvotes: 3

Views: 2412

Answers (1)

Jettatura
Jettatura

Reputation: 564

Non KVM, soft-mmu qemu !!!:

qemu_clock_get_ns(QEMUClockType type) represent elapsed nano-seconds for specified qemu reference clock. There are several reference clocks: realtime, virtual, host, etc. QEMU_CLOCK_VIRTUAL is counter that explicitly driven by qemu main loop: one tick of that clock is the emulated quantum of time (nano-second).

Details: QEMU assume that:

1 guest instruction counter tick = 1 emulated nano second << icount_time_shift

icount_time_shift is specfied by "-icount" comand line option, it is 3 by default.

All qemu timers implemented as deadlines (in QEMU_CLOCK_VIRTUAL units), and qemu execute translation blocks from one deadline to another. Straight conversation from ns to icount provide deteremenistic tb generation: QEMU main loop advance that clock accordance to num of instructions that was executed at translation block/chain (see cpu_exec.c, here abstract pseudo code):

cpu_exec(CPUState env):

  # jump here if any synchronous exception occurs: page fault, protection and etc
  if(setjmp(env) == exeption) 
      ;#fall through

  for(;;):
    # if exception/interrupt is pending then handle it here
    take_exception_or_interrupt();

    while(no_interrupts()) {
        # get num instructions that left till next deadline
        icount_extra = get_icount_limit();

        # find/generate tb accordnace to icount_extra
        # Also every instruction that access to IO is the last instruction at block.
        # if  access to IO cause interrupt we handle it on next iteration
        tb = find_tb(env, icount_extra);

        # execute tb or tb chain
        execute(env, tb);

        # increment QEMU_CLOCK_VIRTUAL accordance to guest instructions was executed
        # (syncronise with iothread)
        update_clock(tb.executed_instr);
        # we will take all interrupts at next iteration 

Intervals provided by QEMU_CLOCK_VIRTUAL are used at all models of guest timers/counters: for example if you set you board system counter frequency to 62 MHz, then qemu do single increment of that counter per 16 increments of QEMU_CLOCK_VIRTUAL.

Then you can use qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) to obtain emulated nano second intervals at you guest model.

Upvotes: 4

Related Questions