k_synchronization_object.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <vector>
  5. #include "core/hle/kernel/k_auto_object.h"
  6. #include "core/hle/result.h"
  7. namespace Kernel {
  8. class KernelCore;
  9. class Synchronization;
  10. class KThread;
  11. /// Class that represents a Kernel object that a thread can be waiting on
  12. class KSynchronizationObject : public KAutoObjectWithList {
  13. KERNEL_AUTOOBJECT_TRAITS(KSynchronizationObject, KAutoObject);
  14. public:
  15. struct ThreadListNode {
  16. ThreadListNode* next{};
  17. KThread* thread{};
  18. };
  19. [[nodiscard]] static Result Wait(KernelCore& kernel, s32* out_index,
  20. KSynchronizationObject** objects, const s32 num_objects,
  21. s64 timeout);
  22. void Finalize() override;
  23. [[nodiscard]] virtual bool IsSignaled() const = 0;
  24. [[nodiscard]] std::vector<KThread*> GetWaitingThreadsForDebugging() const;
  25. void LinkNode(ThreadListNode* node_) {
  26. // Link the node to the list.
  27. if (thread_list_tail == nullptr) {
  28. thread_list_head = node_;
  29. } else {
  30. thread_list_tail->next = node_;
  31. }
  32. thread_list_tail = node_;
  33. }
  34. void UnlinkNode(ThreadListNode* node_) {
  35. // Unlink the node from the list.
  36. ThreadListNode* prev_ptr =
  37. reinterpret_cast<ThreadListNode*>(std::addressof(thread_list_head));
  38. ThreadListNode* prev_val = nullptr;
  39. ThreadListNode *prev, *tail_prev;
  40. do {
  41. prev = prev_ptr;
  42. prev_ptr = prev_ptr->next;
  43. tail_prev = prev_val;
  44. prev_val = prev_ptr;
  45. } while (prev_ptr != node_);
  46. if (thread_list_tail == node_) {
  47. thread_list_tail = tail_prev;
  48. }
  49. prev->next = node_->next;
  50. }
  51. protected:
  52. explicit KSynchronizationObject(KernelCore& kernel);
  53. ~KSynchronizationObject() override;
  54. virtual void OnFinalizeSynchronizationObject() {}
  55. void NotifyAvailable(Result result);
  56. void NotifyAvailable() {
  57. return this->NotifyAvailable(ResultSuccess);
  58. }
  59. private:
  60. ThreadListNode* thread_list_head{};
  61. ThreadListNode* thread_list_tail{};
  62. };
  63. } // namespace Kernel