Panda3D
|
00001 // Filename: pStatClient.h 00002 // Created by: drose (09Jul00) 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 PSTATCLIENT_H 00016 #define PSTATCLIENT_H 00017 00018 #include "pandabase.h" 00019 00020 #include "pStatFrameData.h" 00021 #include "pStatClientImpl.h" 00022 #include "pStatCollectorDef.h" 00023 #include "reMutex.h" 00024 #include "lightMutex.h" 00025 #include "reMutexHolder.h" 00026 #include "lightMutexHolder.h" 00027 #include "pmap.h" 00028 #include "thread.h" 00029 #include "weakPointerTo.h" 00030 #include "vector_int.h" 00031 #include "atomicAdjust.h" 00032 #include "numeric_types.h" 00033 #include "bitArray.h" 00034 00035 class PStatCollector; 00036 class PStatCollectorDef; 00037 class PStatThread; 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Class : PStatClient 00041 // Description : Manages the communications to report statistics via a 00042 // network connection to a remote PStatServer. 00043 // 00044 // Normally, there is only one PStatClient in the world, 00045 // although it is possible to have multiple PStatClients 00046 // if extraordinary circumstances require in. Since 00047 // each PStatCollector registers itself with the 00048 // PStatClient when it is created, having multiple 00049 // PStatClients requires special care when constructing 00050 // the various PStatCollectors. 00051 // 00052 // If DO_PSTATS is not defined, we don't want to use 00053 // stats at all. This class is therefore defined as a 00054 // stub class. 00055 //////////////////////////////////////////////////////////////////// 00056 #ifdef DO_PSTATS 00057 class EXPCL_PANDA_PSTATCLIENT PStatClient : public ConnectionManager, public Thread::PStatsCallback { 00058 public: 00059 PStatClient(); 00060 ~PStatClient(); 00061 00062 PUBLISHED: 00063 INLINE void set_client_name(const string &name); 00064 INLINE string get_client_name() const; 00065 INLINE void set_max_rate(double rate); 00066 INLINE double get_max_rate() const; 00067 00068 INLINE int get_num_collectors() const; 00069 PStatCollector get_collector(int index) const; 00070 MAKE_SEQ(get_collectors, get_num_collectors, get_collector); 00071 INLINE PStatCollectorDef *get_collector_def(int index) const; 00072 string get_collector_name(int index) const; 00073 string get_collector_fullname(int index) const; 00074 00075 INLINE int get_num_threads() const; 00076 PStatThread get_thread(int index) const; 00077 MAKE_SEQ(get_threads, get_num_threads, get_thread); 00078 INLINE string get_thread_name(int index) const; 00079 INLINE string get_thread_sync_name(int index) const; 00080 INLINE Thread *get_thread_object(int index) const; 00081 00082 PStatThread get_main_thread() const; 00083 PStatThread get_current_thread() const; 00084 00085 INLINE double get_real_time() const; 00086 00087 INLINE static bool connect(const string &hostname = string(), int port = -1); 00088 INLINE static void disconnect(); 00089 INLINE static bool is_connected(); 00090 00091 INLINE static void resume_after_pause(); 00092 00093 static void main_tick(); 00094 static void thread_tick(const string &sync_name); 00095 00096 void client_main_tick(); 00097 void client_thread_tick(const string &sync_name); 00098 INLINE bool client_connect(string hostname, int port); 00099 void client_disconnect(); 00100 INLINE bool client_is_connected() const; 00101 00102 INLINE void client_resume_after_pause(); 00103 00104 static PStatClient *get_global_pstats(); 00105 00106 private: 00107 INLINE bool has_impl() const; 00108 INLINE PStatClientImpl *get_impl(); 00109 INLINE const PStatClientImpl *get_impl() const; 00110 00111 PStatCollector make_collector_with_relname(int parent_index, string relname); 00112 PStatCollector make_collector_with_name(int parent_index, const string &name); 00113 PStatThread do_get_current_thread() const; 00114 PStatThread make_thread(Thread *thread); 00115 PStatThread do_make_thread(Thread *thread); 00116 00117 bool is_active(int collector_index, int thread_index) const; 00118 bool is_started(int collector_index, int thread_index) const; 00119 00120 void start(int collector_index, int thread_index); 00121 void start(int collector_index, int thread_index, double as_of); 00122 void stop(int collector_index, int thread_index); 00123 void stop(int collector_index, int thread_index, double as_of); 00124 00125 void clear_level(int collector_index, int thread_index); 00126 void set_level(int collector_index, int thread_index, double level); 00127 void add_level(int collector_index, int thread_index, double increment); 00128 double get_level(int collector_index, int thread_index) const; 00129 00130 static void start_clock_wait(); 00131 static void start_clock_busy_wait(); 00132 static void stop_clock_wait(); 00133 00134 class Collector; 00135 class InternalThread; 00136 void add_collector(Collector *collector); 00137 void add_thread(InternalThread *thread); 00138 00139 INLINE Collector *get_collector_ptr(int collector_index) const; 00140 INLINE InternalThread *get_thread_ptr(int thread_index) const; 00141 00142 virtual void deactivate_hook(Thread *thread); 00143 virtual void activate_hook(Thread *thread); 00144 00145 private: 00146 // This mutex protects everything in this class. 00147 ReMutex _lock; 00148 00149 typedef pmap<string, int> ThingsByName; 00150 typedef pmap<string, vector_int> MultiThingsByName; 00151 MultiThingsByName _threads_by_name, _threads_by_sync_name; 00152 00153 // This is for the data that is per-collector, per-thread. A vector 00154 // of these is stored in each Collector object, below, indexed by 00155 // thread index. 00156 class PerThreadData { 00157 public: 00158 PerThreadData(); 00159 bool _has_level; 00160 double _level; 00161 int _nested_count; 00162 }; 00163 typedef pvector<PerThreadData> PerThread; 00164 00165 // This is where the meat of the Collector data is stored. (All the 00166 // stuff in PStatCollector and PStatCollectorDef is just fluff.) 00167 class Collector { 00168 public: 00169 INLINE Collector(int parent_index, const string &name); 00170 INLINE int get_parent_index() const; 00171 INLINE const string &get_name() const; 00172 INLINE bool is_active() const; 00173 INLINE PStatCollectorDef *get_def(const PStatClient *client, int this_index) const; 00174 00175 private: 00176 void make_def(const PStatClient *client, int this_index); 00177 00178 private: 00179 // This pointer is initially NULL, and will be filled in when it 00180 // is first needed. 00181 PStatCollectorDef *_def; 00182 00183 // This data is used to create the PStatCollectorDef when it is 00184 // needed. 00185 int _parent_index; 00186 string _name; 00187 00188 public: 00189 // Relations to other collectors. 00190 ThingsByName _children; 00191 PerThread _per_thread; 00192 }; 00193 typedef Collector *CollectorPointer; 00194 AtomicAdjust::Pointer _collectors; // CollectorPointer *_collectors; 00195 AtomicAdjust::Integer _collectors_size; // size of the allocated array 00196 AtomicAdjust::Integer _num_collectors; // number of in-use elements within the array 00197 00198 // This defines a single thread, i.e. a separate chain of execution, 00199 // independent of all other threads. Timing and level data are 00200 // maintained separately for each thread. 00201 class InternalThread { 00202 public: 00203 InternalThread(Thread *thread); 00204 00205 WPT(Thread) _thread; 00206 string _name; 00207 string _sync_name; 00208 PStatFrameData _frame_data; 00209 bool _is_active; 00210 int _frame_number; 00211 double _next_packet; 00212 00213 bool _thread_active; 00214 BitArray _active_collectors; // no longer used. 00215 00216 // This mutex is used to protect writes to _frame_data for this 00217 // particular thread, as well as writes to the _per_thread data 00218 // for this particular thread in the Collector class, above. 00219 LightMutex _thread_lock; 00220 }; 00221 typedef InternalThread *ThreadPointer; 00222 AtomicAdjust::Pointer _threads; // ThreadPointer *_threads; 00223 AtomicAdjust::Integer _threads_size; // size of the allocated array 00224 AtomicAdjust::Integer _num_threads; // number of in-use elements within the array 00225 00226 PStatClientImpl *_impl; 00227 00228 static PStatCollector _heap_total_size_pcollector; 00229 static PStatCollector _heap_overhead_size_pcollector; 00230 static PStatCollector _heap_single_size_pcollector; 00231 static PStatCollector _heap_single_other_size_pcollector; 00232 static PStatCollector _heap_array_size_pcollector; 00233 static PStatCollector _heap_array_other_size_pcollector; 00234 static PStatCollector _heap_external_size_pcollector; 00235 static PStatCollector _mmap_size_pcollector; 00236 00237 static PStatCollector _mmap_nf_unused_size_pcollector; 00238 static PStatCollector _mmap_dc_active_other_size_pcollector; 00239 static PStatCollector _mmap_dc_inactive_other_size_pcollector; 00240 static PStatCollector _pstats_pcollector; 00241 static PStatCollector _clock_wait_pcollector; 00242 static PStatCollector _clock_busy_wait_pcollector; 00243 static PStatCollector _thread_block_pcollector; 00244 00245 static PStatClient *_global_pstats; 00246 00247 friend class Collector; 00248 friend class PStatCollector; 00249 friend class PStatThread; 00250 friend class PStatClientImpl; 00251 }; 00252 00253 #include "pStatClient.I" 00254 00255 #else // DO_PSTATS 00256 00257 class EXPCL_PANDA_PSTATCLIENT PStatClient { 00258 public: 00259 PStatClient() { } 00260 ~PStatClient() { } 00261 00262 PUBLISHED: 00263 INLINE static bool connect(const string & = string(), int = -1) { return false; } 00264 INLINE static void disconnect() { } 00265 INLINE static bool is_connected() { return false; } 00266 INLINE static void resume_after_pause() { } 00267 00268 INLINE static void main_tick() { } 00269 INLINE static void thread_tick(const string &) { } 00270 }; 00271 00272 #endif // DO_PSTATS 00273 00274 #endif 00275