mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 14:45:30 +03:00
Ensure that threads are ready before their preemption timer can be
armed. It was discovered during testing of 'Hatsune Miku Project DIVA: Mega Mix' that if a thread was starting while preemption was being enabled a NULL pointer dereference could occur in the timer_settime call as timer_create may not have been called yet.
This commit is contained in:
parent
a7dc69223b
commit
af5ee96b9a
@ -231,16 +231,25 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
void KThread::ArmPreemptionTimer(std::chrono::nanoseconds timeToFire) {
|
||||
struct itimerspec spec{.it_value = {
|
||||
.tv_nsec = std::min(timeToFire.count(), static_cast<long long>(constant::NsInSecond)),
|
||||
.tv_sec = std::max(std::chrono::duration_cast<std::chrono::seconds>(timeToFire).count() - 1, 0LL),
|
||||
}};
|
||||
timer_settime(preemptionTimer, 0, &spec, nullptr);
|
||||
isPreempted = true;
|
||||
std::unique_lock lock(statusMutex);
|
||||
statusCondition.wait(lock, [this]() { return ready || killed; });
|
||||
if (!killed && running) {
|
||||
struct itimerspec spec{.it_value = {
|
||||
.tv_nsec = std::min(timeToFire.count(), static_cast<long long>(constant::NsInSecond)),
|
||||
.tv_sec = std::max(std::chrono::duration_cast<std::chrono::seconds>(timeToFire).count() - 1, 0LL),
|
||||
}};
|
||||
timer_settime(preemptionTimer, 0, &spec, nullptr);
|
||||
isPreempted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void KThread::DisarmPreemptionTimer() {
|
||||
if (isPreempted) {
|
||||
if (!isPreempted)
|
||||
return;
|
||||
|
||||
std::unique_lock lock(statusMutex);
|
||||
statusCondition.wait(lock, [this]() { return ready || killed; });
|
||||
if (!killed && running) {
|
||||
struct itimerspec spec{};
|
||||
timer_settime(preemptionTimer, 0, &spec, nullptr);
|
||||
isPreempted = false;
|
||||
|
Loading…
Reference in New Issue
Block a user