mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 20:31:48 +01:00
Fix minor inaccuracy with VMM and mutexes
This commit fixes a tiny inaccuracy with the VMM which was a problem with block insertion, The mutexes on the other hand had a minor issue regarding owner checks.
This commit is contained in:
parent
41ddaf7f33
commit
f4968793b8
@ -93,6 +93,9 @@ namespace skyline::kernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::InsertBlock(ChunkDescriptor *chunk, const BlockDescriptor block) {
|
void MemoryManager::InsertBlock(ChunkDescriptor *chunk, const BlockDescriptor block) {
|
||||||
|
if(chunk->address + chunk->size < block.address + block.size)
|
||||||
|
throw exception("InsertBlock: Inserting block past chunk end is not allowed");
|
||||||
|
|
||||||
for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) {
|
for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) {
|
||||||
if (iter->address <= block.address) {
|
if (iter->address <= block.address) {
|
||||||
if ((iter->address + iter->size) > block.address) {
|
if ((iter->address + iter->size) > block.address) {
|
||||||
@ -107,25 +110,10 @@ namespace skyline::kernel {
|
|||||||
iter->size = iter->address - block.address;
|
iter->size = iter->address - block.address;
|
||||||
chunk->blockList.insert(std::next(iter), {block, endBlock});
|
chunk->blockList.insert(std::next(iter), {block, endBlock});
|
||||||
}
|
}
|
||||||
} else if (std::next(iter) != chunk->blockList.end()) {
|
|
||||||
auto nextIter = std::next(iter);
|
|
||||||
auto nextEnd = nextIter->address + nextIter->size;
|
|
||||||
|
|
||||||
if(nextEnd > block.address) {
|
|
||||||
iter->size = block.address - iter->address;
|
|
||||||
nextIter->address = block.address + block.size;
|
|
||||||
nextIter->size = nextEnd - nextIter->address;
|
|
||||||
|
|
||||||
chunk->blockList.insert(nextIter, block);
|
|
||||||
} else {
|
|
||||||
throw exception("InsertBlock: Inserting block across more than one block is not allowed");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw exception("InsertBlock: Inserting block with end past chunk end is not allowed");
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw exception("InsertBlock: Block offset not present within current block list");
|
throw exception("InsertBlock: Block offset not present within current block list");
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ namespace skyline::kernel::svc {
|
|||||||
if (state.process->MutexLock(address, ownerHandle))
|
if (state.process->MutexLock(address, ownerHandle))
|
||||||
state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", address);
|
state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", address);
|
||||||
else
|
else
|
||||||
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex at 0x{:X}", address);
|
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex or didn't have waiter flag at 0x{:X}", address);
|
||||||
|
|
||||||
state.ctx->registers.w0 = constant::status::Success;
|
state.ctx->registers.w0 = constant::status::Success;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ namespace skyline::kernel::type {
|
|||||||
Registers fregs{
|
Registers fregs{
|
||||||
.x0 = CLONE_THREAD | CLONE_SIGHAND | CLONE_PTRACE | CLONE_FS | CLONE_VM | CLONE_FILES | CLONE_IO,
|
.x0 = CLONE_THREAD | CLONE_SIGHAND | CLONE_PTRACE | CLONE_FS | CLONE_VM | CLONE_FILES | CLONE_IO,
|
||||||
.x1 = stackTop,
|
.x1 = stackTop,
|
||||||
.x3 = tlsMem->Map(0, size, memory::Permission{ true, true, false }),
|
.x3 = tlsMem->Map(0, size, memory::Permission{true, true, false}),
|
||||||
.x8 = __NR_clone,
|
.x8 = __NR_clone,
|
||||||
.x5 = reinterpret_cast<u64>(&guest::GuestEntry),
|
.x5 = reinterpret_cast<u64>(&guest::GuestEntry),
|
||||||
.x6 = entryPoint,
|
.x6 = entryPoint,
|
||||||
@ -203,10 +203,13 @@ namespace skyline::kernel::type {
|
|||||||
auto mtx = GetPointer<u32>(address);
|
auto mtx = GetPointer<u32>(address);
|
||||||
auto &mtxWaiters = mutexes[address];
|
auto &mtxWaiters = mutexes[address];
|
||||||
|
|
||||||
|
if (mtxWaiters.empty()) {
|
||||||
u32 mtxExpected = 0;
|
u32 mtxExpected = 0;
|
||||||
if (__atomic_compare_exchange_n(mtx, &mtxExpected, (constant::MtxOwnerMask & state.thread->handle) | (mtxWaiters.empty() ? 0 : ~constant::MtxOwnerMask), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
|
if (__atomic_compare_exchange_n(mtx, &mtxExpected, (constant::MtxOwnerMask & state.thread->handle), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
|
||||||
return true;
|
return true;
|
||||||
if (owner && (__atomic_load_n(mtx, __ATOMIC_SEQ_CST) != (owner | ~constant::MtxOwnerMask)))
|
}
|
||||||
|
|
||||||
|
if (__atomic_load_n(mtx, __ATOMIC_SEQ_CST) != (owner | ~constant::MtxOwnerMask))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::shared_ptr<WaitStatus> status;
|
std::shared_ptr<WaitStatus> status;
|
||||||
@ -245,7 +248,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
u32 mtxExpected = (constant::MtxOwnerMask & state.thread->handle) | ~constant::MtxOwnerMask;
|
u32 mtxExpected = (constant::MtxOwnerMask & state.thread->handle) | ~constant::MtxOwnerMask;
|
||||||
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
|
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
|
||||||
mtxExpected = constant::MtxOwnerMask & state.thread->handle;
|
mtxExpected &= constant::MtxOwnerMask;
|
||||||
|
|
||||||
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
|
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
|
||||||
return false;
|
return false;
|
||||||
@ -277,14 +280,15 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
bool timedOut{};
|
|
||||||
|
|
||||||
|
bool timedOut{};
|
||||||
auto start = utils::GetTimeNs();
|
auto start = utils::GetTimeNs();
|
||||||
while (!status->flag)
|
while (!status->flag)
|
||||||
if ((utils::GetTimeNs() - start) >= timeout)
|
if ((utils::GetTimeNs() - start) >= timeout)
|
||||||
timedOut = true;
|
timedOut = true;
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
|
||||||
if (!status->flag)
|
if (!status->flag)
|
||||||
timedOut = false;
|
timedOut = false;
|
||||||
else
|
else
|
||||||
|
@ -30,6 +30,5 @@ class LicenseDialog : DialogFragment() {
|
|||||||
|
|
||||||
license_url.text = libraryUrl
|
license_url.text = libraryUrl
|
||||||
license_content.text = libraryLicense
|
license_content.text = libraryLicense
|
||||||
license_content.movementMethod = ScrollingMovementMethod()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user