forked from waskord/UnleashedRecomp_Android
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththreading.cpp
More file actions
162 lines (128 loc) · 3.74 KB
/
Copy paththreading.cpp
File metadata and controls
162 lines (128 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "kernel/threading.h"
#include <kernel/xdm.h>
#include <cpu/guest_thread.h>
#include <cpu/ppc_context.h>
#include <os/logger.h>
#include <kernel/utilities.h>
#ifdef _WIN32
#include <ntstatus.h>
#endif
uint32_t KeDelayExecutionThread(uint32_t WaitMode, bool Alertable, be<int64_t>* Timeout)
{
// We don't do async file reads.
if (Alertable)
return STATUS_USER_APC;
uint32_t timeout = GuestTimeoutToMilliseconds(Timeout);
#ifdef _WIN32
Sleep(timeout);
#else
if (timeout == 0)
std::this_thread::yield();
else
std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
#endif
return STATUS_SUCCESS;
}
void ExTerminateThread()
{
LOG_UTILITY("!!! STUB !!!");
}
uint32_t ExCreateThread(be<uint32_t>* handle, uint32_t stackSize, be<uint32_t>* threadId, uint32_t xApiThreadStartup, uint32_t startAddress, uint32_t startContext, uint32_t creationFlags)
{
LOGF_UTILITY("0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}",
(intptr_t)handle, stackSize, (intptr_t)threadId, xApiThreadStartup, startAddress, startContext, creationFlags);
uint32_t hostThreadId;
*handle = GetKernelHandle(GuestThread::Start({ startAddress, startContext, creationFlags }, &hostThreadId));
if (threadId != nullptr)
*threadId = hostThreadId;
return 0;
}
void KeSetBasePriorityThread(GuestThreadHandle* hThread, int priority)
{
#ifdef _WIN32
if (priority == 16)
{
priority = 15;
}
else if (priority == -16)
{
priority = -15;
}
SetThreadPriority(hThread == GetKernelObject(CURRENT_THREAD_HANDLE) ? GetCurrentThread() : hThread->thread.native_handle(), priority);
#endif
}
void KeQueryBasePriorityThread()
{
LOG_UTILITY("!!! STUB !!!");
}
uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount)
{
assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->GetThreadId() == GuestThread::GetCurrentThreadId());
hThread->suspended = true;
hThread->suspended.wait(true);
return S_OK;
}
uint32_t NtResumeThread(GuestThreadHandle* hThread, uint32_t* suspendCount)
{
assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE));
hThread->suspended = false;
hThread->suspended.notify_all();
return S_OK;
}
uint32_t KeResumeThread(GuestThreadHandle* object)
{
assert(object != GetKernelObject(CURRENT_THREAD_HANDLE));
object->suspended = false;
object->suspended.notify_all();
return 0;
}
uint32_t KeSetAffinityThread(uint32_t Thread, uint32_t Affinity, be<uint32_t>* lpPreviousAffinity)
{
if (lpPreviousAffinity)
*lpPreviousAffinity = 2;
return 0;
}
static std::vector<size_t> g_tlsFreeIndices;
static size_t g_tlsNextIndex = 0;
static Mutex g_tlsAllocationMutex;
static uint32_t& KeTlsGetValueRef(size_t index)
{
// Having this a global thread_local variable
// for some reason crashes on boot in debug builds.
thread_local std::vector<uint32_t> s_tlsValues;
if (s_tlsValues.size() <= index)
{
s_tlsValues.resize(index + 1, 0);
}
return s_tlsValues[index];
}
uint32_t KeTlsGetValue(uint32_t dwTlsIndex)
{
return KeTlsGetValueRef(dwTlsIndex);
}
uint32_t KeTlsSetValue(uint32_t dwTlsIndex, uint32_t lpTlsValue)
{
KeTlsGetValueRef(dwTlsIndex) = lpTlsValue;
return TRUE;
}
uint32_t KeTlsAlloc()
{
std::lock_guard<Mutex> lock(g_tlsAllocationMutex);
if (!g_tlsFreeIndices.empty())
{
size_t index = g_tlsFreeIndices.back();
g_tlsFreeIndices.pop_back();
return index;
}
return g_tlsNextIndex++;
}
uint32_t KeTlsFree(uint32_t dwTlsIndex)
{
std::lock_guard<Mutex> lock(g_tlsAllocationMutex);
g_tlsFreeIndices.push_back(dwTlsIndex);
return TRUE;
}
uint32_t KiApcNormalRoutineNop()
{
return 0;
}