Panda3D
|
00001 // Filename: threadSimpleManager.h 00002 // Created by: drose (18Jun07) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef THREADSIMPLEMANAGER_H 00016 #define THREADSIMPLEMANAGER_H 00017 00018 #include "pandabase.h" 00019 #include "selectThreadImpl.h" 00020 00021 #ifdef THREAD_SIMPLE_IMPL 00022 00023 #include "pdeque.h" 00024 #include "pmap.h" 00025 #include "pvector.h" 00026 #include "trueClock.h" 00027 #include "configVariableDouble.h" 00028 #include <algorithm> 00029 00030 #ifdef HAVE_POSIX_THREADS 00031 #include <pthread.h> // for pthread_t, below 00032 #endif 00033 #ifdef WIN32 00034 #define WIN32_LEAN_AND_MEAN 00035 #include <windows.h> // for DWORD, below 00036 #endif 00037 00038 class Thread; 00039 class ThreadSimpleImpl; 00040 class BlockerSimple; 00041 struct ThreadContext; 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Class : ThreadSimpleManager 00045 // Description : This is the global object that selects the 00046 // currently-active thread of the various 00047 // ThreadSimpleImpl objects running, when the 00048 // currently-active thread yields. 00049 // 00050 // This class only exists when we are using the 00051 // ThreadSimple implementation, which is to say, we are 00052 // not using "real" threads. 00053 // 00054 // Generally, you shouldn't be calling these methods 00055 // directly. Call the interfaces on Thread instead. 00056 //////////////////////////////////////////////////////////////////// 00057 class EXPCL_PANDA_PIPELINE ThreadSimpleManager { 00058 private: 00059 ThreadSimpleManager(); 00060 00061 public: 00062 void enqueue_ready(ThreadSimpleImpl *thread, bool volunteer); 00063 void enqueue_sleep(ThreadSimpleImpl *thread, double seconds); 00064 void enqueue_block(ThreadSimpleImpl *thread, BlockerSimple *blocker); 00065 bool unblock_one(BlockerSimple *blocker); 00066 bool unblock_all(BlockerSimple *blocker); 00067 void enqueue_finished(ThreadSimpleImpl *thread); 00068 void preempt(ThreadSimpleImpl *thread); 00069 void next_context(); 00070 00071 void prepare_for_exit(); 00072 00073 INLINE ThreadSimpleImpl *get_current_thread(); 00074 void set_current_thread(ThreadSimpleImpl *current_thread); 00075 INLINE bool is_same_system_thread() const; 00076 void remove_thread(ThreadSimpleImpl *thread); 00077 static void system_sleep(double seconds); 00078 static void system_yield(); 00079 00080 double get_current_time() const; 00081 INLINE static ThreadSimpleManager *get_global_ptr(); 00082 00083 void write_status(ostream &out) const; 00084 00085 private: 00086 static void init_pointers(); 00087 00088 typedef pdeque<ThreadSimpleImpl *> FifoThreads; 00089 typedef pvector<ThreadSimpleImpl *> Sleeping; 00090 00091 static void st_choose_next_context(struct ThreadContext *from_context, void *data); 00092 void choose_next_context(struct ThreadContext *from_context); 00093 void do_timeslice_accounting(ThreadSimpleImpl *thread, double now); 00094 void wake_sleepers(Sleeping &sleepers, double now); 00095 void wake_all_sleepers(Sleeping &sleepers); 00096 void report_deadlock(); 00097 double determine_timeslice(ThreadSimpleImpl *chosen_thread); 00098 void kill_non_joinable(FifoThreads &threads); 00099 void kill_non_joinable(Sleeping &threads); 00100 00101 // STL function object to sort the priority queue of sleeping threads. 00102 class CompareStartTime { 00103 public: 00104 INLINE bool operator ()(ThreadSimpleImpl *a, ThreadSimpleImpl *b) const; 00105 }; 00106 00107 public: 00108 // Defined within the class to avoid static-init ordering problems. 00109 ConfigVariableDouble _simple_thread_epoch_timeslice; 00110 ConfigVariableDouble _simple_thread_volunteer_delay; 00111 ConfigVariableDouble _simple_thread_yield_sleep; 00112 ConfigVariableDouble _simple_thread_window; 00113 ConfigVariableDouble _simple_thread_low_weight; 00114 ConfigVariableDouble _simple_thread_normal_weight; 00115 ConfigVariableDouble _simple_thread_high_weight; 00116 ConfigVariableDouble _simple_thread_urgent_weight; 00117 00118 private: 00119 ThreadSimpleImpl *volatile _current_thread; 00120 00121 // The list of ready threads: threads that are ready to execute 00122 // right now. 00123 FifoThreads _ready; 00124 00125 // The list of threads that are ready, but will not be executed 00126 // until next epoch (for instance, because they exceeded their 00127 // timeslice budget this epoch). 00128 FifoThreads _next_ready; 00129 00130 // The list of threads that are blocked on some ConditionVar or 00131 // Mutex. 00132 typedef pmap<BlockerSimple *, FifoThreads> Blocked; 00133 Blocked _blocked; 00134 00135 // Priority queue (partially-ordered heap) of sleeping threads, 00136 // based on wakeup time. 00137 Sleeping _sleeping; 00138 00139 // Priority queue (partially-ordered heap) of volunteer threads, 00140 // based on wakeup time. This are threads that have voluntarily 00141 // yielded a timeslice. They are treated the same as sleeping 00142 // threads, unless all threads are sleeping. 00143 Sleeping _volunteers; 00144 00145 // Threads which have finished execution and are awaiting cleanup. 00146 FifoThreads _finished; 00147 00148 ThreadSimpleImpl *_waiting_for_exit; 00149 00150 TrueClock *_clock; 00151 00152 double _tick_scale; 00153 00154 class TickRecord { 00155 public: 00156 unsigned int _tick_count; 00157 ThreadSimpleImpl *_thread; 00158 }; 00159 typedef pdeque<TickRecord> TickRecords; 00160 TickRecords _tick_records; 00161 unsigned int _total_ticks; 00162 00163 static bool _pointers_initialized; 00164 static ThreadSimpleManager *_global_ptr; 00165 }; 00166 00167 // We include this down here to avoid the circularity problem. 00168 /* okcircular */ 00169 #include "threadSimpleImpl.h" 00170 00171 #include "threadSimpleManager.I" 00172 00173 #endif // THREAD_SIMPLE_IMPL 00174 00175 #endif