threadSimpleManager.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file threadSimpleManager.h
  10. * @author drose
  11. * @date 2007-06-18
  12. */
  13. #ifndef THREADSIMPLEMANAGER_H
  14. #define THREADSIMPLEMANAGER_H
  15. #include "pandabase.h"
  16. #include "selectThreadImpl.h"
  17. #ifdef THREAD_SIMPLE_IMPL
  18. #include "pdeque.h"
  19. #include "pmap.h"
  20. #include "pvector.h"
  21. #include "trueClock.h"
  22. #include "configVariableDouble.h"
  23. #include <algorithm>
  24. #ifdef HAVE_POSIX_THREADS
  25. #include <pthread.h> // for pthread_t, below
  26. #endif
  27. #ifdef WIN32
  28. #ifndef WIN32_LEAN_AND_MEAN
  29. #define WIN32_LEAN_AND_MEAN 1
  30. #endif
  31. #include <windows.h> // for DWORD, below
  32. #endif
  33. class Thread;
  34. class ThreadSimpleImpl;
  35. class BlockerSimple;
  36. struct ThreadContext;
  37. /**
  38. * This is the global object that selects the currently-active thread of the
  39. * various ThreadSimpleImpl objects running, when the currently-active thread
  40. * yields.
  41. *
  42. * This class only exists when we are using the ThreadSimple implementation,
  43. * which is to say, we are not using "real" threads.
  44. *
  45. * Generally, you shouldn't be calling these methods directly. Call the
  46. * interfaces on Thread instead.
  47. */
  48. class EXPCL_PANDA_PIPELINE ThreadSimpleManager {
  49. private:
  50. ThreadSimpleManager();
  51. public:
  52. void enqueue_ready(ThreadSimpleImpl *thread, bool volunteer);
  53. void enqueue_sleep(ThreadSimpleImpl *thread, double seconds);
  54. void enqueue_block(ThreadSimpleImpl *thread, BlockerSimple *blocker);
  55. bool unblock_one(BlockerSimple *blocker);
  56. bool unblock_all(BlockerSimple *blocker);
  57. void enqueue_finished(ThreadSimpleImpl *thread);
  58. void preempt(ThreadSimpleImpl *thread);
  59. void next_context();
  60. void prepare_for_exit();
  61. INLINE ThreadSimpleImpl *get_current_thread();
  62. void set_current_thread(ThreadSimpleImpl *current_thread);
  63. INLINE bool is_same_system_thread() const;
  64. void remove_thread(ThreadSimpleImpl *thread);
  65. static void system_sleep(double seconds);
  66. static void system_yield();
  67. double get_current_time() const;
  68. INLINE static ThreadSimpleManager *get_global_ptr();
  69. void write_status(std::ostream &out) const;
  70. private:
  71. static void init_pointers();
  72. typedef pdeque<ThreadSimpleImpl *> FifoThreads;
  73. typedef pvector<ThreadSimpleImpl *> Sleeping;
  74. static void st_choose_next_context(struct ThreadContext *from_context, void *data);
  75. void choose_next_context(struct ThreadContext *from_context);
  76. void do_timeslice_accounting(ThreadSimpleImpl *thread, double now);
  77. void wake_sleepers(Sleeping &sleepers, double now);
  78. void wake_all_sleepers(Sleeping &sleepers);
  79. void report_deadlock();
  80. double determine_timeslice(ThreadSimpleImpl *chosen_thread);
  81. void kill_non_joinable(FifoThreads &threads);
  82. void kill_non_joinable(Sleeping &threads);
  83. // STL function object to sort the priority queue of sleeping threads.
  84. class CompareStartTime {
  85. public:
  86. INLINE bool operator ()(ThreadSimpleImpl *a, ThreadSimpleImpl *b) const;
  87. };
  88. public:
  89. // Defined within the class to avoid static-init ordering problems.
  90. ConfigVariableDouble _simple_thread_epoch_timeslice;
  91. ConfigVariableDouble _simple_thread_volunteer_delay;
  92. ConfigVariableDouble _simple_thread_yield_sleep;
  93. ConfigVariableDouble _simple_thread_window;
  94. ConfigVariableDouble _simple_thread_low_weight;
  95. ConfigVariableDouble _simple_thread_normal_weight;
  96. ConfigVariableDouble _simple_thread_high_weight;
  97. ConfigVariableDouble _simple_thread_urgent_weight;
  98. private:
  99. ThreadSimpleImpl *volatile _current_thread;
  100. // The list of ready threads: threads that are ready to execute right now.
  101. FifoThreads _ready;
  102. // The list of threads that are ready, but will not be executed until next
  103. // epoch (for instance, because they exceeded their timeslice budget this
  104. // epoch).
  105. FifoThreads _next_ready;
  106. // The list of threads that are blocked on some ConditionVar or Mutex.
  107. typedef pmap<BlockerSimple *, FifoThreads> Blocked;
  108. Blocked _blocked;
  109. // Priority queue (partially-ordered heap) of sleeping threads, based on
  110. // wakeup time.
  111. Sleeping _sleeping;
  112. // Priority queue (partially-ordered heap) of volunteer threads, based on
  113. // wakeup time. This are threads that have voluntarily yielded a timeslice.
  114. // They are treated the same as sleeping threads, unless all threads are
  115. // sleeping.
  116. Sleeping _volunteers;
  117. // Threads which have finished execution and are awaiting cleanup.
  118. FifoThreads _finished;
  119. ThreadSimpleImpl *_waiting_for_exit;
  120. TrueClock *_clock;
  121. double _tick_scale;
  122. class TickRecord {
  123. public:
  124. unsigned int _tick_count;
  125. ThreadSimpleImpl *_thread;
  126. };
  127. typedef pdeque<TickRecord> TickRecords;
  128. TickRecords _tick_records;
  129. unsigned int _total_ticks;
  130. static bool _pointers_initialized;
  131. static ThreadSimpleManager *_global_ptr;
  132. };
  133. // We include this down here to avoid the circularity problem.
  134. /* okcircular */
  135. #include "threadSimpleImpl.h"
  136. #include "threadSimpleManager.I"
  137. #endif // THREAD_SIMPLE_IMPL
  138. #endif