mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #3301 from Subv/exitprocess2
Kernel/SVC: Partially implemented svcExitProcess.
This commit is contained in:
		
						commit
						c3c684cd2b
					
				
					 3 changed files with 41 additions and 1 deletions
				
			
		|  | @ -40,6 +40,7 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) { | ||||||
|     process->codeset = std::move(code_set); |     process->codeset = std::move(code_set); | ||||||
|     process->flags.raw = 0; |     process->flags.raw = 0; | ||||||
|     process->flags.memory_region.Assign(MemoryRegion::APPLICATION); |     process->flags.memory_region.Assign(MemoryRegion::APPLICATION); | ||||||
|  |     process->status = ProcessStatus::Created; | ||||||
| 
 | 
 | ||||||
|     process_list.push_back(process); |     process_list.push_back(process); | ||||||
|     return process; |     return process; | ||||||
|  | @ -151,6 +152,8 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { | ||||||
|         HandleSpecialMapping(vm_manager, mapping); |         HandleSpecialMapping(vm_manager, mapping); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     status = ProcessStatus::Running; | ||||||
|  | 
 | ||||||
|     vm_manager.LogLayout(Log::Level::Debug); |     vm_manager.LogLayout(Log::Level::Debug); | ||||||
|     Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority, this); |     Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority, this); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -49,6 +49,8 @@ union ProcessFlags { | ||||||
|     BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
 |     BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum class ProcessStatus { Created, Running, Exited }; | ||||||
|  | 
 | ||||||
| class ResourceLimit; | class ResourceLimit; | ||||||
| struct MemoryRegionInfo; | struct MemoryRegionInfo; | ||||||
| 
 | 
 | ||||||
|  | @ -122,6 +124,8 @@ public: | ||||||
|     u16 kernel_version = 0; |     u16 kernel_version = 0; | ||||||
|     /// The default CPU for this process, threads are scheduled on this cpu by default.
 |     /// The default CPU for this process, threads are scheduled on this cpu by default.
 | ||||||
|     u8 ideal_processor = 0; |     u8 ideal_processor = 0; | ||||||
|  |     /// Current status of the process
 | ||||||
|  |     ProcessStatus status; | ||||||
| 
 | 
 | ||||||
|     /// The id of this process
 |     /// The id of this process
 | ||||||
|     u32 process_id = next_process_id++; |     u32 process_id = next_process_id++; | ||||||
|  |  | ||||||
|  | @ -143,6 +143,36 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void ExitProcess() { | ||||||
|  |     LOG_INFO(Kernel_SVC, "Process %u exiting", g_current_process->process_id); | ||||||
|  | 
 | ||||||
|  |     ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited"); | ||||||
|  | 
 | ||||||
|  |     g_current_process->status = ProcessStatus::Exited; | ||||||
|  | 
 | ||||||
|  |     // Stop all the process threads that are currently waiting for objects.
 | ||||||
|  |     auto& thread_list = GetThreadList(); | ||||||
|  |     for (auto& thread : thread_list) { | ||||||
|  |         if (thread->owner_process != g_current_process) | ||||||
|  |             continue; | ||||||
|  | 
 | ||||||
|  |         if (thread == GetCurrentThread()) | ||||||
|  |             continue; | ||||||
|  | 
 | ||||||
|  |         // TODO(Subv): When are the other running/ready threads terminated?
 | ||||||
|  |         ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | ||||||
|  |                        thread->status == THREADSTATUS_WAIT_SYNCH_ALL, | ||||||
|  |                    "Exiting processes with non-waiting threads is currently unimplemented"); | ||||||
|  | 
 | ||||||
|  |         thread->Stop(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Kill the current thread
 | ||||||
|  |     GetCurrentThread()->Stop(); | ||||||
|  | 
 | ||||||
|  |     Core::System::GetInstance().PrepareReschedule(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// Maps a memory block to specified address
 | /// Maps a memory block to specified address
 | ||||||
| static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) { | static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) { | ||||||
|     LOG_TRACE(Kernel_SVC, |     LOG_TRACE(Kernel_SVC, | ||||||
|  | @ -1232,7 +1262,7 @@ static const FunctionDef SVC_Table[] = { | ||||||
|     {0x00, nullptr, "Unknown"}, |     {0x00, nullptr, "Unknown"}, | ||||||
|     {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"}, |     {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"}, | ||||||
|     {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"}, |     {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"}, | ||||||
|     {0x03, nullptr, "ExitProcess"}, |     {0x03, ExitProcess, "ExitProcess"}, | ||||||
|     {0x04, nullptr, "GetProcessAffinityMask"}, |     {0x04, nullptr, "GetProcessAffinityMask"}, | ||||||
|     {0x05, nullptr, "SetProcessAffinityMask"}, |     {0x05, nullptr, "SetProcessAffinityMask"}, | ||||||
|     {0x06, nullptr, "GetProcessIdealProcessor"}, |     {0x06, nullptr, "GetProcessIdealProcessor"}, | ||||||
|  | @ -1373,6 +1403,9 @@ void CallSVC(u32 immediate) { | ||||||
|     // Lock the global kernel mutex when we enter the kernel HLE.
 |     // Lock the global kernel mutex when we enter the kernel HLE.
 | ||||||
|     std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); |     std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); | ||||||
| 
 | 
 | ||||||
|  |     ASSERT_MSG(g_current_process->status == ProcessStatus::Running, | ||||||
|  |                "Running threads from exiting processes is unimplemented"); | ||||||
|  | 
 | ||||||
|     const FunctionDef* info = GetSVCInfo(immediate); |     const FunctionDef* info = GetSVCInfo(immediate); | ||||||
|     if (info) { |     if (info) { | ||||||
|         if (info->func) { |         if (info->func) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue