mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Added Signals; more runtime fixes
This commit is contained in:
		
							parent
							
								
									e4f05884c3
								
							
						
					
					
						commit
						8abc5525be
					
				
					 17 changed files with 118 additions and 56 deletions
				
			
		|  | @ -1504,19 +1504,12 @@ void GMainWindow::OnCheats() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnSave() { | void GMainWindow::OnSave() { | ||||||
|     Core::System& system{Core::System::GetInstance()}; |     Core::System::GetInstance().SendSignal(Core::System::Signal::Save); | ||||||
|     auto fs = std::ofstream("save0.citrasave"); |  | ||||||
|     emu_thread->SetRunning(false); |  | ||||||
|     Core::System::GetInstance().Save(fs); |  | ||||||
|     emu_thread->SetRunning(true); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnLoad() { | void GMainWindow::OnLoad() { | ||||||
|     if (QFileInfo("save0.citrasave").exists()) { |     if (QFileInfo("save0.citrasave").exists()) { | ||||||
|         auto fs = std::ifstream("save0.citrasave"); |         Core::System::GetInstance().SendSignal(Core::System::Signal::Load); | ||||||
|         emu_thread->SetRunning(false); |  | ||||||
|         Core::System::GetInstance().Load(fs); |  | ||||||
|         emu_thread->SetRunning(true); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -160,15 +160,33 @@ private: | ||||||
|     // The priority level queues of thread ids.
 |     // The priority level queues of thread ids.
 | ||||||
|     std::array<Queue, NUM_QUEUES> queues; |     std::array<Queue, NUM_QUEUES> queues; | ||||||
| 
 | 
 | ||||||
|  |     s32 ToIndex(Queue* q) const { | ||||||
|  |         if (q == nullptr) { | ||||||
|  |             return -2; | ||||||
|  |         } else if (q == UnlinkedTag()) { | ||||||
|  |             return -1; | ||||||
|  |         } else { | ||||||
|  |             return static_cast<s32>(q - &queues[0]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Queue* ToPointer(s32 idx) { | ||||||
|  |         if (idx == -1) { | ||||||
|  |             return UnlinkedTag(); | ||||||
|  |         } else if (idx < 0) { | ||||||
|  |             return nullptr; | ||||||
|  |         } else { | ||||||
|  |             return &queues[idx]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void save(Archive& ar, const unsigned int file_version) const { |     void save(Archive& ar, const unsigned int file_version) const { | ||||||
|         s32 idx = first == UnlinkedTag() ? -1 : static_cast<s32>(first - &queues[0]); |         s32 idx = ToIndex(first); | ||||||
|         ar << idx; |         ar << idx; | ||||||
|         for (auto i = 0; i < NUM_QUEUES; i++) { |         for (auto i = 0; i < NUM_QUEUES; i++) { | ||||||
|             s32 idx1 = first == UnlinkedTag() |             s32 idx1 = ToIndex(queues[i].next_nonempty); | ||||||
|                            ? -1 |  | ||||||
|                            : static_cast<s32>(queues[i].next_nonempty - &queues[0]); |  | ||||||
|             ar << idx1; |             ar << idx1; | ||||||
|             ar << queues[i].data; |             ar << queues[i].data; | ||||||
|         } |         } | ||||||
|  | @ -178,10 +196,10 @@ private: | ||||||
|     void load(Archive& ar, const unsigned int file_version) { |     void load(Archive& ar, const unsigned int file_version) { | ||||||
|         s32 idx; |         s32 idx; | ||||||
|         ar >> idx; |         ar >> idx; | ||||||
|         first = idx < 0 ? UnlinkedTag() : &queues[idx]; |         first = ToPointer(idx); | ||||||
|         for (auto i = 0; i < NUM_QUEUES; i++) { |         for (auto i = 0; i < NUM_QUEUES; i++) { | ||||||
|             ar >> idx; |             ar >> idx; | ||||||
|             queues[i].next_nonempty = idx < 0 ? UnlinkedTag() : &queues[idx]; |             queues[i].next_nonempty = ToPointer(idx); | ||||||
|             ar >> queues[i].data; |             ar >> queues[i].data; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -264,7 +264,7 @@ private: | ||||||
|             ar >> r; |             ar >> r; | ||||||
|             SetCP15Register(static_cast<CP15Register>(i), r); |             SetCP15Register(static_cast<CP15Register>(i), r); | ||||||
|         } |         } | ||||||
|         // TODO: Clear caches etc?
 |         ClearInstructionCache(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     BOOST_SERIALIZATION_SPLIT_MEMBER() |     BOOST_SERIALIZATION_SPLIT_MEMBER() | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
|  | #include <fstream> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <utility> | #include <utility> | ||||||
| #include <boost/serialization/array.hpp> | #include <boost/serialization/array.hpp> | ||||||
|  | @ -103,15 +104,38 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|     HW::Update(); |     HW::Update(); | ||||||
|     Reschedule(); |     Reschedule(); | ||||||
| 
 | 
 | ||||||
|     if (reset_requested.exchange(false)) { |     auto signal = current_signal.exchange(Signal::None); | ||||||
|  |     switch (signal) { | ||||||
|  |     case Signal::Reset: | ||||||
|         Reset(); |         Reset(); | ||||||
|     } else if (shutdown_requested.exchange(false)) { |         break; | ||||||
|  |     case Signal::Shutdown: | ||||||
|         return ResultStatus::ShutdownRequested; |         return ResultStatus::ShutdownRequested; | ||||||
|  |         break; | ||||||
|  |     case Signal::Load: { | ||||||
|  |         auto stream = std::ifstream("save0.citrasave", std::fstream::binary); | ||||||
|  |         System::Load(stream); | ||||||
|  |     } break; | ||||||
|  |     case Signal::Save: { | ||||||
|  |         auto stream = std::ofstream("save0.citrasave", std::fstream::binary); | ||||||
|  |         System::Save(stream); | ||||||
|  |     } break; | ||||||
|  |     default: | ||||||
|  |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return status; |     return status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool System::SendSignal(System::Signal signal) { | ||||||
|  |     auto prev = System::Signal::None; | ||||||
|  |     if (!current_signal.compare_exchange_strong(prev, signal)) { | ||||||
|  |         LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, prev); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| System::ResultStatus System::SingleStep() { | System::ResultStatus System::SingleStep() { | ||||||
|     return RunLoop(false); |     return RunLoop(false); | ||||||
| } | } | ||||||
|  | @ -216,8 +240,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo | ||||||
| 
 | 
 | ||||||
|     timing = std::make_unique<Timing>(); |     timing = std::make_unique<Timing>(); | ||||||
| 
 | 
 | ||||||
|     kernel = std::make_unique<Kernel::KernelSystem>( |     kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, | ||||||
|         *memory, *timing, [this] { PrepareReschedule(); }, system_mode); |                                                     [this] { PrepareReschedule(); }, system_mode); | ||||||
| 
 | 
 | ||||||
|     if (Settings::values.use_cpu_jit) { |     if (Settings::values.use_cpu_jit) { | ||||||
| #ifdef ARCHITECTURE_x86_64 | #ifdef ARCHITECTURE_x86_64 | ||||||
|  | @ -409,6 +433,7 @@ void System::Reset() { | ||||||
| 
 | 
 | ||||||
| template <class Archive> | template <class Archive> | ||||||
| void System::serialize(Archive& ar, const unsigned int file_version) { | void System::serialize(Archive& ar, const unsigned int file_version) { | ||||||
|  |     Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); | ||||||
|     ar&* cpu_core.get(); |     ar&* cpu_core.get(); | ||||||
|     ar&* service_manager.get(); |     ar&* service_manager.get(); | ||||||
|     ar& GPU::g_regs; |     ar& GPU::g_regs; | ||||||
|  | @ -436,11 +461,20 @@ void System::Save(std::ostream& stream) const { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void System::Load(std::istream& stream) { | void System::Load(std::istream& stream) { | ||||||
|     { |     try { | ||||||
|         iarchive ia{stream}; | 
 | ||||||
|         ia&* this; |         { | ||||||
|  |             iarchive ia{stream}; | ||||||
|  |             ia&* this; | ||||||
|  |         } | ||||||
|  |         VideoCore::Load(stream); | ||||||
|  | 
 | ||||||
|  |         // Flush state through:
 | ||||||
|  |         Kernel().SetCurrentProcess(Kernel().GetCurrentProcess()); | ||||||
|  | 
 | ||||||
|  |     } catch (const std::exception& e) { | ||||||
|  |         LOG_ERROR(Core, "Error loading: {}", e.what()); | ||||||
|     } |     } | ||||||
|     VideoCore::Load(stream); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace Core
 | } // namespace Core
 | ||||||
|  |  | ||||||
|  | @ -116,14 +116,18 @@ public: | ||||||
|     /// Shutdown and then load again
 |     /// Shutdown and then load again
 | ||||||
|     void Reset(); |     void Reset(); | ||||||
| 
 | 
 | ||||||
|  |     enum class Signal : u32 { None, Shutdown, Reset, Save, Load }; | ||||||
|  | 
 | ||||||
|  |     bool SendSignal(Signal signal); | ||||||
|  | 
 | ||||||
|     /// Request reset of the system
 |     /// Request reset of the system
 | ||||||
|     void RequestReset() { |     void RequestReset() { | ||||||
|         reset_requested = true; |         SendSignal(Signal::Reset); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Request shutdown of the system
 |     /// Request shutdown of the system
 | ||||||
|     void RequestShutdown() { |     void RequestShutdown() { | ||||||
|         shutdown_requested = true; |         SendSignal(Signal::Shutdown); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|  | @ -341,8 +345,7 @@ private: | ||||||
|     Frontend::EmuWindow* m_emu_window; |     Frontend::EmuWindow* m_emu_window; | ||||||
|     std::string m_filepath; |     std::string m_filepath; | ||||||
| 
 | 
 | ||||||
|     std::atomic<bool> reset_requested; |     std::atomic<Signal> current_signal; | ||||||
|     std::atomic<bool> shutdown_requested; |  | ||||||
| 
 | 
 | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
|     template <typename Archive> |     template <typename Archive> | ||||||
|  |  | ||||||
|  | @ -23,14 +23,10 @@ bool Timing::Event::operator<(const Event& right) const { | ||||||
| TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback callback) { | TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback callback) { | ||||||
|     // check for existing type with same name.
 |     // check for existing type with same name.
 | ||||||
|     // we want event type names to remain unique so that we can use them for serialization.
 |     // we want event type names to remain unique so that we can use them for serialization.
 | ||||||
|     ASSERT_MSG(event_types.find(name) == event_types.end(), |     auto info = event_types.emplace(name, TimingEventType{}); | ||||||
|                "CoreTiming Event \"{}\" is already registered. Events should only be registered " |  | ||||||
|                "during Init to avoid breaking save states.", |  | ||||||
|                name); |  | ||||||
| 
 |  | ||||||
|     auto info = event_types.emplace(name, TimingEventType{callback, nullptr}); |  | ||||||
|     TimingEventType* event_type = &info.first->second; |     TimingEventType* event_type = &info.first->second; | ||||||
|     event_type->name = &info.first->first; |     event_type->name = &info.first->first; | ||||||
|  |     event_type->callback = callback; | ||||||
|     return event_type; |     return event_type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -129,6 +125,10 @@ void Timing::Advance() { | ||||||
|         Event evt = std::move(event_queue.front()); |         Event evt = std::move(event_queue.front()); | ||||||
|         std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |         std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); | ||||||
|         event_queue.pop_back(); |         event_queue.pop_back(); | ||||||
|  |         if (event_types.find(*evt.type->name) == event_types.end()) { | ||||||
|  |             LOG_ERROR(Core, "Unknown queued event"); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|         evt.type->callback(evt.userdata, global_timer - evt.time); |         evt.type->callback(evt.userdata, global_timer - evt.time); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| // FileSys namespace
 | // FileSys namespace
 | ||||||
| 
 | 
 | ||||||
| SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile) | SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile) | ||||||
|  | SERIALIZE_EXPORT_IMPL(FileSys::IVFCFileInMemory) | ||||||
| SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator) | SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator) | ||||||
| SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator) | SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator) | ||||||
| SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator) | SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator) | ||||||
|  |  | ||||||
|  | @ -176,11 +176,23 @@ private: | ||||||
|     std::vector<u8> romfs_file; |     std::vector<u8> romfs_file; | ||||||
|     u64 data_offset; |     u64 data_offset; | ||||||
|     u64 data_size; |     u64 data_size; | ||||||
|  | 
 | ||||||
|  |     IVFCFileInMemory() = default; | ||||||
|  | 
 | ||||||
|  |     template <class Archive> | ||||||
|  |     void serialize(Archive& ar, const unsigned int) { | ||||||
|  |         ar& boost::serialization::base_object<FileBackend>(*this); | ||||||
|  |         ar& romfs_file; | ||||||
|  |         ar& data_offset; | ||||||
|  |         ar& data_size; | ||||||
|  |     } | ||||||
|  |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace FileSys
 | } // namespace FileSys
 | ||||||
| 
 | 
 | ||||||
| BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile) | BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile) | ||||||
|  | BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFileInMemory) | ||||||
| BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator) | BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator) | ||||||
| BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator) | BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator) | ||||||
| BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator) | BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator) | ||||||
|  |  | ||||||
|  | @ -23,6 +23,9 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, | ||||||
|                            std::function<void()> prepare_reschedule_callback, u32 system_mode) |                            std::function<void()> prepare_reschedule_callback, u32 system_mode) | ||||||
|     : memory(memory), timing(timing), |     : memory(memory), timing(timing), | ||||||
|       prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { |       prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { | ||||||
|  |     for (auto i = 0; i < memory_regions.size(); i++) { | ||||||
|  |         memory_regions[i] = std::make_shared<MemoryRegionInfo>(); | ||||||
|  |     } | ||||||
|     MemoryInit(system_mode); |     MemoryInit(system_mode); | ||||||
| 
 | 
 | ||||||
|     resource_limits = std::make_unique<ResourceLimitList>(*this); |     resource_limits = std::make_unique<ResourceLimitList>(*this); | ||||||
|  | @ -107,7 +110,7 @@ template <class Archive> | ||||||
| void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { | void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { | ||||||
|     ar& memory_regions; |     ar& memory_regions; | ||||||
|     ar& named_ports; |     ar& named_ports; | ||||||
|     ar&* current_cpu.get(); |     // current_cpu set externally
 | ||||||
|     // NB: subsystem references and prepare_reschedule_callback are constant
 |     // NB: subsystem references and prepare_reschedule_callback are constant
 | ||||||
|     ar&* resource_limits.get(); |     ar&* resource_limits.get(); | ||||||
|     ar& next_object_id; |     ar& next_object_id; | ||||||
|  |  | ||||||
|  | @ -134,7 +134,8 @@ public: | ||||||
|      */ |      */ | ||||||
|     ResultVal<std::shared_ptr<Thread>> CreateThread(std::string name, VAddr entry_point, |     ResultVal<std::shared_ptr<Thread>> CreateThread(std::string name, VAddr entry_point, | ||||||
|                                                     u32 priority, u32 arg, s32 processor_id, |                                                     u32 priority, u32 arg, s32 processor_id, | ||||||
|                                                     VAddr stack_top, std::shared_ptr<Process> owner_process); |                                                     VAddr stack_top, | ||||||
|  |                                                     std::shared_ptr<Process> owner_process); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Creates a semaphore. |      * Creates a semaphore. | ||||||
|  | @ -232,11 +233,11 @@ public: | ||||||
|     IPCDebugger::Recorder& GetIPCRecorder(); |     IPCDebugger::Recorder& GetIPCRecorder(); | ||||||
|     const IPCDebugger::Recorder& GetIPCRecorder() const; |     const IPCDebugger::Recorder& GetIPCRecorder() const; | ||||||
| 
 | 
 | ||||||
|     MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); |     std::shared_ptr<MemoryRegionInfo> GetMemoryRegion(MemoryRegion region); | ||||||
| 
 | 
 | ||||||
|     void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); |     void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); | ||||||
| 
 | 
 | ||||||
|     std::array<MemoryRegionInfo, 3> memory_regions; |     std::array<std::shared_ptr<MemoryRegionInfo>, 3> memory_regions{}; | ||||||
| 
 | 
 | ||||||
|     /// Adds a port to the named port table
 |     /// Adds a port to the named port table
 | ||||||
|     void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port); |     void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port); | ||||||
|  |  | ||||||
|  | @ -49,9 +49,9 @@ void KernelSystem::MemoryInit(u32 mem_type) { | ||||||
|     // the sizes specified in the memory_region_sizes table.
 |     // the sizes specified in the memory_region_sizes table.
 | ||||||
|     VAddr base = 0; |     VAddr base = 0; | ||||||
|     for (int i = 0; i < 3; ++i) { |     for (int i = 0; i < 3; ++i) { | ||||||
|         memory_regions[i].Reset(base, memory_region_sizes[mem_type][i]); |         memory_regions[i]->Reset(base, memory_region_sizes[mem_type][i]); | ||||||
| 
 | 
 | ||||||
|         base += memory_regions[i].size; |         base += memory_regions[i]->size; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // We must've allocated the entire FCRAM by the end
 |     // We must've allocated the entire FCRAM by the end
 | ||||||
|  | @ -63,20 +63,20 @@ void KernelSystem::MemoryInit(u32 mem_type) { | ||||||
|     // app_mem_malloc does not always match the configured size for memory_region[0]: in case the
 |     // app_mem_malloc does not always match the configured size for memory_region[0]: in case the
 | ||||||
|     // n3DS type override is in effect it reports the size the game expects, not the real one.
 |     // n3DS type override is in effect it reports the size the game expects, not the real one.
 | ||||||
|     config_mem.app_mem_alloc = memory_region_sizes[mem_type][0]; |     config_mem.app_mem_alloc = memory_region_sizes[mem_type][0]; | ||||||
|     config_mem.sys_mem_alloc = memory_regions[1].size; |     config_mem.sys_mem_alloc = memory_regions[1]->size; | ||||||
|     config_mem.base_mem_alloc = memory_regions[2].size; |     config_mem.base_mem_alloc = memory_regions[2]->size; | ||||||
| 
 | 
 | ||||||
|     shared_page_handler = std::make_shared<SharedPage::Handler>(timing); |     shared_page_handler = std::make_shared<SharedPage::Handler>(timing); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MemoryRegionInfo* KernelSystem::GetMemoryRegion(MemoryRegion region) { | std::shared_ptr<MemoryRegionInfo> KernelSystem::GetMemoryRegion(MemoryRegion region) { | ||||||
|     switch (region) { |     switch (region) { | ||||||
|     case MemoryRegion::APPLICATION: |     case MemoryRegion::APPLICATION: | ||||||
|         return &memory_regions[0]; |         return memory_regions[0]; | ||||||
|     case MemoryRegion::SYSTEM: |     case MemoryRegion::SYSTEM: | ||||||
|         return &memory_regions[1]; |         return memory_regions[1]; | ||||||
|     case MemoryRegion::BASE: |     case MemoryRegion::BASE: | ||||||
|         return &memory_regions[2]; |         return memory_regions[2]; | ||||||
|     default: |     default: | ||||||
|         UNREACHABLE(); |         UNREACHABLE(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -200,7 +200,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     u32 memory_used = 0; |     u32 memory_used = 0; | ||||||
| 
 | 
 | ||||||
|     MemoryRegionInfo* memory_region = nullptr; |     std::shared_ptr<MemoryRegionInfo> memory_region = nullptr; | ||||||
| 
 | 
 | ||||||
|     /// The Thread Local Storage area is allocated as processes create threads,
 |     /// The Thread Local Storage area is allocated as processes create threads,
 | ||||||
|     /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
 |     /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
 | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory( | ||||||
|     if (address == 0) { |     if (address == 0) { | ||||||
|         // We need to allocate a block from the Linear Heap ourselves.
 |         // We need to allocate a block from the Linear Heap ourselves.
 | ||||||
|         // We'll manually allocate some memory from the linear heap in the specified region.
 |         // We'll manually allocate some memory from the linear heap in the specified region.
 | ||||||
|         MemoryRegionInfo* memory_region = GetMemoryRegion(region); |         auto memory_region = GetMemoryRegion(region); | ||||||
|         auto offset = memory_region->LinearAllocate(size); |         auto offset = memory_region->LinearAllocate(size); | ||||||
| 
 | 
 | ||||||
|         ASSERT_MSG(offset, "Not enough space in region to allocate shared memory!"); |         ASSERT_MSG(offset, "Not enough space in region to allocate shared memory!"); | ||||||
|  | @ -79,7 +79,7 @@ std::shared_ptr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet( | ||||||
|     auto shared_memory{std::make_shared<SharedMemory>(*this)}; |     auto shared_memory{std::make_shared<SharedMemory>(*this)}; | ||||||
| 
 | 
 | ||||||
|     // Allocate memory in heap
 |     // Allocate memory in heap
 | ||||||
|     MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); |     auto memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); | ||||||
|     auto backing_blocks = memory_region->HeapAllocate(size); |     auto backing_blocks = memory_region->HeapAllocate(size); | ||||||
|     ASSERT_MSG(!backing_blocks.empty(), "Not enough space in region to allocate shared memory!"); |     ASSERT_MSG(!backing_blocks.empty(), "Not enough space in region to allocate shared memory!"); | ||||||
|     shared_memory->holding_memory = backing_blocks; |     shared_memory->holding_memory = backing_blocks; | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ namespace Kernel { | ||||||
| 
 | 
 | ||||||
| template <class Archive> | template <class Archive> | ||||||
| void Thread::serialize(Archive& ar, const unsigned int file_version) { | void Thread::serialize(Archive& ar, const unsigned int file_version) { | ||||||
|     ar& boost::serialization::base_object<Object>(*this); |     ar& boost::serialization::base_object<WaitObject>(*this); | ||||||
|     ar&* context.get(); |     ar&* context.get(); | ||||||
|     ar& thread_id; |     ar& thread_id; | ||||||
|     ar& status; |     ar& status; | ||||||
|  | @ -363,7 +363,7 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread( | ||||||
|     if (needs_allocation) { |     if (needs_allocation) { | ||||||
|         // There are no already-allocated pages with free slots, lets allocate a new one.
 |         // There are no already-allocated pages with free slots, lets allocate a new one.
 | ||||||
|         // TLS pages are allocated from the BASE region in the linear heap.
 |         // TLS pages are allocated from the BASE region in the linear heap.
 | ||||||
|         MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE); |         auto memory_region = GetMemoryRegion(MemoryRegion::BASE); | ||||||
| 
 | 
 | ||||||
|         // Allocate some memory from the end of the linear heap for this region.
 |         // Allocate some memory from the end of the linear heap for this region.
 | ||||||
|         auto offset = memory_region->LinearAllocate(Memory::PAGE_SIZE); |         auto offset = memory_region->LinearAllocate(Memory::PAGE_SIZE); | ||||||
|  |  | ||||||
|  | @ -824,10 +824,6 @@ std::unique_ptr<Kernel::SessionRequestHandler::SessionDataBase> GSP_GPU::MakeSes | ||||||
|     return std::make_unique<SessionData>(this); |     return std::make_unique<SessionData>(this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SessionData::SessionData() { |  | ||||||
|     UNREACHABLE(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| SessionData::SessionData(GSP_GPU* gsp) : gsp(gsp) { | SessionData::SessionData(GSP_GPU* gsp) : gsp(gsp) { | ||||||
|     // Assign a new thread id to this session when it connects. Note: In the real GSP service this
 |     // Assign a new thread id to this session when it connects. Note: In the real GSP service this
 | ||||||
|     // is done through a real thread (svcCreateThread) but we have to simulate it since our HLE
 |     // is done through a real thread (svcCreateThread) but we have to simulate it since our HLE
 | ||||||
|  |  | ||||||
|  | @ -187,7 +187,7 @@ class GSP_GPU; | ||||||
| 
 | 
 | ||||||
| class SessionData : public Kernel::SessionRequestHandler::SessionDataBase { | class SessionData : public Kernel::SessionRequestHandler::SessionDataBase { | ||||||
| public: | public: | ||||||
|     SessionData(); |     SessionData() = default; | ||||||
|     SessionData(GSP_GPU* gsp); |     SessionData(GSP_GPU* gsp); | ||||||
|     ~SessionData(); |     ~SessionData(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ | ||||||
| 
 | 
 | ||||||
| SERVICE_CONSTRUCT_IMPL(Service::LDR::RO) | SERVICE_CONSTRUCT_IMPL(Service::LDR::RO) | ||||||
| SERIALIZE_EXPORT_IMPL(Service::LDR::RO) | SERIALIZE_EXPORT_IMPL(Service::LDR::RO) | ||||||
|  | SERIALIZE_EXPORT_IMPL(Service::LDR::ClientSlot) | ||||||
| 
 | 
 | ||||||
| namespace Service::LDR { | namespace Service::LDR { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue