diff options
| -rw-r--r-- | src/core/hle/kernel/semaphore.cpp | 41 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.h | 9 |
2 files changed, 18 insertions, 32 deletions
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 216c97835..f7a895c3f 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp | |||
| @@ -27,11 +27,11 @@ public: | |||
| 27 | std::string name; ///< Name of semaphore (optional) | 27 | std::string name; ///< Name of semaphore (optional) |
| 28 | 28 | ||
| 29 | /** | 29 | /** |
| 30 | * Tests whether a semaphore is at its peak capacity | 30 | * Tests whether a semaphore still has free slots |
| 31 | * @return Whether the semaphore is full | 31 | * @return Whether the semaphore is available |
| 32 | */ | 32 | */ |
| 33 | bool IsFull() const { | 33 | bool IsAvailable() const { |
| 34 | return current_usage == max_count; | 34 | return current_usage < max_count; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | ResultVal<bool> WaitSynchronization() override { | 37 | ResultVal<bool> WaitSynchronization() override { |
| @@ -50,42 +50,27 @@ public: | |||
| 50 | 50 | ||
| 51 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 51 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 52 | 52 | ||
| 53 | /** | 53 | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, |
| 54 | * Creates a semaphore | ||
| 55 | * @param initial_count number of slots reserved for other threads | ||
| 56 | * @param max_count maximum number of holders the semaphore can have | ||
| 57 | * @param name Optional name of semaphore | ||
| 58 | * @return Handle for the newly created semaphore | ||
| 59 | */ | ||
| 60 | Handle CreateSemaphore(u32 initial_count, | ||
| 61 | u32 max_count, const std::string& name) { | 54 | u32 max_count, const std::string& name) { |
| 62 | 55 | ||
| 56 | if (initial_count > max_count) | ||
| 57 | return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, | ||
| 58 | ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||
| 59 | |||
| 63 | Semaphore* semaphore = new Semaphore; | 60 | Semaphore* semaphore = new Semaphore; |
| 64 | Handle handle = g_object_pool.Create(semaphore); | 61 | *handle = g_object_pool.Create(semaphore); |
| 65 | 62 | ||
| 66 | semaphore->initial_count = initial_count; | 63 | semaphore->initial_count = initial_count; |
| 67 | // When the semaphore is created, some slots are reserved for other threads, | 64 | // When the semaphore is created, some slots are reserved for other threads, |
| 68 | // and the rest is reserved for the caller thread | 65 | // and the rest is reserved for the caller thread |
| 69 | semaphore->max_count = semaphore->current_usage = max_count; | 66 | semaphore->max_count = max_count; |
| 70 | semaphore->current_usage -= initial_count; | 67 | semaphore->current_usage = max_count - initial_count; |
| 71 | semaphore->name = name; | 68 | semaphore->name = name; |
| 72 | 69 | ||
| 73 | return handle; | ||
| 74 | } | ||
| 75 | |||
| 76 | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, | ||
| 77 | u32 max_count, const std::string& name) { | ||
| 78 | |||
| 79 | if (initial_count > max_count) | ||
| 80 | return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, | ||
| 81 | ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||
| 82 | *handle = CreateSemaphore(initial_count, max_count, name); | ||
| 83 | |||
| 84 | return RESULT_SUCCESS; | 70 | return RESULT_SUCCESS; |
| 85 | } | 71 | } |
| 86 | 72 | ||
| 87 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | 73 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { |
| 88 | |||
| 89 | Semaphore* semaphore = g_object_pool.Get<Semaphore>(handle); | 74 | Semaphore* semaphore = g_object_pool.Get<Semaphore>(handle); |
| 90 | if (semaphore == nullptr) | 75 | if (semaphore == nullptr) |
| 91 | return InvalidHandle(ErrorModule::Kernel); | 76 | return InvalidHandle(ErrorModule::Kernel); |
| @@ -99,7 +84,7 @@ ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | |||
| 99 | 84 | ||
| 100 | // Notify some of the threads that the semaphore has been released | 85 | // Notify some of the threads that the semaphore has been released |
| 101 | // stop once the semaphore is full again or there are no more waiting threads | 86 | // stop once the semaphore is full again or there are no more waiting threads |
| 102 | while (!semaphore->waiting_threads.empty() && !semaphore->IsFull()) { | 87 | while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { |
| 103 | Kernel::ResumeThreadFromWait(semaphore->waiting_threads.front()); | 88 | Kernel::ResumeThreadFromWait(semaphore->waiting_threads.front()); |
| 104 | semaphore->waiting_threads.pop(); | 89 | semaphore->waiting_threads.pop(); |
| 105 | semaphore->current_usage++; | 90 | semaphore->current_usage++; |
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index b29812e1d..f0075fdb8 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h | |||
| @@ -11,21 +11,22 @@ | |||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * Creates a semaphore | 14 | * Creates a semaphore. |
| 15 | * @param handle Pointer to the handle of the newly created object | 15 | * @param handle Pointer to the handle of the newly created object |
| 16 | * @param initial_count number of slots reserved for other threads | 16 | * @param initial_count Number of slots reserved for other threads |
| 17 | * @param max_count maximum number of slots the semaphore can have | 17 | * @param max_count Maximum number of slots the semaphore can have |
| 18 | * @param name Optional name of semaphore | 18 | * @param name Optional name of semaphore |
| 19 | * @return ResultCode of the error | 19 | * @return ResultCode of the error |
| 20 | */ | 20 | */ |
| 21 | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, u32 max_count, const std::string& name = "Unknown"); | 21 | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, u32 max_count, const std::string& name = "Unknown"); |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * Releases a certain number of slots from a semaphore | 24 | * Releases a certain number of slots from a semaphore. |
| 25 | * @param count The number of free slots the semaphore had before this call | 25 | * @param count The number of free slots the semaphore had before this call |
| 26 | * @param handle The handle of the semaphore to release | 26 | * @param handle The handle of the semaphore to release |
| 27 | * @param release_count The number of slots to release | 27 | * @param release_count The number of slots to release |
| 28 | * @return ResultCode of the error | 28 | * @return ResultCode of the error |
| 29 | */ | 29 | */ |
| 30 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); | 30 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); |
| 31 | |||
| 31 | } // namespace | 32 | } // namespace |