mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 18:54:14 +01:00 
			
		
		
		
	semaphore: Updates for Switch.
This commit is contained in:
		
							parent
							
								
									6f6d9af408
								
							
						
					
					
						commit
						91f10a1460
					
				| @ -5,6 +5,7 @@ | ||||
| #include "common/assert.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/object_address_table.h" | ||||
| #include "core/hle/kernel/semaphore.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| 
 | ||||
| @ -13,20 +14,18 @@ namespace Kernel { | ||||
| Semaphore::Semaphore() {} | ||||
| Semaphore::~Semaphore() {} | ||||
| 
 | ||||
| ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, VAddr address, | ||||
|                                                   std::string name) { | ||||
| 
 | ||||
|     if (initial_count > max_count) | ||||
|         return ERR_INVALID_COMBINATION_KERNEL; | ||||
| 
 | ||||
| ResultVal<SharedPtr<Semaphore>> Semaphore::Create(VAddr guest_addr, VAddr mutex_addr, std::string name) { | ||||
|     SharedPtr<Semaphore> semaphore(new Semaphore); | ||||
| 
 | ||||
|     // When the semaphore is created, some slots are reserved for other threads,
 | ||||
|     // and the rest is reserved for the caller thread
 | ||||
|     semaphore->max_count = max_count; | ||||
|     semaphore->available_count = initial_count; | ||||
|     semaphore->address = address; | ||||
|     // and the rest is reserved for the caller thread;
 | ||||
|     semaphore->available_count = Memory::Read32(guest_addr); | ||||
|     semaphore->name = std::move(name); | ||||
|     semaphore->guest_addr = guest_addr; | ||||
|     semaphore->mutex_addr = mutex_addr; | ||||
| 
 | ||||
|     // Semaphores are referenced by guest address, so track this in the kernel
 | ||||
|     g_object_address_table.Insert(guest_addr, semaphore); | ||||
| 
 | ||||
|     return MakeResult<SharedPtr<Semaphore>>(std::move(semaphore)); | ||||
| } | ||||
| @ -39,18 +38,22 @@ void Semaphore::Acquire(Thread* thread) { | ||||
|     if (available_count <= 0) | ||||
|         return; | ||||
|     --available_count; | ||||
|     UpdateGuestState(); | ||||
| } | ||||
| 
 | ||||
| ResultVal<s32> Semaphore::Release(s32 release_count) { | ||||
|     if (max_count - available_count < release_count) | ||||
|         return ERR_OUT_OF_RANGE_KERNEL; | ||||
| 
 | ||||
|     s32 previous_count = available_count; | ||||
|     available_count += release_count; | ||||
|     UpdateGuestState(); | ||||
| 
 | ||||
|     WakeupAllWaitingThreads(); | ||||
| 
 | ||||
|     return MakeResult<s32>(previous_count); | ||||
| } | ||||
| 
 | ||||
| } // namespace
 | ||||
| void Semaphore::UpdateGuestState() { | ||||
|     Memory::Write32(guest_addr, available_count); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
|  | ||||
| @ -17,12 +17,14 @@ class Semaphore final : public WaitObject { | ||||
| public: | ||||
|     /**
 | ||||
|      * Creates a semaphore. | ||||
|      * @param initial_count Number of slots reserved for other threads | ||||
|      * @param max_count Maximum number of slots the semaphore can have | ||||
|      * @param name Optional name of semaphore | ||||
|      * @return The created semaphore | ||||
|      * @param guest_addr Address of the object tracking the semaphore in guest memory. If specified, | ||||
|      * this semaphore will update the guest object when its state changes. | ||||
|      * @param mutex_addr Optional address of a guest mutex associated with this semaphore, used by | ||||
|      * the OS for implementing events. | ||||
|      * @param name Optional name of semaphore. | ||||
|      * @return The created semaphore. | ||||
|      */ | ||||
|     static ResultVal<SharedPtr<Semaphore>> Create(s32 initial_count, s32 max_count, VAddr address, | ||||
|     static ResultVal<SharedPtr<Semaphore>> Create(VAddr guest_addr, VAddr mutex_addr = 0, | ||||
|                                                   std::string name = "Unknown"); | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
| @ -39,8 +41,10 @@ public: | ||||
| 
 | ||||
|     s32 max_count;       ///< Maximum number of simultaneous holders the semaphore can have
 | ||||
|     s32 available_count; ///< Number of free slots left in the semaphore
 | ||||
|     VAddr address; | ||||
|     std::string name;    ///< Name of semaphore (optional)
 | ||||
|     VAddr guest_addr;    ///< Address of the guest semaphore value
 | ||||
|     VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this semaphore,
 | ||||
|                       ///< used for implementing events
 | ||||
| 
 | ||||
|     bool ShouldWait(Thread* thread) const override; | ||||
|     void Acquire(Thread* thread) override; | ||||
| @ -55,6 +59,9 @@ public: | ||||
| private: | ||||
|     Semaphore(); | ||||
|     ~Semaphore() override; | ||||
| 
 | ||||
|     /// Updates the state of the object tracking this semaphore in guest memory
 | ||||
|     void UpdateGuestState(); | ||||
| }; | ||||
| 
 | ||||
| } // namespace
 | ||||
| } // namespace Kernel
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user