Go to the documentation of this file.00001
00002
00003 #include "ace/Monitor_Control/CPU_Load_Monitor.h"
00004
00005 #if defined (ACE_HAS_MONITOR_FRAMEWORK) && (ACE_HAS_MONITOR_FRAMEWORK == 1)
00006
00007 #if defined (ACE_HAS_KSTAT)
00008 #include <sys/sysinfo.h>
00009 #endif
00010
00011 #if defined (linux)
00012 #include "ace/OS_NS_stdio.h"
00013 #endif
00014
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016
00017 namespace ACE
00018 {
00019 namespace Monitor_Control
00020 {
00021 const char* CPU_Load_Monitor::default_name_ =
00022 "OS/Processor/CPULoad";
00023
00024 CPU_Load_Monitor::CPU_Load_Monitor (const char* name)
00025 : Monitor_Base (name, Monitor_Control_Types::MC_NUMBER)
00026 #if defined (ACE_HAS_WIN32_PDH)
00027 , Windows_Monitor (ACE_TEXT("\\Processor(_Total)\\% Processor Time"))
00028 #endif
00029 #if defined (linux) || defined (ACE_HAS_KSTAT)
00030 , user_ (0)
00031 , wait_ (0)
00032 , kernel_ (0)
00033 , idle_ (0)
00034 , prev_idle_ (0)
00035 , prev_total_ (0.0)
00036 #endif
00037 #if defined (linux)
00038 , file_ptr_ (0)
00039 #elif defined (ACE_HAS_KSTAT)
00040 , kstats_ (0)
00041 , kstat_ (0)
00042 , kstat_id_ (0)
00043 #endif
00044 {
00045 this->init ();
00046 }
00047
00048 void
00049 CPU_Load_Monitor::update (void)
00050 {
00051 #if defined (ACE_HAS_WIN32_PDH)
00052 this->update_i ();
00053 this->receive (this->value_);
00054 #elif defined (linux)
00055 this->access_proc_stat (&this->idle_);
00056 #elif defined (ACE_HAS_KSTAT)
00057 this->access_kstats (&this->idle_);
00058 #endif
00059
00060 #if defined (linux) || defined (ACE_HAS_KSTAT)
00061 double delta_idle = this->idle_ - this->prev_idle_;
00062 double total =
00063 this->user_ + this->wait_ + this->kernel_ + this->idle_;
00064 double delta_total = total - this->prev_total_;
00065
00066 if (delta_total == 0.0)
00067 {
00068
00069
00070 return;
00071 }
00072
00073 double percent_cpu_load = 100.0 - (delta_idle / delta_total * 100.0);
00074
00075
00076 this->receive (percent_cpu_load);
00077
00078 this->prev_idle_ = this->idle_;
00079 this->prev_total_ = total;
00080 #endif
00081 }
00082
00083 const char*
00084 CPU_Load_Monitor::default_name (void)
00085 {
00086 return CPU_Load_Monitor::default_name_;
00087 }
00088
00089 void
00090 CPU_Load_Monitor::clear_i (void)
00091 {
00092 #if defined (ACE_HAS_WIN32_PDH)
00093 this->clear_impl ();
00094 #endif
00095
00096 this->init ();
00097 this->Monitor_Base::clear_i ();
00098 }
00099
00100 void
00101 CPU_Load_Monitor::init (void)
00102 {
00103 #if defined (linux)
00104
00105
00106
00107 this->access_proc_stat (&this->prev_idle_);
00108
00109 this->prev_total_ =
00110 this->user_ + this->wait_ + this->kernel_ + this->prev_idle_;
00111 #elif defined (ACE_HAS_KSTAT)
00112
00113 this->access_kstats (&this->prev_idle_);
00114
00115 this->prev_total_ =
00116 this->user_ + this->wait_ + this->kernel_ + this->prev_idle_;
00117 #endif
00118 }
00119
00120 #if defined (linux)
00121 void
00122 CPU_Load_Monitor::access_proc_stat (unsigned long *which_idle)
00123 {
00124 this->file_ptr_ = ACE_OS::fopen (ACE_TEXT ("/proc/stat"),
00125 ACE_TEXT ("r"));
00126
00127 if (this->file_ptr_ == 0)
00128 {
00129 ACE_ERROR ((LM_ERROR,
00130 ACE_TEXT ("CPU load - opening /proc/stat failed\n")));
00131 return;
00132 }
00133
00134 char *item = 0;
00135 char *arg = 0;
00136
00137 while ((ACE_OS::fgets (buf_, sizeof (buf_), file_ptr_)) != 0)
00138 {
00139 item = ACE_OS::strtok (this->buf_, " \t\n");
00140 arg = ACE_OS::strtok (0, "\n");
00141
00142 if (item == 0 || arg == 0)
00143 {
00144 continue;
00145 }
00146
00147 if (ACE_OS::strcmp (item, "cpu") == 0)
00148 {
00149 sscanf (arg,
00150 "%lu %lu %lu %lu",
00151 &this->user_,
00152 &this->wait_,
00153 &this->kernel_,
00154 which_idle);
00155 break;
00156 }
00157 }
00158
00159 ACE_OS::fclose (this->file_ptr_);
00160 }
00161 #endif
00162
00163 #if defined (ACE_HAS_KSTAT)
00164 void
00165 CPU_Load_Monitor::access_kstats (unsigned long *which_idle)
00166 {
00167 this->kstats_ = kstat_open ();
00168
00169 if (this->kstats_ == 0)
00170 {
00171 ACE_ERROR ((LM_ERROR,
00172 ACE_TEXT ("opening kstats file failed\n")));
00173 return;
00174 }
00175
00176 this->kstat_id_ = this->kstats_->kc_chain_id;
00177
00178 while (true)
00179 {
00180 this->kernel_ = 0UL;
00181 this->wait_ = 0UL;
00182 this->user_ = 0UL;
00183 (*which_idle) = 0UL;
00184
00185
00186
00187 for (this->kstat_ = this->kstats_->kc_chain;
00188 this->kstat_ != 0;
00189 this->kstat_ = this->kstat_->ks_next)
00190 {
00191 int result = ACE_OS::strncmp (this->kstat_->ks_name,
00192 "cpu_stat",
00193 ACE_OS::strlen ("cpu_stat"));
00194
00195 if (result == 0)
00196 {
00197
00198
00199
00200
00201
00202 kid_t kstat_id = kstat_read (this->kstats_, this->kstat_, 0);
00203
00204 if (kstat_id != this->kstat_id_)
00205 {
00206 break;
00207 }
00208
00209 cpu_stat_t &kstat_cpu =
00210 *((cpu_stat_t *) this->kstat_->ks_data);
00211
00212 this->kernel_ += kstat_cpu.cpu_sysinfo.cpu[CPU_KERNEL];
00213 this->wait_ += kstat_cpu.cpu_sysinfo.cpu[CPU_WAIT];
00214 this->user_ += kstat_cpu.cpu_sysinfo.cpu[CPU_USER];
00215 (*which_idle) += kstat_cpu.cpu_sysinfo.cpu[CPU_IDLE];
00216 }
00217 }
00218
00219 if (this->kstat_ != 0)
00220 {
00221
00222
00223 this->kstat_id_ = kstat_chain_update (this->kstats_);
00224
00225 if (! this->kstat_id_ > 0)
00226 {
00227 ACE_ERROR ((LM_ERROR,
00228 ACE_TEXT ("kstat chain update ")
00229 ACE_TEXT ("returned null id\n")));
00230 return;
00231 }
00232 }
00233 else
00234 {
00235
00236 break;
00237 }
00238 }
00239
00240 int status = kstat_close (this->kstats_);
00241
00242 if (status != 0)
00243 {
00244 ACE_ERROR ((LM_ERROR,
00245 ACE_TEXT ("closing kstats file failed\n")));
00246 }
00247 }
00248 #endif
00249 }
00250 }
00251
00252 ACE_END_VERSIONED_NAMESPACE_DECL
00253
00254 #endif