00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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>
00032 #endif
00033 #ifdef WIN32
00034 #define WIN32_LEAN_AND_MEAN
00035 #include <windows.h>
00036 #endif
00037
00038 class Thread;
00039 class ThreadSimpleImpl;
00040 class BlockerSimple;
00041 struct ThreadContext;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
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
00102 class CompareStartTime {
00103 public:
00104 INLINE bool operator ()(ThreadSimpleImpl *a, ThreadSimpleImpl *b) const;
00105 };
00106
00107 public:
00108
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
00122
00123 FifoThreads _ready;
00124
00125
00126
00127
00128 FifoThreads _next_ready;
00129
00130
00131
00132 typedef pmap<BlockerSimple *, FifoThreads> Blocked;
00133 Blocked _blocked;
00134
00135
00136
00137 Sleeping _sleeping;
00138
00139
00140
00141
00142
00143 Sleeping _volunteers;
00144
00145
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
00168
00169 #include "threadSimpleImpl.h"
00170
00171 #include "threadSimpleManager.I"
00172
00173 #endif // THREAD_SIMPLE_IMPL
00174
00175 #endif