Merge pull request #5591 from unknownbrackets/io-thread

Handle concurrent sync io operations better
This commit is contained in:
Henrik Rydgård committed 2014-03-03 13:30:35 +07:00
commit dc2f28f899
3 files changed
+45 -7

No files matched your search

+34 -7
View File
@@ -638,7 +638,7 @@ void __IoSchedSync(FileNode *f, int fd, int usec) {
u64 param = ((u64)__KernelGetCurThread()) << 32 | fd;
CoreTiming::ScheduleEvent(usToCycles(usec), syncNotifyEvent, param);
f->pendingAsyncResult = true;
f->pendingAsyncResult = false;
f->hasAsyncResult = false;
}
@@ -742,7 +742,17 @@ bool __IoRead(int &result, int id, u32 data_addr, int size) {
if (f->npdrm) {
result = npdrmRead(f, data, size);
return true;
} else if (__KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE) {
}
bool useThread = __KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE;
if (useThread) {
// If there's a pending operation on this file, wait for it to finish and don't overwrite it.
useThread = !ioManager.HasOperation(f->handle);
if (!useThread) {
ioManager.SyncThread();
}
}
if (useThread) {
AsyncIOEvent ev = IO_EVENT_READ;
ev.handle = f->handle;
ev.buf = data;
@@ -754,10 +764,13 @@ bool __IoRead(int &result, int id, u32 data_addr, int size) {
return true;
}
} else {
ERROR_LOG_REPORT(SCEIO, "sceIoRead Reading into bad pointer %08x", data_addr);
// TODO: Returning 0 because it wasn't being sign-extended in async result before.
// What should this do?
result = 0;
if (size != 0) {
// TODO: For some combinations of bad pointer + size, SCE_KERNEL_ERROR_ILLEGAL_ADDR.
// Seems like only for kernel RAM. For most cases, it really is -1.
result = -1;
} else {
result = 0;
}
return true;
}
} else {
@@ -854,7 +867,16 @@ bool __IoWrite(int &result, int id, u32 data_addr, int size) {
result = ERROR_KERNEL_BAD_FILE_DESCRIPTOR;
return true;
}
if (__KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE) {
bool useThread = __KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE;
if (useThread) {
// If there's a pending operation on this file, wait for it to finish and don't overwrite it.
useThread = !ioManager.HasOperation(f->handle);
if (!useThread) {
ioManager.SyncThread();
}
}
if (useThread) {
AsyncIOEvent ev = IO_EVENT_WRITE;
ev.handle = f->handle;
ev.buf = (u8 *) data_ptr;
@@ -1005,6 +1027,11 @@ u32 npdrmLseek(FileNode *f, s32 where, FileMove whence)
s64 __IoLseekDest(FileNode *f, s64 offset, int whence, FileMove &seek) {
seek = FILEMOVE_BEGIN;
// Let's make sure this isn't incorrect mid-operation.
if (ioManager.HasOperation(f->handle)) {
ioManager.SyncThread();
}
s64 newPos = 0;
switch (whence) {
case 0:
+10
View File
@@ -21,6 +21,16 @@
#include "Core/HW/AsyncIOManager.h"
#include "Core/FileSystems/MetaFileSystem.h"
bool AsyncIOManager::HasOperation(u32 handle) {
if (resultsPending_.find(handle) != resultsPending_.end()) {
return true;
}
if (results_.find(handle) != results_.end()) {
return true;
}
return false;
}
void AsyncIOManager::ScheduleOperation(AsyncIOEvent ev) {
lock_guard guard(resultsLock_);
if (!resultsPending_.insert(ev.handle).second) {
+1
View File
@@ -51,6 +51,7 @@ class AsyncIOManager : public IOThreadEventQueue {
public:
void DoState(PointerWrap &p);
bool HasOperation(u32 handle);
void ScheduleOperation(AsyncIOEvent ev);
void Shutdown();