Panda3D
 All Classes Functions Variables Enumerations
pStatClient.h
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 
 All Classes Functions Variables Enumerations