summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/kernel.cpp15
-rw-r--r--src/core/hle/kernel/kernel.h9
-rw-r--r--src/core/hle/kernel/mutex.cpp28
-rw-r--r--src/core/hle/kernel/thread.cpp78
-rw-r--r--src/core/hle/kernel/thread.h4
-rw-r--r--src/core/loader.cpp6
6 files changed, 75 insertions, 65 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 45e36173c..de80de893 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -139,15 +139,20 @@ void Shutdown() {
139 Kernel::ThreadingShutdown(); 139 Kernel::ThreadingShutdown();
140} 140}
141 141
142} // namespace 142/**
143 143 * Loads executable stored at specified address
144bool __KernelLoadExec(u32 entry_point) { 144 * @entry_point Entry point in memory of loaded executable
145 Kernel::Init(); 145 * @return True on success, otherwise false
146 */
147bool LoadExec(u32 entry_point) {
148 Init();
146 149
147 Core::g_app_core->SetPC(entry_point); 150 Core::g_app_core->SetPC(entry_point);
148 151
149 // 0x30 is the typical main thread priority I've seen used so far 152 // 0x30 is the typical main thread priority I've seen used so far
150 Handle thread_id = Kernel::SetupMainThread(0x30); 153 Handle thread = Kernel::SetupMainThread(0x30);
151 154
152 return true; 155 return true;
153} 156}
157
158} // namespace
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 180339914..7cd79c2c4 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -144,6 +144,11 @@ private:
144 144
145extern ObjectPool g_object_pool; 145extern ObjectPool g_object_pool;
146 146
147} // namespace 147/**
148 * Loads executable stored at specified address
149 * @entry_point Entry point in memory of loaded executable
150 * @return True on success, otherwise false
151 */
152bool LoadExec(u32 entry_point);
148 153
149bool __KernelLoadExec(u32 entry_point); 154} // namespace
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 7cf3439e9..019efbc78 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -30,17 +30,17 @@ public:
30typedef std::multimap<Handle, Handle> MutexMap; 30typedef std::multimap<Handle, Handle> MutexMap;
31static MutexMap g_mutex_held_locks; 31static MutexMap g_mutex_held_locks;
32 32
33void __MutexAcquireLock(Mutex* mutex, Handle thread) { 33void MutexAcquireLock(Mutex* mutex, Handle thread) {
34 g_mutex_held_locks.insert(std::make_pair(thread, mutex->GetHandle())); 34 g_mutex_held_locks.insert(std::make_pair(thread, mutex->GetHandle()));
35 mutex->lock_thread = thread; 35 mutex->lock_thread = thread;
36} 36}
37 37
38void __MutexAcquireLock(Mutex* mutex) { 38void MutexAcquireLock(Mutex* mutex) {
39 Handle thread = GetCurrentThread(); 39 Handle thread = GetCurrentThreadHandle();
40 __MutexAcquireLock(mutex, thread); 40 MutexAcquireLock(mutex, thread);
41} 41}
42 42
43void __MutexEraseLock(Mutex* mutex) { 43void MutexEraseLock(Mutex* mutex) {
44 Handle handle = mutex->GetHandle(); 44 Handle handle = mutex->GetHandle();
45 auto locked = g_mutex_held_locks.equal_range(mutex->lock_thread); 45 auto locked = g_mutex_held_locks.equal_range(mutex->lock_thread);
46 for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { 46 for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) {
@@ -52,29 +52,29 @@ void __MutexEraseLock(Mutex* mutex) {
52 mutex->lock_thread = -1; 52 mutex->lock_thread = -1;
53} 53}
54 54
55bool __LockMutex(Mutex* mutex) { 55bool LockMutex(Mutex* mutex) {
56 // Mutex alread locked? 56 // Mutex alread locked?
57 if (mutex->locked) { 57 if (mutex->locked) {
58 return false; 58 return false;
59 } 59 }
60 __MutexAcquireLock(mutex); 60 MutexAcquireLock(mutex);
61 return true; 61 return true;
62} 62}
63 63
64bool __ReleaseMutexForThread(Mutex* mutex, Handle thread) { 64bool ReleaseMutexForThread(Mutex* mutex, Handle thread) {
65 __MutexAcquireLock(mutex, thread); 65 MutexAcquireLock(mutex, thread);
66 Kernel::ResumeThreadFromWait(thread); 66 Kernel::ResumeThreadFromWait(thread);
67 return true; 67 return true;
68} 68}
69 69
70bool __ReleaseMutex(Mutex* mutex) { 70bool ReleaseMutex(Mutex* mutex) {
71 __MutexEraseLock(mutex); 71 MutexEraseLock(mutex);
72 bool woke_threads = false; 72 bool woke_threads = false;
73 auto iter = mutex->waiting_threads.begin(); 73 auto iter = mutex->waiting_threads.begin();
74 74
75 // Find the next waiting thread for the mutex... 75 // Find the next waiting thread for the mutex...
76 while (!woke_threads && !mutex->waiting_threads.empty()) { 76 while (!woke_threads && !mutex->waiting_threads.empty()) {
77 woke_threads |= __ReleaseMutexForThread(mutex, *iter); 77 woke_threads |= ReleaseMutexForThread(mutex, *iter);
78 mutex->waiting_threads.erase(iter); 78 mutex->waiting_threads.erase(iter);
79 } 79 }
80 // Reset mutex lock thread handle, nothing is waiting 80 // Reset mutex lock thread handle, nothing is waiting
@@ -91,7 +91,7 @@ bool __ReleaseMutex(Mutex* mutex) {
91 */ 91 */
92Result ReleaseMutex(Handle handle) { 92Result ReleaseMutex(Handle handle) {
93 Mutex* mutex = Kernel::g_object_pool.GetFast<Mutex>(handle); 93 Mutex* mutex = Kernel::g_object_pool.GetFast<Mutex>(handle);
94 if (!__ReleaseMutex(mutex)) { 94 if (!ReleaseMutex(mutex)) {
95 return -1; 95 return -1;
96 } 96 }
97 return 0; 97 return 0;
@@ -110,7 +110,7 @@ Mutex* CreateMutex(Handle& handle, bool initial_locked) {
110 110
111 // Acquire mutex with current thread if initialized as locked... 111 // Acquire mutex with current thread if initialized as locked...
112 if (mutex->locked) { 112 if (mutex->locked) {
113 __MutexAcquireLock(mutex); 113 MutexAcquireLock(mutex);
114 114
115 // Otherwise, reset lock thread handle 115 // Otherwise, reset lock thread handle
116 } else { 116 } else {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 934ca87c4..5f1d5c400 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -64,28 +64,33 @@ Thread* g_current_thread;
64 64
65 65
66/// Gets the current thread 66/// Gets the current thread
67inline Thread* __GetCurrentThread() { 67inline Thread* GetCurrentThread() {
68 return g_current_thread; 68 return g_current_thread;
69} 69}
70 70
71/// Gets the current thread handle
72Handle GetCurrentThreadHandle() {
73 return GetCurrentThread()->GetHandle();
74}
75
71/// Sets the current thread 76/// Sets the current thread
72inline void __SetCurrentThread(Thread* t) { 77inline void SetCurrentThread(Thread* t) {
73 g_current_thread = t; 78 g_current_thread = t;
74 g_current_thread_handle = t->GetHandle(); 79 g_current_thread_handle = t->GetHandle();
75} 80}
76 81
77/// Saves the current CPU context 82/// Saves the current CPU context
78void __SaveContext(ThreadContext& ctx) { 83void SaveContext(ThreadContext& ctx) {
79 Core::g_app_core->SaveContext(ctx); 84 Core::g_app_core->SaveContext(ctx);
80} 85}
81 86
82/// Loads a CPU context 87/// Loads a CPU context
83void __LoadContext(ThreadContext& ctx) { 88void LoadContext(ThreadContext& ctx) {
84 Core::g_app_core->LoadContext(ctx); 89 Core::g_app_core->LoadContext(ctx);
85} 90}
86 91
87/// Resets a thread 92/// Resets a thread
88void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) { 93void ResetThread(Thread* t, u32 arg, s32 lowest_priority) {
89 memset(&t->context, 0, sizeof(ThreadContext)); 94 memset(&t->context, 0, sizeof(ThreadContext));
90 95
91 t->context.cpu_registers[0] = arg; 96 t->context.cpu_registers[0] = arg;
@@ -101,7 +106,7 @@ void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) {
101} 106}
102 107
103/// Change a thread to "ready" state 108/// Change a thread to "ready" state
104void __ChangeReadyState(Thread* t, bool ready) { 109void ChangeReadyState(Thread* t, bool ready) {
105 Handle handle = t->GetHandle(); 110 Handle handle = t->GetHandle();
106 if (t->IsReady()) { 111 if (t->IsReady()) {
107 if (!ready) { 112 if (!ready) {
@@ -118,11 +123,11 @@ void __ChangeReadyState(Thread* t, bool ready) {
118} 123}
119 124
120/// Changes a threads state 125/// Changes a threads state
121void __ChangeThreadState(Thread* t, ThreadStatus new_status) { 126void ChangeThreadState(Thread* t, ThreadStatus new_status) {
122 if (!t || t->status == new_status) { 127 if (!t || t->status == new_status) {
123 return; 128 return;
124 } 129 }
125 __ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); 130 ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0);
126 t->status = new_status; 131 t->status = new_status;
127 132
128 if (new_status == THREADSTATUS_WAIT) { 133 if (new_status == THREADSTATUS_WAIT) {
@@ -133,42 +138,42 @@ void __ChangeThreadState(Thread* t, ThreadStatus new_status) {
133} 138}
134 139
135/// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields) 140/// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields)
136void __CallThread(Thread* t) { 141void CallThread(Thread* t) {
137 // Stop waiting 142 // Stop waiting
138 if (t->wait_type != WAITTYPE_NONE) { 143 if (t->wait_type != WAITTYPE_NONE) {
139 t->wait_type = WAITTYPE_NONE; 144 t->wait_type = WAITTYPE_NONE;
140 } 145 }
141 __ChangeThreadState(t, THREADSTATUS_READY); 146 ChangeThreadState(t, THREADSTATUS_READY);
142} 147}
143 148
144/// Switches CPU context to that of the specified thread 149/// Switches CPU context to that of the specified thread
145void __SwitchContext(Thread* t, const char* reason) { 150void SwitchContext(Thread* t, const char* reason) {
146 Thread* cur = __GetCurrentThread(); 151 Thread* cur = GetCurrentThread();
147 152
148 // Save context for current thread 153 // Save context for current thread
149 if (cur) { 154 if (cur) {
150 __SaveContext(cur->context); 155 SaveContext(cur->context);
151 156
152 if (cur->IsRunning()) { 157 if (cur->IsRunning()) {
153 __ChangeReadyState(cur, true); 158 ChangeReadyState(cur, true);
154 } 159 }
155 } 160 }
156 // Load context of new thread 161 // Load context of new thread
157 if (t) { 162 if (t) {
158 __SetCurrentThread(t); 163 SetCurrentThread(t);
159 __ChangeReadyState(t, false); 164 ChangeReadyState(t, false);
160 t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; 165 t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY;
161 t->wait_type = WAITTYPE_NONE; 166 t->wait_type = WAITTYPE_NONE;
162 __LoadContext(t->context); 167 LoadContext(t->context);
163 } else { 168 } else {
164 __SetCurrentThread(NULL); 169 SetCurrentThread(NULL);
165 } 170 }
166} 171}
167 172
168/// Gets the next thread that is ready to be run by priority 173/// Gets the next thread that is ready to be run by priority
169Thread* __NextThread() { 174Thread* NextThread() {
170 Handle next; 175 Handle next;
171 Thread* cur = __GetCurrentThread(); 176 Thread* cur = GetCurrentThread();
172 177
173 if (cur && cur->IsRunning()) { 178 if (cur && cur->IsRunning()) {
174 next = g_thread_ready_queue.pop_first_better(cur->current_priority); 179 next = g_thread_ready_queue.pop_first_better(cur->current_priority);
@@ -183,9 +188,9 @@ Thread* __NextThread() {
183 188
184/// Puts a thread in the wait state for the given type/reason 189/// Puts a thread in the wait state for the given type/reason
185void WaitCurThread(WaitType wait_type, const char* reason) { 190void WaitCurThread(WaitType wait_type, const char* reason) {
186 Thread* t = __GetCurrentThread(); 191 Thread* t = GetCurrentThread();
187 t->wait_type = wait_type; 192 t->wait_type = wait_type;
188 __ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); 193 ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND)));
189} 194}
190 195
191/// Resumes a thread from waiting by marking it as "ready" 196/// Resumes a thread from waiting by marking it as "ready"
@@ -195,7 +200,7 @@ void ResumeThreadFromWait(Handle handle) {
195 if (t) { 200 if (t) {
196 t->status &= ~THREADSTATUS_WAIT; 201 t->status &= ~THREADSTATUS_WAIT;
197 if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { 202 if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
198 __ChangeReadyState(t, true); 203 ChangeReadyState(t, true);
199 } 204 }
200 } 205 }
201} 206}
@@ -256,7 +261,7 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
256 Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, 261 Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top,
257 stack_size); 262 stack_size);
258 263
259 __ResetThread(t, arg, 0); 264 ResetThread(t, arg, 0);
260 265
261 HLE::EatCycles(32000); 266 HLE::EatCycles(32000);
262 267
@@ -264,16 +269,11 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
264 // Technically, this should not eat all at once, and reschedule in the middle, but that's hard. 269 // Technically, this should not eat all at once, and reschedule in the middle, but that's hard.
265 HLE::ReSchedule("thread created"); 270 HLE::ReSchedule("thread created");
266 271
267 __CallThread(t); 272 CallThread(t);
268 273
269 return handle; 274 return handle;
270} 275}
271 276
272/// Gets the current thread
273Handle GetCurrentThread() {
274 return __GetCurrentThread()->GetHandle();
275}
276
277/// Sets up the primary application thread 277/// Sets up the primary application thread
278Handle SetupMainThread(s32 priority, int stack_size) { 278Handle SetupMainThread(s32 priority, int stack_size) {
279 Handle handle; 279 Handle handle;
@@ -282,33 +282,33 @@ Handle SetupMainThread(s32 priority, int stack_size) {
282 Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority, 282 Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority,
283 THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); 283 THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
284 284
285 __ResetThread(t, 0, 0); 285 ResetThread(t, 0, 0);
286 286
287 // If running another thread already, set it to "ready" state 287 // If running another thread already, set it to "ready" state
288 Thread* cur = __GetCurrentThread(); 288 Thread* cur = GetCurrentThread();
289 if (cur && cur->IsRunning()) { 289 if (cur && cur->IsRunning()) {
290 __ChangeReadyState(cur, true); 290 ChangeReadyState(cur, true);
291 } 291 }
292 292
293 // Run new "main" thread 293 // Run new "main" thread
294 __SetCurrentThread(t); 294 SetCurrentThread(t);
295 t->status = THREADSTATUS_RUNNING; 295 t->status = THREADSTATUS_RUNNING;
296 __LoadContext(t->context); 296 LoadContext(t->context);
297 297
298 return handle; 298 return handle;
299} 299}
300 300
301/// Reschedules to the next available thread (call after current thread is suspended) 301/// Reschedules to the next available thread (call after current thread is suspended)
302void Reschedule(const char* reason) { 302void Reschedule(const char* reason) {
303 Thread* prev = __GetCurrentThread(); 303 Thread* prev = GetCurrentThread();
304 Thread* next = __NextThread(); 304 Thread* next = NextThread();
305 if (next > 0) { 305 if (next > 0) {
306 __SwitchContext(next, reason); 306 SwitchContext(next, reason);
307 307
308 // Hack - automatically change previous thread (which would have been in "wait" state) to 308 // Hack - automatically change previous thread (which would have been in "wait" state) to
309 // "ready" state, so that we can immediately resume to it when new thread yields. FixMe to 309 // "ready" state, so that we can immediately resume to it when new thread yields. FixMe to
310 // actually wait for whatever event it is supposed to be waiting on. 310 // actually wait for whatever event it is supposed to be waiting on.
311 __ChangeReadyState(prev, true); 311 ChangeReadyState(prev, true);
312 } 312 }
313} 313}
314 314
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 82bf16082..a9e9eb95f 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -59,8 +59,8 @@ void WaitCurThread(WaitType wait_type, const char* reason);
59/// Resumes a thread from waiting by marking it as "ready" 59/// Resumes a thread from waiting by marking it as "ready"
60void ResumeThreadFromWait(Handle handle); 60void ResumeThreadFromWait(Handle handle);
61 61
62/// Gets the current thread 62/// Gets the current thread handle
63Handle GetCurrentThread(); 63Handle GetCurrentThreadHandle();
64 64
65/// Put current thread in a wait state - on WaitSynchronization 65/// Put current thread in a wait state - on WaitSynchronization
66void WaitThread_Synchronization(); 66void WaitThread_Synchronization();
diff --git a/src/core/loader.cpp b/src/core/loader.cpp
index 444b75feb..ff1c873bb 100644
--- a/src/core/loader.cpp
+++ b/src/core/loader.cpp
@@ -56,7 +56,7 @@ bool Load_ELF(std::string &filename) {
56 elf_reader = new ElfReader(buffer); 56 elf_reader = new ElfReader(buffer);
57 elf_reader->LoadInto(0x00100000); 57 elf_reader->LoadInto(0x00100000);
58 58
59 __KernelLoadExec(elf_reader->GetEntryPoint()); 59 Kernel::LoadExec(elf_reader->GetEntryPoint());
60 60
61 delete[] buffer; 61 delete[] buffer;
62 delete elf_reader; 62 delete elf_reader;
@@ -102,7 +102,7 @@ bool Load_DAT(std::string &filename) {
102 *d++ = (*s++); 102 *d++ = (*s++);
103 } 103 }
104 104
105 __KernelLoadExec(entry_point); 105 Kernel::LoadExec(entry_point);
106 106
107 107
108 delete[] buffer; 108 delete[] buffer;
@@ -144,7 +144,7 @@ bool Load_BIN(std::string &filename) {
144 *d++ = (*s++); 144 *d++ = (*s++);
145 } 145 }
146 146
147 __KernelLoadExec(entry_point); 147 Kernel::LoadExec(entry_point);
148 148
149 delete[] buffer; 149 delete[] buffer;
150 } 150 }