k_synchronization_object.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. static Result Wait(KernelCore& kernel, s32* out_index, KSynchronizationObject** objects,
  20. const s32 num_objects, s64 timeout);
  21. void Finalize() override;
  22. virtual bool IsSignaled() const = 0;
  23. std::vector<KThread*> GetWaitingThreadsForDebugging() const;
  24. void LinkNode(ThreadListNode* node_) {
  25. // Link the node to the list.
  26. if (m_thread_list_tail == nullptr) {
  27. m_thread_list_head = node_;
  28. } else {
  29. m_thread_list_tail->next = node_;
  30. }
  31. m_thread_list_tail = node_;
  32. }
  33. void UnlinkNode(ThreadListNode* node_) {
  34. // Unlink the node from the list.
  35. ThreadListNode* prev_ptr =
  36. reinterpret_cast<ThreadListNode*>(std::addressof(m_thread_list_head));
  37. ThreadListNode* prev_val = nullptr;
  38. ThreadListNode *prev, *tail_prev;
  39. do {
  40. prev = prev_ptr;
  41. prev_ptr = prev_ptr->next;
  42. tail_prev = prev_val;
  43. prev_val = prev_ptr;
  44. } while (prev_ptr != node_);
  45. if (m_thread_list_tail == node_) {
  46. m_thread_list_tail = tail_prev;
  47. }
  48. prev->next = node_->next;
  49. }
  50. protected:
  51. explicit KSynchronizationObject(KernelCore& kernel);
  52. ~KSynchronizationObject() override;
  53. virtual void OnFinalizeSynchronizationObject() {}
  54. void NotifyAvailable(Result result);
  55. void NotifyAvailable() {
  56. return this->NotifyAvailable(ResultSuccess);
  57. }
  58. private:
  59. ThreadListNode* m_thread_list_head{};
  60. ThreadListNode* m_thread_list_tail{};
  61. };
  62. } // namespace Kernel