CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/HLE/HLEHelperThread.cpp
Views: 1401
1
// Copyright (c) 2014- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#include "Common/Serialize/Serializer.h"
19
#include "Common/Serialize/SerializeFuncs.h"
20
#include "Core/CoreTiming.h"
21
#include "Core/MemMapHelpers.h"
22
#include "Core/HLE/HLE.h"
23
#include "Core/HLE/HLEHelperThread.h"
24
#include "Core/HLE/KernelWaitHelpers.h"
25
#include "Core/HLE/sceKernelThread.h"
26
#include "Core/HLE/sceKernelMemory.h"
27
#include "Core/MIPS/MIPSCodeUtils.h"
28
29
HLEHelperThread::HLEHelperThread() : id_(0), entry_(0) {
30
}
31
32
HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[], u32 instrCount, u32 prio, int stacksize) {
33
u32 instrBytes = instrCount * sizeof(u32);
34
u32 totalBytes = instrBytes + sizeof(u32) * 2;
35
AllocEntry(totalBytes);
36
Memory::Memcpy(entry_, instructions, instrBytes, "HelperMIPS");
37
38
// Just to simplify things, we add the return here.
39
Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0);
40
Memory::Write_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4);
41
42
Create(threadName, prio, stacksize);
43
}
44
45
HLEHelperThread::HLEHelperThread(const char *threadName, const char *module, const char *func, u32 prio, int stacksize) {
46
const u32 bytes = sizeof(u32) * 2;
47
AllocEntry(bytes);
48
Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + 0);
49
Memory::Write_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4);
50
51
Create(threadName, prio, stacksize);
52
}
53
54
HLEHelperThread::~HLEHelperThread() {
55
if (id_ > 0)
56
__KernelDeleteThread(id_, SCE_KERNEL_ERROR_THREAD_TERMINATED, "helper deleted");
57
if (entry_)
58
kernelMemory.Free(entry_);
59
}
60
61
void HLEHelperThread::AllocEntry(u32 size) {
62
entry_ = kernelMemory.Alloc(size, false, "HLEHelper");
63
Memory::Memset(entry_, 0, size, "HLEHelperClear");
64
currentMIPS->InvalidateICache(entry_, size);
65
}
66
67
void HLEHelperThread::Create(const char *threadName, u32 prio, int stacksize) {
68
id_ = __KernelCreateThreadInternal(threadName, __KernelGetCurThreadModuleId(), entry_, prio, stacksize, 0x00001000);
69
}
70
71
void HLEHelperThread::DoState(PointerWrap &p) {
72
auto s = p.Section("HLEHelperThread", 1);
73
if (!s) {
74
return;
75
}
76
77
Do(p, id_);
78
Do(p, entry_);
79
}
80
81
void HLEHelperThread::Start(u32 a0, u32 a1) {
82
__KernelStartThread(id_, a0, a1, true);
83
}
84
85
void HLEHelperThread::Terminate() {
86
__KernelStopThread(id_, SCE_KERNEL_ERROR_THREAD_TERMINATED, "helper terminated");
87
}
88
89
bool HLEHelperThread::Stopped() {
90
return KernelIsThreadDormant(id_);
91
}
92
93
void HLEHelperThread::ChangePriority(u32 prio) {
94
KernelChangeThreadPriority(id_, prio);
95
}
96
97
void HLEHelperThread::Resume(WaitType waitType, SceUID uid, int result) {
98
bool res = HLEKernel::ResumeFromWait(id_, waitType, uid, result);
99
if (!res) {
100
ERROR_LOG(Log::HLE, "Failed to wake helper thread from wait");
101
}
102
}
103
104
void HLEHelperThread::Forget() {
105
id_ = 0;
106
entry_ = 0;
107
}
108
109