Working on a general-purpose virtual timer interface. This should allow
more consistent time interfaces once it's finished.
This commit is contained in:
parent
f12a510b8b
commit
c0d7138924
75
bochs/iodev/virt_timer.cc
Normal file
75
bochs/iodev/virt_timer.cc
Normal file
@ -0,0 +1,75 @@
|
||||
#include "bochs.h"
|
||||
|
||||
bx_virt_timer_c bx_virt_timer;
|
||||
|
||||
static void
|
||||
bx_virt_timer_c::nullTimer(void* this_ptr) {
|
||||
UNUSED(this_ptr);
|
||||
}
|
||||
|
||||
|
||||
//Get the current virtual time.
|
||||
// This may return the same value on subsequent calls.
|
||||
Bit64u
|
||||
bx_virt_timer_c::get_virtual_time(void) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.time_usec();
|
||||
}
|
||||
}
|
||||
|
||||
//Get the current virtual time.
|
||||
// This will return a monotonically increasing value.
|
||||
Bit64u
|
||||
bx_virt_timer_c::time_usec_sequential(void) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.time_usec_sequential();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Register a timer handler to go off after a given interval.
|
||||
//Register a timer handler to go off with a periodic interval.
|
||||
int
|
||||
bx_virt_timer_c::register_timer( void *this_ptr, bx_timer_handler_t handler,
|
||||
Bit32u useconds,
|
||||
bx_bool continuous, bx_bool active,
|
||||
const char *id) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.register_timer(this_ptr, handler, useconds,
|
||||
continuous, active, id);
|
||||
}
|
||||
}
|
||||
|
||||
//unregister a previously registered timer.
|
||||
unsigned
|
||||
bx_virt_timer_c::unregisterTimer(int timerID) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.unregisterTimer(timerID);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bx_virt_timer_c::start_timers(void) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.start_timers();
|
||||
}
|
||||
}
|
||||
|
||||
//activate a deactivated but registered timer.
|
||||
void
|
||||
bx_virt_timer_c::activate_timer( unsigned timer_index, Bit32u useconds,
|
||||
bx_bool continuous ) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.activate_timer(timer_index, useconds, continuous);
|
||||
}
|
||||
}
|
||||
|
||||
//deactivate (but don't unregister) a currently registered timer.
|
||||
void
|
||||
bx_virt_timer_c::deactivate_timer( unsigned timer_index ) {
|
||||
if(!use_virtual_timers) {
|
||||
return bx_pc_system.deactivate_timer(timer_index);
|
||||
}
|
||||
}
|
||||
|
82
bochs/iodev/virt_timer.h
Normal file
82
bochs/iodev/virt_timer.h
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
#define BX_USE_VIRTUAL_TIMERS 0
|
||||
|
||||
#define BX_MAX_VIRTUAL_TIMERS (15+BX_SMP_PROCESSORS)
|
||||
#define BX_NULL_VIRTUAL_TIMER_HANDLE 100000
|
||||
|
||||
|
||||
class bx_virt_timer_c {
|
||||
private:
|
||||
|
||||
struct {
|
||||
bx_bool inUse; // Timer slot is in-use (currently registered).
|
||||
Bit64u period; // Timer periodocity in virtual useconds.
|
||||
Bit64u timeToFire; // Time to fire next (in virtual useconds).
|
||||
bx_bool active; // 0=inactive, 1=active.
|
||||
bx_bool continuous; // 0=one-shot timer, 1=continuous periodicity.
|
||||
bx_timer_handler_t funct; // A callback function for when the
|
||||
// timer fires.
|
||||
void *this_ptr; // The this-> pointer for C++ callbacks
|
||||
// has to be stored as well.
|
||||
#define BxMaxTimerIDLen 32
|
||||
char id[BxMaxTimerIDLen]; // String ID of timer.
|
||||
} timer[BX_MAX_VIRTUAL_TIMERS];
|
||||
|
||||
unsigned numTimers; // Number of currently allocated timers.
|
||||
|
||||
Bit64u last_ips_time;
|
||||
Bit64u last_virtual_time;
|
||||
Bit64u last_host_time;
|
||||
|
||||
Bit64u initial_ips_time;
|
||||
Bit64u initial_virtual_time;
|
||||
Bit64u initial_host_time;
|
||||
|
||||
Bit64u next_virtual_time;
|
||||
Bit64u next_ips_time;
|
||||
|
||||
Bit64u virtual_time_calls;
|
||||
|
||||
bx_bool use_virtual_timers;
|
||||
|
||||
// A special null timer is always inserted in the timer[0] slot. This
|
||||
// make sure that at least one timer is always active, and that the
|
||||
// duration is always less than a maximum 32-bit integer, so a 32-bit
|
||||
// counter can be used for the current countdown.
|
||||
static const Bit64u NullTimerInterval;
|
||||
static void nullTimer(void* this_ptr);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//Get the current virtual time.
|
||||
// This may return the same value on subsequent calls.
|
||||
Bit64u time_usec(void);
|
||||
|
||||
//Get the current virtual time.
|
||||
// This will return a monotonically increasing value.
|
||||
Bit64u time_usec_sequential(void);
|
||||
|
||||
//Register a timer handler to go off after a given interval.
|
||||
//Register a timer handler to go off with a periodic interval.
|
||||
int register_timer( void *this_ptr, bx_timer_handler_t handler,
|
||||
Bit32u useconds,
|
||||
bx_bool continuous, bx_bool active, const char *id);
|
||||
|
||||
//unregister a previously registered timer.
|
||||
unsigned unregisterTimer(int timerID);
|
||||
|
||||
void start_timers(void);
|
||||
|
||||
//activate a deactivated but registered timer.
|
||||
void activate_timer( unsigned timer_index, Bit32u useconds,
|
||||
bx_bool continuous );
|
||||
|
||||
//deactivate (but don't unregister) a currently registered timer.
|
||||
void deactivate_timer( unsigned timer_index );
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern bx_virt_timer_c bx_virt_timer;
|
Loading…
Reference in New Issue
Block a user