mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
kern: minor behavioral fixes to condvar/address arbiter
This commit is contained in:
parent
c547c7f0e7
commit
388f9e6455
2 changed files with 50 additions and 26 deletions
|
@ -73,15 +73,16 @@ namespace ams::kern {
|
||||||
s32 num_waiters = 0;
|
s32 num_waiters = 0;
|
||||||
{
|
{
|
||||||
KScopedSchedulerLock sl;
|
KScopedSchedulerLock sl;
|
||||||
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
|
||||||
|
|
||||||
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
|
||||||
|
|
||||||
/* Check the userspace value. */
|
/* Check the userspace value. */
|
||||||
s32 user_value;
|
s32 user_value;
|
||||||
R_UNLESS(UpdateIfEqual(std::addressof(user_value), addr, value, value + 1), svc::ResultInvalidCurrentMemory());
|
R_UNLESS(UpdateIfEqual(std::addressof(user_value), addr, value, value + 1), svc::ResultInvalidCurrentMemory());
|
||||||
R_UNLESS(user_value == value, svc::ResultInvalidState());
|
R_UNLESS(user_value == value, svc::ResultInvalidState());
|
||||||
|
|
||||||
|
g_cv_arbiter_compare_thread.SetupForAddressArbiterCompare(addr, -1);
|
||||||
|
|
||||||
|
auto it = this->tree.nfind(g_cv_arbiter_compare_thread);
|
||||||
|
|
||||||
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
|
while ((it != this->tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
KThread *target_thread = std::addressof(*it);
|
KThread *target_thread = std::addressof(*it);
|
||||||
target_thread->SetSyncedObject(nullptr, ResultSuccess());
|
target_thread->SetSyncedObject(nullptr, ResultSuccess());
|
||||||
|
@ -108,26 +109,54 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Determine the updated value. */
|
/* Determine the updated value. */
|
||||||
s32 new_value;
|
s32 new_value;
|
||||||
if (count <= 0) {
|
if (GetTargetFirmware() >= TargetFirmware_7_0_0) {
|
||||||
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
if (count <= 0) {
|
||||||
new_value = value - 1;
|
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
|
new_value = value - 2;
|
||||||
|
} else {
|
||||||
|
new_value = value + 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
new_value = value + 1;
|
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
|
auto tmp_it = it;
|
||||||
|
s32 tmp_num_waiters = 0;
|
||||||
|
while ((++tmp_it != this->tree.end()) && (tmp_it->GetAddressArbiterKey() == addr)) {
|
||||||
|
if ((tmp_num_waiters++) >= count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_num_waiters < count) {
|
||||||
|
new_value = value - 1;
|
||||||
|
} else {
|
||||||
|
new_value = value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new_value = value + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto tmp_it = it;
|
if (count <= 0) {
|
||||||
int tmp_num_waiters = 0;
|
if ((it != this->tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
while ((tmp_it != this->tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && (tmp_num_waiters < count + 1)) {
|
new_value = value - 1;
|
||||||
++tmp_num_waiters;
|
} else {
|
||||||
++tmp_it;
|
new_value = value + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp_num_waiters == 0) {
|
|
||||||
new_value = value + 1;
|
|
||||||
} else if (tmp_num_waiters <= count) {
|
|
||||||
new_value = value - 1;
|
|
||||||
} else {
|
} else {
|
||||||
new_value = value;
|
auto tmp_it = it;
|
||||||
|
s32 tmp_num_waiters = 0;
|
||||||
|
while ((tmp_it != this->tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && (tmp_num_waiters < count + 1)) {
|
||||||
|
++tmp_num_waiters;
|
||||||
|
++tmp_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_num_waiters == 0) {
|
||||||
|
new_value = value + 1;
|
||||||
|
} else if (tmp_num_waiters <= count) {
|
||||||
|
new_value = value - 1;
|
||||||
|
} else {
|
||||||
|
new_value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,13 +205,8 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close threads in the list. */
|
/* Close threads in the list. */
|
||||||
if (num_waiters > MaxThreads) {
|
for (auto it = thread_list.begin(); it != thread_list.end(); it = thread_list.erase(it)) {
|
||||||
auto it = thread_list.begin();
|
(*it).Close();
|
||||||
while (it != thread_list.end()) {
|
|
||||||
KThread *thread = std::addressof(*it);
|
|
||||||
thread->Close();
|
|
||||||
it = thread_list.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue