Просмотр исходного кода

semaphore: Updates for Switch.

bunnei 8 лет назад
Родитель
Сommit
91f10a1460
2 измененных файлов с 31 добавлено и 21 удалено
  1. 17 14
      src/core/hle/kernel/semaphore.cpp
  2. 14 7
      src/core/hle/kernel/semaphore.h

+ 17 - 14
src/core/hle/kernel/semaphore.cpp

@@ -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

+ 14 - 7
src/core/hle/kernel/semaphore.h

@@ -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