diff options
Diffstat (limited to 'ACE/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_CPU_Load_Average_Monitor.cpp')
-rw-r--r-- | ACE/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_CPU_Load_Average_Monitor.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/ACE/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_CPU_Load_Average_Monitor.cpp b/ACE/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_CPU_Load_Average_Monitor.cpp new file mode 100644 index 00000000000..96b28757543 --- /dev/null +++ b/ACE/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_CPU_Load_Average_Monitor.cpp @@ -0,0 +1,239 @@ +#include "orbsvcs/LoadBalancing/LB_CPU_Load_Average_Monitor.h" +#include "tao/ORB_Constants.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/os_include/os_netdb.h" +#include "ace/os_include/sys/os_pstat.h" +#include "ace/os_include/sys/os_loadavg.h" +#if defined(__NetBSD__) || defined (__APPLE__) +#include <sys/sysctl.h> +#endif + +ACE_RCSID (LoadBalancing, + LB_CPU_Load_Average_Monitor, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_LB_CPU_Load_Average_Monitor::TAO_LB_CPU_Load_Average_Monitor ( + const ACE_TCHAR * location_id, + const ACE_TCHAR * location_kind) + : location_ (1) +{ + this->location_.length (1); + + if (location_id == 0) + { + char host[MAXHOSTNAMELEN + 1]; + if (ACE_OS::hostname (host, sizeof (host)) != 0) + { + // Couldn't determine hostname. Use the current time + // instead. + CORBA::ULong t = static_cast<CORBA::ULong> (ACE_OS::time ()); + + // A 64 byte buffer is more than enough to contain the + // string representation of a 32 bit unsigned integer. + char buf[64] = { '\0' }; + ACE_OS::sprintf (buf, "%u", t); + + this->location_[0].id = CORBA::string_dup (buf); + this->location_[0].kind = CORBA::string_dup ("Creation Time"); + } + else + { + this->location_[0].id = CORBA::string_dup (host); + this->location_[0].kind = CORBA::string_dup ("Hostname"); + } + } + else + { + this->location_[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(location_id)); + + if (location_kind != 0) + this->location_[0].kind = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(location_kind)); + } +} + +TAO_LB_CPU_Load_Average_Monitor::~TAO_LB_CPU_Load_Average_Monitor (void) +{ +} + +CosLoadBalancing::Location * +TAO_LB_CPU_Load_Average_Monitor::the_location (void) +{ + CosLoadBalancing::Location * location; + ACE_NEW_THROW_EX (location, + CosLoadBalancing::Location (this->location_), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + return location; +} + +CosLoadBalancing::LoadList * +TAO_LB_CPU_Load_Average_Monitor::loads (void) +{ + CORBA::Float load = 0; + + // Obtain the number of processors each time a load is computed. + // The idea is to take into account the processor failures that can + // occur on platforms that continue running with the remaining + // processors. + // + // @@ Is this a realistic scenario? Perhaps we should just cache + // the number of processors and assume that any processor failure + // is a catastrophic one. + +#if 0 + + SYSTEM_INFO sys_info; + ::GetSystemInfo (&sys_info); + + ACE_ASSERT (sys_info.dwNumberOfProcessors > 0); + + load = ::GetLoadAvg () / sys_info.dwNumberOfProcessors; + +#elif defined (linux) || defined (sun) + + // Only bother getting the load average over the last minute. + // + // @todo Make this configurable so that the load average over the + // last 5 and 15 minutes can be used instead. + double loadavg[1]; + +# if defined (linux) \ + && ((defined (__GLIBC__) && defined (__GLIBC_MINOR__) \ + && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \ + || (!defined (_BSD_SOURCE) && !defined (_GNU_SOURCE))) + + // GLibc < 2.2 does not implement getloadavg(). Furthermore, + // getloadavg() is only "visible" if _BSD_SOURCE or _GNU_SOURCE is + // defined. + + // Obtain the load average directly from the `/proc' filesystem. + FILE * s = ACE_OS::fopen ("/proc/loadavg", "r"); + + if (s == 0) + throw CORBA::NO_IMPLEMENT ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + errno), + CORBA::COMPLETED_NO); + + fscanf (s, "%f", &loadavg[0]); + + (void) ACE_OS::fclose (s); + + const int samples = 1; + +# else + +# if defined (ACE_LACKS_GETLOADAVG) + + const int samples = 0; + +# else + + const int samples = ::getloadavg (loadavg, 1); + +# endif /* ACE_LACKS_GETLOADAVG */ + +# endif /* linux + && ((__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) + || (!_BSD_SOURCE && !_GNU_SOURCE)) */ + + if (samples == 1) + { + const long num_processors = ACE_OS::sysconf (_SC_NPROCESSORS_ONLN); + + ACE_ASSERT (num_processors > 0); + + if (num_processors > 0) + load = loadavg[0] / num_processors; + else + throw CORBA::TRANSIENT (); // Correct exception? + } + else + throw CORBA::TRANSIENT (); // Correct exception? + +#elif defined (__NetBSD__) || defined (__APPLE__) + + double loadavg[1]; + + const int samples = ::getloadavg (loadavg, 1); + + if (samples == 1) + { + int mib[2], num_processors; + size_t len; + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + len = sizeof(num_processors); + + sysctl(mib, 2, &num_processors, &len, 0, 0); + + ACE_ASSERT (num_processors > 0); + + if (num_processors > 0) + load = loadavg[0] / num_processors; + else + throw CORBA::TRANSIENT (); // Correct exception? + } + else + throw CORBA::TRANSIENT (); // Correct exception? + +#elif defined (__hpux) + + struct pst_dynamic psd; + + if (::pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1) + { + const long & num_processors = psd.psd_proc_cnt; + + ACE_ASSERT (num_processors > 0); + + if (num_processors > 0) + load = psd.psd_avg_1_min / num_processors; + else + throw CORBA::TRANSIENT (); // Correct exception? + } + else + throw CORBA::TRANSIENT (); // Correct exception? + +#endif + +#if defined (linux) || defined (sun) || defined (__hpux) || defined(__NetBSD__) || defined (__APPLE__) + + CosLoadBalancing::LoadList * tmp = 0; + ACE_NEW_THROW_EX (tmp, + CosLoadBalancing::LoadList (1), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + CosLoadBalancing::LoadList_var load_list = tmp; + + load_list->length (1); + + load_list[0].id = CosLoadBalancing::LoadAverage; + load_list[0].value = load; + + return load_list._retn (); + +#else + + ACE_UNUSED_ARG (load); + throw CORBA::NO_IMPLEMENT (); + +#endif /* linux || sun || __hpux || __NetBSD__ || __APPLE__ */ + +} + +TAO_END_VERSIONED_NAMESPACE_DECL |