Skip to content

Commit 5f1676d

Browse files
authored
IOP: Fix WakeupThread waking up threads with other waittypes (#4047)
StreamListThread should have been deadlocked waiting for the uninitialized LfoList semaphore, instead it'd get woken up by WakeupThread erroneously.
1 parent fde7b3b commit 5f1676d

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

game/overlord/jak2/streamlist.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,15 +407,20 @@ u32 StreamListThread() {
407407
}
408408
uVar9 = uVar9 + 1;
409409
} while (uVar9 < 4);
410+
410411
SignalSema(EEStreamsList.sema);
411412
RequestedStreamsList.unk2_init0 = 1;
412413
SignalSema(RequestedStreamsList.sema);
414+
413415
WaitSema(EEPlayList.sema);
414416
CheckPlayList(&EEPlayList);
415417
SignalSema(EEPlayList.sema);
416-
WaitSema(LfoList.sema);
417-
CheckLfoList(&LfoList);
418-
SignalSema(LfoList.sema);
418+
419+
// FIXME LfoList hasn't been initialised because of unimplemented
420+
// streamlfo functions.
421+
// WaitSema(LfoList.sema);
422+
// CheckLfoList(&LfoList);
423+
// SignalSema(LfoList.sema);
419424
} while (true);
420425
return 0;
421426
}

game/system/IOP_Kernel.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,14 @@ void IOP_Kernel::DelayThread(u32 usec) {
101101
void IOP_Kernel::SleepThread() {
102102
ASSERT(_currentThread);
103103

104-
_currentThread->state = IopThread::State::Suspend;
104+
if (_currentThread->wakeupCount > 0) {
105+
_currentThread->wakeupCount--;
106+
return;
107+
}
108+
109+
_currentThread->state = IopThread::State::Wait;
110+
_currentThread->waitType = IopThread::Wait::Sleep;
111+
105112
leaveThread();
106113
}
107114

@@ -116,6 +123,13 @@ void IOP_Kernel::YieldThread() {
116123
*/
117124
void IOP_Kernel::WakeupThread(s32 id) {
118125
ASSERT(id > 0);
126+
127+
auto& thread = threads.at(id);
128+
if (thread.state != IopThread::State::Wait || thread.waitType != IopThread::Wait::Sleep) {
129+
thread.wakeupCount++;
130+
return;
131+
}
132+
119133
threads.at(id).state = IopThread::State::Ready;
120134
}
121135

game/system/IOP_Kernel.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct IopThread {
5353
Dormant,
5454
};
5555

56-
enum class Wait { None, Semaphore, Delay, Messagebox, EventFlag };
56+
enum class Wait { None, Sleep, Semaphore, Delay, Messagebox, EventFlag };
5757

5858
IopThread(std::string n, void (*f)(), s32 ID, u32 pri)
5959
: name(std::move(n)), function(f), priority(pri), thID(ID) {
@@ -71,6 +71,7 @@ struct IopThread {
7171
time_stamp resumeTime = {};
7272
u32 priority = 0;
7373
s32 thID = -1;
74+
s32 wakeupCount = 0;
7475
};
7576

7677
struct Semaphore {

0 commit comments

Comments
 (0)