mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-31 16:09:03 -05:00 
			
		
		
		
	Run clang-format on PR.
This commit is contained in:
		| @@ -14,160 +14,161 @@ | ||||
| #include "core/memory.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|     namespace AddressArbiter { | ||||
| namespace AddressArbiter { | ||||
|  | ||||
|         // Performs actual address waiting logic. | ||||
|         ResultCode WaitForAddress(VAddr address, s64 timeout) { | ||||
|             SharedPtr<Thread> current_thread = GetCurrentThread(); | ||||
|             current_thread->arb_wait_address = address; | ||||
|             current_thread->status = THREADSTATUS_WAIT_ARB; | ||||
|             current_thread->wakeup_callback = nullptr; | ||||
| // Performs actual address waiting logic. | ||||
| ResultCode WaitForAddress(VAddr address, s64 timeout) { | ||||
|     SharedPtr<Thread> current_thread = GetCurrentThread(); | ||||
|     current_thread->arb_wait_address = address; | ||||
|     current_thread->status = THREADSTATUS_WAIT_ARB; | ||||
|     current_thread->wakeup_callback = nullptr; | ||||
|  | ||||
|             current_thread->WakeAfterDelay(timeout); | ||||
|     current_thread->WakeAfterDelay(timeout); | ||||
|  | ||||
|             Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); | ||||
|             // This should never actually execute. | ||||
|             return RESULT_SUCCESS; | ||||
|         } | ||||
|     Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); | ||||
|     // This should never actually execute. | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
|         // Gets the threads waiting on an address. | ||||
|         void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>> &waiting_threads, VAddr address) { | ||||
|             auto RetrieveWaitingThreads = | ||||
|                 [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { | ||||
|                 const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); | ||||
|                 auto& thread_list = scheduler->GetThreadList(); | ||||
| // Gets the threads waiting on an address. | ||||
| void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, VAddr address) { | ||||
|     auto RetrieveWaitingThreads = | ||||
|         [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { | ||||
|             const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); | ||||
|             auto& thread_list = scheduler->GetThreadList(); | ||||
|  | ||||
|                 for (auto& thread : thread_list) { | ||||
|                     if (thread->arb_wait_address == arb_addr) | ||||
|                         waiting_threads.push_back(thread); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             // Retrieve a list of all threads that are waiting for this address. | ||||
|             RetrieveWaitingThreads(0, waiting_threads, address); | ||||
|             RetrieveWaitingThreads(1, waiting_threads, address); | ||||
|             RetrieveWaitingThreads(2, waiting_threads, address); | ||||
|             RetrieveWaitingThreads(3, waiting_threads, address); | ||||
|             // Sort them by priority, such that the highest priority ones come first. | ||||
|             std::sort(waiting_threads.begin(), waiting_threads.end(), | ||||
|                 [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { | ||||
|                 return lhs->current_priority < rhs->current_priority; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         // Wake up num_to_wake (or all) threads in a vector. | ||||
|         void WakeThreads(std::vector<SharedPtr<Thread>> &waiting_threads, s32 num_to_wake) { | ||||
|             // Only process up to 'target' threads, unless 'target' is <= 0, in which case process | ||||
|             // them all. | ||||
|             size_t last = waiting_threads.size(); | ||||
|             if (num_to_wake > 0) | ||||
|                 last = num_to_wake; | ||||
|  | ||||
|             // Signal the waiting threads. | ||||
|             // TODO: Rescheduling should not occur while waking threads. How can it be prevented? | ||||
|             for (size_t i = 0; i < last; i++) { | ||||
|                 ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); | ||||
|                 waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||||
|                 waiting_threads[i]->arb_wait_address = 0; | ||||
|                 waiting_threads[i]->ResumeFromWait(); | ||||
|             for (auto& thread : thread_list) { | ||||
|                 if (thread->arb_wait_address == arb_addr) | ||||
|                     waiting_threads.push_back(thread); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         } | ||||
|     // Retrieve a list of all threads that are waiting for this address. | ||||
|     RetrieveWaitingThreads(0, waiting_threads, address); | ||||
|     RetrieveWaitingThreads(1, waiting_threads, address); | ||||
|     RetrieveWaitingThreads(2, waiting_threads, address); | ||||
|     RetrieveWaitingThreads(3, waiting_threads, address); | ||||
|     // Sort them by priority, such that the highest priority ones come first. | ||||
|     std::sort(waiting_threads.begin(), waiting_threads.end(), | ||||
|               [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { | ||||
|                   return lhs->current_priority < rhs->current_priority; | ||||
|               }); | ||||
| } | ||||
|  | ||||
|         // Signals an address being waited on. | ||||
|         ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { | ||||
|             // Get threads waiting on the address. | ||||
|             std::vector<SharedPtr<Thread>> waiting_threads; | ||||
|             GetThreadsWaitingOnAddress(waiting_threads, address); | ||||
| // Wake up num_to_wake (or all) threads in a vector. | ||||
| void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) { | ||||
|     // Only process up to 'target' threads, unless 'target' is <= 0, in which case process | ||||
|     // them all. | ||||
|     size_t last = waiting_threads.size(); | ||||
|     if (num_to_wake > 0) | ||||
|         last = num_to_wake; | ||||
|  | ||||
|             WakeThreads(waiting_threads, num_to_wake); | ||||
|             return RESULT_SUCCESS; | ||||
|         } | ||||
|     // Signal the waiting threads. | ||||
|     // TODO: Rescheduling should not occur while waking threads. How can it be prevented? | ||||
|     for (size_t i = 0; i < last; i++) { | ||||
|         ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); | ||||
|         waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||||
|         waiting_threads[i]->arb_wait_address = 0; | ||||
|         waiting_threads[i]->ResumeFromWait(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|         // Signals an address being waited on and increments its value if equal to the value argument. | ||||
|         ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { | ||||
|             // Ensure that we can write to the address. | ||||
|             if (!Memory::IsValidVirtualAddress(address)) { | ||||
|                 return ERR_INVALID_ADDRESS_STATE; | ||||
|             } | ||||
| // Signals an address being waited on. | ||||
| ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { | ||||
|     // Get threads waiting on the address. | ||||
|     std::vector<SharedPtr<Thread>> waiting_threads; | ||||
|     GetThreadsWaitingOnAddress(waiting_threads, address); | ||||
|  | ||||
|             if ((s32)Memory::Read32(address) == value) { | ||||
|                 Memory::Write32(address, (u32)(value + 1)); | ||||
|             } else { | ||||
|                 return ERR_INVALID_STATE; | ||||
|             } | ||||
|     WakeThreads(waiting_threads, num_to_wake); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
|             return SignalToAddress(address, num_to_wake); | ||||
|         } | ||||
| // Signals an address being waited on and increments its value if equal to the value argument. | ||||
| ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { | ||||
|     // Ensure that we can write to the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|         // Signals an address being waited on and modifies its value based on waiting thread count if equal to the value argument. | ||||
|         ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { | ||||
|             // Ensure that we can write to the address. | ||||
|             if (!Memory::IsValidVirtualAddress(address)) { | ||||
|                 return ERR_INVALID_ADDRESS_STATE; | ||||
|             } | ||||
|     if ((s32)Memory::Read32(address) == value) { | ||||
|         Memory::Write32(address, (u32)(value + 1)); | ||||
|     } else { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|  | ||||
|             // Get threads waiting on the address. | ||||
|             std::vector<SharedPtr<Thread>> waiting_threads; | ||||
|             GetThreadsWaitingOnAddress(waiting_threads, address); | ||||
|     return SignalToAddress(address, num_to_wake); | ||||
| } | ||||
|  | ||||
|             // Determine the modified value depending on the waiting count. | ||||
|             s32 updated_value; | ||||
|             if (waiting_threads.size() == 0) { | ||||
|                 updated_value = value - 1; | ||||
|             } else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) { | ||||
|                 updated_value = value + 1; | ||||
|             } else { | ||||
|                 updated_value = value; | ||||
|             } | ||||
| // Signals an address being waited on and modifies its value based on waiting thread count if equal | ||||
| // to the value argument. | ||||
| ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, | ||||
|                                                          s32 num_to_wake) { | ||||
|     // Ensure that we can write to the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|             if ((s32)Memory::Read32(address) == value) { | ||||
|                 Memory::Write32(address, (u32)(updated_value)); | ||||
|             } else { | ||||
|                 return ERR_INVALID_STATE; | ||||
|             } | ||||
|     // Get threads waiting on the address. | ||||
|     std::vector<SharedPtr<Thread>> waiting_threads; | ||||
|     GetThreadsWaitingOnAddress(waiting_threads, address); | ||||
|  | ||||
|             WakeThreads(waiting_threads, num_to_wake); | ||||
|             return RESULT_SUCCESS; | ||||
|         } | ||||
|     // Determine the modified value depending on the waiting count. | ||||
|     s32 updated_value; | ||||
|     if (waiting_threads.size() == 0) { | ||||
|         updated_value = value - 1; | ||||
|     } else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) { | ||||
|         updated_value = value + 1; | ||||
|     } else { | ||||
|         updated_value = value; | ||||
|     } | ||||
|  | ||||
|         // Waits on an address if the value passed is less than the argument value, optionally decrementing. | ||||
|         ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement) { | ||||
|             // Ensure that we can read the address. | ||||
|             if (!Memory::IsValidVirtualAddress(address)) { | ||||
|                 return ERR_INVALID_ADDRESS_STATE; | ||||
|             } | ||||
|     if ((s32)Memory::Read32(address) == value) { | ||||
|         Memory::Write32(address, (u32)(updated_value)); | ||||
|     } else { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|  | ||||
|             s32 cur_value = (s32)Memory::Read32(address); | ||||
|             if (cur_value < value) { | ||||
|                 Memory::Write32(address, (u32)(cur_value - 1)); | ||||
|             } else { | ||||
|                 return ERR_INVALID_STATE; | ||||
|             } | ||||
|             // Short-circuit without rescheduling, if timeout is zero. | ||||
|             if (timeout == 0) { | ||||
|                 return RESULT_TIMEOUT; | ||||
|             } | ||||
|     WakeThreads(waiting_threads, num_to_wake); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
|             return WaitForAddress(address, timeout); | ||||
|         } | ||||
| // Waits on an address if the value passed is less than the argument value, optionally decrementing. | ||||
| ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement) { | ||||
|     // Ensure that we can read the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|  | ||||
|         // Waits on an address if the value passed is equal to the argument value. | ||||
|         ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { | ||||
|             // Ensure that we can read the address. | ||||
|             if (!Memory::IsValidVirtualAddress(address)) { | ||||
|                 return ERR_INVALID_ADDRESS_STATE; | ||||
|             } | ||||
|             // Only wait for the address if equal. | ||||
|             if ((s32)Memory::Read32(address) != value) { | ||||
|                 return ERR_INVALID_STATE; | ||||
|             } | ||||
|             // Short-circuit without rescheduling, if timeout is zero. | ||||
|             if (timeout == 0) { | ||||
|                 return RESULT_TIMEOUT; | ||||
|             } | ||||
|     s32 cur_value = (s32)Memory::Read32(address); | ||||
|     if (cur_value < value) { | ||||
|         Memory::Write32(address, (u32)(cur_value - 1)); | ||||
|     } else { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|     // Short-circuit without rescheduling, if timeout is zero. | ||||
|     if (timeout == 0) { | ||||
|         return RESULT_TIMEOUT; | ||||
|     } | ||||
|  | ||||
|             return WaitForAddress(address, timeout); | ||||
|         } | ||||
|     } // namespace AddressArbiter | ||||
| } // namespace Kernel | ||||
|     return WaitForAddress(address, timeout); | ||||
| } | ||||
|  | ||||
| // Waits on an address if the value passed is equal to the argument value. | ||||
| ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { | ||||
|     // Ensure that we can read the address. | ||||
|     if (!Memory::IsValidVirtualAddress(address)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
|     // Only wait for the address if equal. | ||||
|     if ((s32)Memory::Read32(address) != value) { | ||||
|         return ERR_INVALID_STATE; | ||||
|     } | ||||
|     // Short-circuit without rescheduling, if timeout is zero. | ||||
|     if (timeout == 0) { | ||||
|         return RESULT_TIMEOUT; | ||||
|     } | ||||
|  | ||||
|     return WaitForAddress(address, timeout); | ||||
| } | ||||
| } // namespace AddressArbiter | ||||
| } // namespace Kernel | ||||
|   | ||||
| @@ -8,25 +8,25 @@ | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
|     namespace AddressArbiter { | ||||
|         enum class ArbitrationType { | ||||
|             WaitIfLessThan = 0, | ||||
|             DecrementAndWaitIfLessThan = 1, | ||||
|             WaitIfEqual = 2, | ||||
|         }; | ||||
| namespace AddressArbiter { | ||||
| enum class ArbitrationType { | ||||
|     WaitIfLessThan = 0, | ||||
|     DecrementAndWaitIfLessThan = 1, | ||||
|     WaitIfEqual = 2, | ||||
| }; | ||||
|  | ||||
|         enum class SignalType { | ||||
|             Signal = 0, | ||||
|             IncrementAndSignalIfEqual = 1, | ||||
|             ModifyByWaitingCountAndSignalIfEqual = 2, | ||||
|         }; | ||||
| enum class SignalType { | ||||
|     Signal = 0, | ||||
|     IncrementAndSignalIfEqual = 1, | ||||
|     ModifyByWaitingCountAndSignalIfEqual = 2, | ||||
| }; | ||||
|  | ||||
|         ResultCode SignalToAddress(VAddr address, s32 num_to_wake); | ||||
|         ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); | ||||
|         ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); | ||||
| ResultCode SignalToAddress(VAddr address, s32 num_to_wake); | ||||
| ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); | ||||
| ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); | ||||
|  | ||||
|         ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement); | ||||
|         ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); | ||||
|     } // namespace AddressArbiter | ||||
| ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement); | ||||
| ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); | ||||
| } // namespace AddressArbiter | ||||
|  | ||||
| } // namespace Kernel | ||||
| } // namespace Kernel | ||||
|   | ||||
| @@ -228,8 +228,8 @@ public: | ||||
|  | ||||
|     // If waiting on a ConditionVariable, this is the ConditionVariable  address | ||||
|     VAddr condvar_wait_address; | ||||
|     VAddr mutex_wait_address;   ///< If waiting on a Mutex, this is the mutex address | ||||
|     Handle wait_handle;         ///< The handle used to wait for the mutex. | ||||
|     VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address | ||||
|     Handle wait_handle;       ///< The handle used to wait for the mutex. | ||||
|  | ||||
|     // If waiting for an AddressArbiter, this is the address being waited on. | ||||
|     VAddr arb_wait_address{0}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Scire
					Michael Scire