diff options
| author | 2017-01-05 12:55:01 -0500 | |
|---|---|---|
| committer | 2017-01-05 12:55:01 -0500 | |
| commit | f20d872643654c574f73a263f032613046900f07 (patch) | |
| tree | 021284c18034d053c81928fa19d2efb6658451fb /src/core/hle/kernel/thread.h | |
| parent | Merge pull request #2407 from jroweboy/nightly-deploy (diff) | |
| parent | Kernel: Add some asserts to enforce the invariants in the scheduler. (diff) | |
| download | yuzu-f20d872643654c574f73a263f032613046900f07.tar.gz yuzu-f20d872643654c574f73a263f032613046900f07.tar.xz yuzu-f20d872643654c574f73a263f032613046900f07.zip | |
Merge pull request #2393 from Subv/synch
Kernel: Mutex priority inheritance and synchronization improvements.
Diffstat (limited to 'src/core/hle/kernel/thread.h')
| -rw-r--r-- | src/core/hle/kernel/thread.h | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index c77ac644d..af72b76ea 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -31,13 +31,14 @@ enum ThreadProcessorId : s32 { | |||
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | enum ThreadStatus { | 33 | enum ThreadStatus { |
| 34 | THREADSTATUS_RUNNING, ///< Currently running | 34 | THREADSTATUS_RUNNING, ///< Currently running |
| 35 | THREADSTATUS_READY, ///< Ready to run | 35 | THREADSTATUS_READY, ///< Ready to run |
| 36 | THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter | 36 | THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter |
| 37 | THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC | 37 | THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC |
| 38 | THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC | 38 | THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false |
| 39 | THREADSTATUS_DORMANT, ///< Created but not yet made ready | 39 | THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true |
| 40 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated | 40 | THREADSTATUS_DORMANT, ///< Created but not yet made ready |
| 41 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | namespace Kernel { | 44 | namespace Kernel { |
| @@ -72,8 +73,8 @@ public: | |||
| 72 | return HANDLE_TYPE; | 73 | return HANDLE_TYPE; |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | bool ShouldWait() override; | 76 | bool ShouldWait(Thread* thread) const override; |
| 76 | void Acquire() override; | 77 | void Acquire(Thread* thread) override; |
| 77 | 78 | ||
| 78 | /** | 79 | /** |
| 79 | * Gets the thread's current priority | 80 | * Gets the thread's current priority |
| @@ -90,6 +91,12 @@ public: | |||
| 90 | void SetPriority(s32 priority); | 91 | void SetPriority(s32 priority); |
| 91 | 92 | ||
| 92 | /** | 93 | /** |
| 94 | * Boost's a thread's priority to the best priority among the thread's held mutexes. | ||
| 95 | * This prevents priority inversion via priority inheritance. | ||
| 96 | */ | ||
| 97 | void UpdatePriority(); | ||
| 98 | |||
| 99 | /** | ||
| 93 | * Temporarily boosts the thread's priority until the next time it is scheduled | 100 | * Temporarily boosts the thread's priority until the next time it is scheduled |
| 94 | * @param priority The new priority | 101 | * @param priority The new priority |
| 95 | */ | 102 | */ |
| @@ -128,13 +135,14 @@ public: | |||
| 128 | 135 | ||
| 129 | /** | 136 | /** |
| 130 | * Retrieves the index that this particular object occupies in the list of objects | 137 | * Retrieves the index that this particular object occupies in the list of objects |
| 131 | * that the thread passed to WaitSynchronizationN. | 138 | * that the thread passed to WaitSynchronizationN, starting the search from the last element. |
| 132 | * It is used to set the output value of WaitSynchronizationN when the thread is awakened. | 139 | * It is used to set the output value of WaitSynchronizationN when the thread is awakened. |
| 140 | * When a thread wakes up due to an object signal, the kernel will use the index of the last | ||
| 141 | * matching object in the wait objects list in case of having multiple instances of the same | ||
| 142 | * object in the list. | ||
| 133 | * @param object Object to query the index of. | 143 | * @param object Object to query the index of. |
| 134 | */ | 144 | */ |
| 135 | s32 GetWaitObjectIndex(const WaitObject* object) const { | 145 | s32 GetWaitObjectIndex(WaitObject* object) const; |
| 136 | return wait_objects_index.at(object->GetObjectId()); | ||
| 137 | } | ||
| 138 | 146 | ||
| 139 | /** | 147 | /** |
| 140 | * Stops a thread, invalidating it from further use | 148 | * Stops a thread, invalidating it from further use |
| @@ -152,10 +160,10 @@ public: | |||
| 152 | /** | 160 | /** |
| 153 | * Returns whether this thread is waiting for all the objects in | 161 | * Returns whether this thread is waiting for all the objects in |
| 154 | * its wait list to become ready, as a result of a WaitSynchronizationN call | 162 | * its wait list to become ready, as a result of a WaitSynchronizationN call |
| 155 | * with wait_all = true, or a ReplyAndReceive call. | 163 | * with wait_all = true. |
| 156 | */ | 164 | */ |
| 157 | bool IsSleepingOnWaitAll() const { | 165 | bool IsSleepingOnWaitAll() const { |
| 158 | return !wait_objects.empty(); | 166 | return status == THREADSTATUS_WAIT_SYNCH_ALL; |
| 159 | } | 167 | } |
| 160 | 168 | ||
| 161 | ARM_Interface::ThreadContext context; | 169 | ARM_Interface::ThreadContext context; |
| @@ -178,15 +186,15 @@ public: | |||
| 178 | /// Mutexes currently held by this thread, which will be released when it exits. | 186 | /// Mutexes currently held by this thread, which will be released when it exits. |
| 179 | boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; | 187 | boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; |
| 180 | 188 | ||
| 189 | /// Mutexes that this thread is currently waiting for. | ||
| 190 | boost::container::flat_set<SharedPtr<Mutex>> pending_mutexes; | ||
| 191 | |||
| 181 | SharedPtr<Process> owner_process; ///< Process that owns this thread | 192 | SharedPtr<Process> owner_process; ///< Process that owns this thread |
| 182 | 193 | ||
| 183 | /// Objects that the thread is waiting on. | 194 | /// Objects that the thread is waiting on, in the same order as they were |
| 184 | /// This is only populated when the thread should wait for all the objects to become ready. | 195 | // passed to WaitSynchronization1/N. |
| 185 | std::vector<SharedPtr<WaitObject>> wait_objects; | 196 | std::vector<SharedPtr<WaitObject>> wait_objects; |
| 186 | 197 | ||
| 187 | /// Mapping of Object ids to their position in the last waitlist that this object waited on. | ||
| 188 | boost::container::flat_map<int, s32> wait_objects_index; | ||
| 189 | |||
| 190 | VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address | 198 | VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address |
| 191 | 199 | ||
| 192 | /// True if the WaitSynchronizationN output parameter should be set on thread wakeup. | 200 | /// True if the WaitSynchronizationN output parameter should be set on thread wakeup. |