mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
vbox: replace alarm_timer thread with trigger_once
Instead of using the alarm_timer thread we use our own timer thread that uses a kernel semaphore on Nova. On all other platforms a timer connection and trigger_once is used. Fixes #1727.
This commit is contained in:
parent
f7ad6cf4e6
commit
f9a64b663c
@ -16,6 +16,7 @@
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/semaphore.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <VBox/vmm/vm.h>
|
||||
@ -101,6 +102,27 @@ uint64_t genode_cpu_hz() {
|
||||
}
|
||||
|
||||
|
||||
void genode_update_tsc(void (*update_func)(void), unsigned long update_us)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Timer::Connection timer;
|
||||
Signal_context sig_ctx;
|
||||
Signal_receiver sig_rec;
|
||||
Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx);
|
||||
|
||||
timer.sigh(sig_cap);
|
||||
timer.trigger_once(update_us);
|
||||
|
||||
for (;;) {
|
||||
Signal s = sig_rec.wait_for_signal();
|
||||
update_func();
|
||||
|
||||
timer.trigger_once(update_us);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Vmm_memory::revoke_from_vm(Region *r)
|
||||
{
|
||||
PWRN("%s unimplemented", __func__);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <rom_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
#include <vmm/vcpu_thread.h>
|
||||
#include <vmm/vcpu_dispatcher.h>
|
||||
@ -189,6 +190,32 @@ uint64_t genode_cpu_hz()
|
||||
}
|
||||
|
||||
|
||||
void genode_update_tsc(void (*update_func)(void), unsigned long update_us)
|
||||
{
|
||||
using namespace Genode;
|
||||
using namespace Nova;
|
||||
|
||||
enum { TSC_FACTOR = 1000ULL };
|
||||
|
||||
Genode::addr_t sem = Thread_base::myself()->tid().exc_pt_sel + Nova::SM_SEL_EC;
|
||||
unsigned long tsc_khz = (genode_cpu_hz() / 1000) / TSC_FACTOR;
|
||||
|
||||
Trace::Timestamp us_64 = update_us;
|
||||
|
||||
for (;;) {
|
||||
update_func();
|
||||
|
||||
Trace::Timestamp now = Trace::timestamp();
|
||||
|
||||
/* block until timeout fires or it gets canceled */
|
||||
unsigned long long tsc_absolute = now + us_64 * tsc_khz;
|
||||
Genode::uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, tsc_absolute);
|
||||
if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT)
|
||||
nova_die();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Vmm_memory::revoke_from_vm(Region *r)
|
||||
{
|
||||
Assert(r);
|
||||
|
@ -39,8 +39,7 @@ struct Attached_gip : Genode::Attached_ram_dataspace
|
||||
|
||||
|
||||
enum {
|
||||
UPDATE_HZ = 100, /* Hz */
|
||||
/* Note: UPDATE_MS < 10ms is not supported by alarm timer, take care !*/
|
||||
UPDATE_HZ = 1000,
|
||||
UPDATE_MS = 1000 / UPDATE_HZ,
|
||||
UPDATE_NS = UPDATE_MS * 1000 * 1000,
|
||||
};
|
||||
@ -49,9 +48,11 @@ enum {
|
||||
PSUPGLOBALINFOPAGE g_pSUPGlobalInfoPage;
|
||||
|
||||
|
||||
class Periodic_GIP : public Genode::Alarm {
|
||||
struct Periodic_gip : public Genode::Thread<4096>
|
||||
{
|
||||
Periodic_gip() : Thread("periodic_gip") { start(); }
|
||||
|
||||
bool on_alarm(unsigned) override
|
||||
static void update()
|
||||
{
|
||||
/**
|
||||
* We're using rdtsc here since timer_session->elapsed_ms produces
|
||||
@ -98,11 +99,10 @@ class Periodic_GIP : public Genode::Alarm {
|
||||
* read struct SUPGIPCPU description for more details.
|
||||
*/
|
||||
ASMAtomicIncU32(&cpu->u32TransactionId);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void entry() override { genode_update_tsc(update, UPDATE_MS * 1000); }
|
||||
};
|
||||
|
||||
|
||||
int SUPR3Init(PSUPDRVSESSION *ppSession)
|
||||
@ -149,8 +149,7 @@ int SUPR3Init(PSUPDRVSESSION *ppSession)
|
||||
cpu->idApic = 0;
|
||||
|
||||
/* schedule periodic call of GIP update function */
|
||||
static Periodic_GIP alarm;
|
||||
Genode::Timeout_thread::alarm_timer()->schedule(&alarm, UPDATE_MS);
|
||||
static Periodic_gip periodic_gip;
|
||||
|
||||
initialized = true;
|
||||
|
||||
|
@ -35,6 +35,7 @@ bool create_emt_vcpu(pthread_t * pthread, size_t stack,
|
||||
|
||||
|
||||
uint64_t genode_cpu_hz();
|
||||
void genode_update_tsc(void (*update_func)(void), unsigned long update_us);
|
||||
|
||||
Genode::Cpu_session * get_vcpu_cpu_session();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user