mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 18:06:50 +00:00
vbox5-generic: use pthread_cond_timedwait for halt
use similar implementation as introduced for vbox5-nova vbox5-nova: avoid Blocking_canceled exception Related to #3810
This commit is contained in:
parent
072a00ba18
commit
851b842033
@ -383,7 +383,7 @@ int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation,
|
||||
|
||||
Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu);
|
||||
Assert(vcpu_handler);
|
||||
vcpu_handler->halt(u64NowGip + ns_diff);
|
||||
vcpu_handler->halt(ns_diff);
|
||||
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
@ -1161,13 +1161,6 @@ class Periodic_gip
|
||||
Libc::with_libc([&] () {
|
||||
rttimer_func(nullptr, rttimer_obj, 0); });
|
||||
}
|
||||
|
||||
for (Vcpu_handler *vcpu_handler = vcpu_handler_list().first();
|
||||
vcpu_handler;
|
||||
vcpu_handler = vcpu_handler->next())
|
||||
{
|
||||
vcpu_handler->check_time();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -334,8 +334,8 @@ int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation,
|
||||
|
||||
case VMMR0_DO_GVMM_SCHED_HALT:
|
||||
{
|
||||
const uint64_t u64NowGip = RTTimeNanoTS();
|
||||
const uint64_t ns_diff = u64Arg > u64NowGip ? u64Arg - u64NowGip : 0;
|
||||
uint64_t const u64NowGip = RTTimeNanoTS();
|
||||
uint64_t const ns_diff = u64Arg > u64NowGip ? u64Arg - u64NowGip : 0;
|
||||
|
||||
if (!ns_diff)
|
||||
return VINF_SUCCESS;
|
||||
|
@ -70,10 +70,9 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element
|
||||
Genode::Semaphore _sem_handler;
|
||||
Genode::Vm_state *_state { nullptr };
|
||||
|
||||
/* halt / wakeup handling with timeout support */
|
||||
Genode::Mutex _r0_mutex;
|
||||
Genode::Semaphore _r0_block;
|
||||
Genode::uint64_t _r0_wakeup_abs { 0 };
|
||||
pthread_cond_t _cond_wait;
|
||||
pthread_mutex_t _mutex;
|
||||
|
||||
|
||||
/* information used for NPT/EPT handling */
|
||||
Genode::addr_t npt_ept_exit_addr { 0 };
|
||||
@ -111,6 +110,29 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element
|
||||
INTERRUPT_STATE_NONE = 0U,
|
||||
};
|
||||
|
||||
timespec add_timespec_ns(timespec a, uint64_t ns) const
|
||||
{
|
||||
enum { NSEC_PER_SEC = 1'000'000'000ull };
|
||||
|
||||
long sec = a.tv_sec;
|
||||
|
||||
while (a.tv_nsec >= NSEC_PER_SEC) {
|
||||
a.tv_nsec -= NSEC_PER_SEC;
|
||||
sec++;
|
||||
}
|
||||
while (ns >= NSEC_PER_SEC) {
|
||||
ns -= NSEC_PER_SEC;
|
||||
sec++;
|
||||
}
|
||||
|
||||
long nsec = a.tv_nsec + ns;
|
||||
while (nsec >= NSEC_PER_SEC) {
|
||||
nsec -= NSEC_PER_SEC;
|
||||
sec++;
|
||||
}
|
||||
return timespec { sec, nsec };
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int map_memory(Genode::Vm_connection &vm_session,
|
||||
@ -675,7 +697,15 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element
|
||||
_ep(env, stack_size,
|
||||
Genode::String<12>("EP-EMT-", cpu_id).string(), location),
|
||||
_cpu_id(cpu_id)
|
||||
{ }
|
||||
{
|
||||
pthread_mutexattr_t _attr;
|
||||
pthread_mutexattr_init(&_attr);
|
||||
|
||||
pthread_cond_init(&_cond_wait, nullptr);
|
||||
|
||||
pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_ERRORCHECK);
|
||||
pthread_mutex_init(&_mutex, &_attr);
|
||||
}
|
||||
|
||||
unsigned int cpu_id() { return _cpu_id; }
|
||||
|
||||
@ -722,37 +752,24 @@ class Vcpu_handler : public Genode::List<Vcpu_handler>::Element
|
||||
#endif
|
||||
}
|
||||
|
||||
void check_time()
|
||||
void halt(Genode::uint64_t const wait_ns)
|
||||
{
|
||||
{
|
||||
Genode::Mutex::Guard guard(_r0_mutex);
|
||||
/* calculate timeout */
|
||||
timespec ts { 0, 0 };
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts = add_timespec_ns(ts, wait_ns);
|
||||
|
||||
const uint64_t u64NowGip = RTTimeNanoTS();
|
||||
if (!_r0_wakeup_abs || _r0_wakeup_abs >= u64NowGip)
|
||||
return;
|
||||
}
|
||||
|
||||
wake_up();
|
||||
}
|
||||
|
||||
void halt(Genode::uint64_t rttime_abs)
|
||||
{
|
||||
{
|
||||
Genode::Mutex::Guard guard(_r0_mutex);
|
||||
_r0_wakeup_abs = rttime_abs;
|
||||
}
|
||||
|
||||
_r0_block.down();
|
||||
/* wait for condition or timeout */
|
||||
pthread_mutex_lock(&_mutex);
|
||||
pthread_cond_timedwait(&_cond_wait, &_mutex, &ts);
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
void wake_up()
|
||||
{
|
||||
{
|
||||
Genode::Mutex::Guard guard(_r0_mutex);
|
||||
_r0_wakeup_abs = 0;
|
||||
}
|
||||
|
||||
_r0_block.up();
|
||||
pthread_mutex_lock(&_mutex);
|
||||
pthread_cond_signal(&_cond_wait);
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
int run_hw(PVMR0 pVMR0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user