summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/semaphore.cpp41
-rw-r--r--src/core/hle/kernel/semaphore.h9
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/** 53ResultCode 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 */
60Handle 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
76ResultCode 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
87ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { 73ResultCode 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 @@
11namespace Kernel { 11namespace 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 */
21ResultCode CreateSemaphore(Handle* handle, u32 initial_count, u32 max_count, const std::string& name = "Unknown"); 21ResultCode 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 */
30ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); 30ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count);
31
31} // namespace 32} // namespace