Kernel/Semaphores: Addressed some issues.
This commit is contained in:
		| @@ -27,11 +27,11 @@ public: | |||||||
|     std::string name;                           ///< Name of semaphore (optional) |     std::string name;                           ///< Name of semaphore (optional) | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Tests whether a semaphore is at its peak capacity |      * Tests whether a semaphore still has free slots | ||||||
|      * @return Whether the semaphore is full |      * @return Whether the semaphore is available | ||||||
|      */ |      */ | ||||||
|     bool IsFull() const { |     bool IsAvailable() const { | ||||||
|         return current_usage == max_count; |         return current_usage < max_count; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ResultVal<bool> WaitSynchronization() override { |     ResultVal<bool> WaitSynchronization() override { | ||||||
| @@ -50,42 +50,27 @@ public: | |||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Creates a semaphore |  | ||||||
|  * @param initial_count number of slots reserved for other threads |  | ||||||
|  * @param max_count maximum number of holders the semaphore can have |  | ||||||
|  * @param name Optional name of semaphore |  | ||||||
|  * @return Handle for the newly created semaphore |  | ||||||
|  */ |  | ||||||
| Handle CreateSemaphore(u32 initial_count,  |  | ||||||
|     u32 max_count, const std::string& name) { |  | ||||||
|  |  | ||||||
|     Semaphore* semaphore = new Semaphore; |  | ||||||
|     Handle handle = g_object_pool.Create(semaphore); |  | ||||||
|  |  | ||||||
|     semaphore->initial_count = initial_count; |  | ||||||
|     // When the semaphore is created, some slots are reserved for other threads, |  | ||||||
|     // and the rest is reserved for the caller thread |  | ||||||
|     semaphore->max_count = semaphore->current_usage = max_count; |  | ||||||
|     semaphore->current_usage -= initial_count; |  | ||||||
|     semaphore->name = name; |  | ||||||
|  |  | ||||||
|     return handle; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ResultCode CreateSemaphore(Handle* handle, u32 initial_count,  | ResultCode CreateSemaphore(Handle* handle, u32 initial_count,  | ||||||
|     u32 max_count, const std::string& name) { |     u32 max_count, const std::string& name) { | ||||||
|  |  | ||||||
|     if (initial_count > max_count) |     if (initial_count > max_count) | ||||||
|         return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, |         return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, | ||||||
|                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); |                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||||
|     *handle = CreateSemaphore(initial_count, max_count, name); |  | ||||||
|  |     Semaphore* semaphore = new Semaphore; | ||||||
|  |     *handle = g_object_pool.Create(semaphore); | ||||||
|  |  | ||||||
|  |     semaphore->initial_count = initial_count; | ||||||
|  |     // 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->current_usage = max_count - initial_count; | ||||||
|  |     semaphore->name = name; | ||||||
|  |  | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | ||||||
|  |  | ||||||
|     Semaphore* semaphore = g_object_pool.Get<Semaphore>(handle); |     Semaphore* semaphore = g_object_pool.Get<Semaphore>(handle); | ||||||
|     if (semaphore == nullptr) |     if (semaphore == nullptr) | ||||||
|         return InvalidHandle(ErrorModule::Kernel); |         return InvalidHandle(ErrorModule::Kernel); | ||||||
| @@ -99,7 +84,7 @@ ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | |||||||
|  |  | ||||||
|     // Notify some of the threads that the semaphore has been released |     // Notify some of the threads that the semaphore has been released | ||||||
|     // stop once the semaphore is full again or there are no more waiting threads |     // stop once the semaphore is full again or there are no more waiting threads | ||||||
|     while (!semaphore->waiting_threads.empty() && !semaphore->IsFull()) { |     while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { | ||||||
|         Kernel::ResumeThreadFromWait(semaphore->waiting_threads.front()); |         Kernel::ResumeThreadFromWait(semaphore->waiting_threads.front()); | ||||||
|         semaphore->waiting_threads.pop(); |         semaphore->waiting_threads.pop(); | ||||||
|         semaphore->current_usage++; |         semaphore->current_usage++; | ||||||
|   | |||||||
| @@ -11,21 +11,22 @@ | |||||||
| namespace Kernel { | namespace Kernel { | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Creates a semaphore |  * Creates a semaphore. | ||||||
|  * @param handle Pointer to the handle of the newly created object |  * @param handle Pointer to the handle of the newly created object | ||||||
|  * @param initial_count number of slots reserved for other threads |  * @param initial_count Number of slots reserved for other threads | ||||||
|  * @param max_count maximum number of slots the semaphore can have |  * @param max_count Maximum number of slots the semaphore can have | ||||||
|  * @param name Optional name of semaphore |  * @param name Optional name of semaphore | ||||||
|  * @return ResultCode of the error |  * @return ResultCode of the error | ||||||
|  */ |  */ | ||||||
| ResultCode CreateSemaphore(Handle* handle, u32 initial_count, u32 max_count, const std::string& name = "Unknown"); | ResultCode CreateSemaphore(Handle* handle, u32 initial_count, u32 max_count, const std::string& name = "Unknown"); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Releases a certain number of slots from a semaphore |  * Releases a certain number of slots from a semaphore. | ||||||
|  * @param count The number of free slots the semaphore had before this call |  * @param count The number of free slots the semaphore had before this call | ||||||
|  * @param handle The handle of the semaphore to release |  * @param handle The handle of the semaphore to release | ||||||
|  * @param release_count The number of slots to release |  * @param release_count The number of slots to release | ||||||
|  * @return ResultCode of the error |  * @return ResultCode of the error | ||||||
|  */ |  */ | ||||||
| ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); | ||||||
|  |  | ||||||
| } // namespace | } // namespace | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user