casa
$Rev:20696$
|
00001 //# HostInfo_solaris.h: Solaris specific memory, swap, and CPU code. 00002 //# $Id: HostInfoSolaris.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $ 00003 00004 /* 00005 ** This is a greatly MODIFIED version of a "top" machine dependent file. 00006 ** The only resemblance it bears to the original is with respect to the 00007 ** mechanics of finding various system details. The copyright details 00008 ** follow. 00009 ** 00010 ** --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- 00011 ** 00012 ** Top users/processes display for Unix 00013 ** Version 3 00014 ** 00015 ** This program may be freely redistributed, 00016 ** but this entire comment MUST remain intact. 00017 ** 00018 ** Copyright (c) 1984, 1989, William LeFebvre, Rice University 00019 ** Copyright (c) 1989 - 1994, William LeFebvre, Northwestern University 00020 ** Copyright (c) 1994, 1995, William LeFebvre, Argonne National Laboratory 00021 ** Copyright (c) 1996, William LeFebvre, Group sys Consulting 00022 ** Copyright (c) 2002, Associated Universities Inc. 00023 */ 00024 00025 #ifndef CASA_HOSTINFOSOLARIS_H 00026 #define CASA_HOSTINFOSOLARIS_H 00027 00028 # if defined(HOSTINFO_DO_IMPLEMENT) 00029 00030 /* 00031 * 00032 * LIBS: -lkstat 00033 * 00034 * AUTHOR: Darrell Schiebel <drs@nrao.edu> 00035 * 00036 * ORIGINAL AUTHORS: Torsten Kasch <torsten@techfak.uni-bielefeld.de> 00037 * Robert Boucher <boucher@sofkin.ca> 00038 * ORIGINAL CONTRIBUTORS: Marc Cohen <marc@aai.com> 00039 * Charles Hedrick <hedrick@geneva.rutgers.edu> 00040 * William L. Jones <jones@chpc> 00041 * Petri Kutvonen <kutvonen@cs.helsinki.fi> 00042 * Casper Dik <casper.dik@sun.com> 00043 * Tim Pugh <tpugh@oce.orst.edu> 00044 */ 00045 00046 #include <stdio.h> 00047 #include <unistd.h> 00048 #include <stdlib.h> 00049 #include <string.h> 00050 #include <kvm.h> 00051 #include <sys/types.h> 00052 #include <sys/sysinfo.h> 00053 #include <sys/swap.h> 00054 00055 #include <kstat.h> 00056 00057 namespace casa { //# NAMESPACE CASA - BEGIN 00058 00059 // <summary> 00060 // HostInfo for Solaris machines. 00061 // </summary> 00062 00063 // <use visibility=local> 00064 00065 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos=""> 00066 // </reviewed> 00067 00068 // <prerequisite> 00069 // <li> <linkto class=HostInfo>HostInfo</linkto> 00070 // </prerequisite> 00071 00072 // <synopsis> 00073 // This file provides the Solaris specific functions for HostInfo. 00074 // It is selectively included by HostInfo.cc. 00075 // </synopsis> 00076 // 00077 // <group name="HostInfo"> 00078 00079 /* 00080 * Some kstats are fixed at 32 bits, these will be specified as ui32; some 00081 * are "natural" size (32 bit on 32 bit Solaris, 64 on 64 bit Solaris 00082 * we'll make those unsigned long) 00083 * Older Solaris doesn't define KSTAT_DATA_UINT32, those are always 32 bit. 00084 */ 00085 # ifndef KSTAT_DATA_UINT32 00086 # define ui32 ul 00087 # endif 00088 00089 #ifdef SC_AINFO 00090 #undef USE_ANONINFO /* Use swapctl() instead */ 00091 #endif 00092 00093 #define NO_NPROC 00094 00095 /* pagetok function is really a pointer to an appropriate function */ 00096 #define pagetok(size) ((*p_pagetok)(size)) 00097 00098 #ifndef USE_ANONINFO 00099 static void get_swapinfo(int *total, int *fr); 00100 #endif 00101 00102 class HostMachineInfo { 00103 friend class HostInfo; 00104 00105 void kupdate( ); 00106 HostMachineInfo( ); 00107 ~HostMachineInfo( ); 00108 void update_info( ); 00109 00110 static int pageshift; 00111 int (*p_pagetok) (int); 00112 00113 static inline int pagetok_none(int size) { return(size); } 00114 static inline int pagetok_left(int size) { return(size << pageshift); } 00115 static inline int pagetok_right(int size) { return(size >> pageshift); } 00116 00117 int valid; 00118 kstat_ctl_t *kc; 00119 00120 int cpus; 00121 00122 ssize_t memory_total; 00123 ssize_t memory_used; 00124 ssize_t memory_free; 00125 00126 ssize_t swap_total; 00127 ssize_t swap_used; 00128 ssize_t swap_free; 00129 }; 00130 00131 // </group> 00132 00133 00134 int HostMachineInfo::pageshift = 0; 00135 00136 HostMachineInfo::~HostMachineInfo( ) { if ( kc ) kstat_close(kc); } 00137 00138 HostMachineInfo::HostMachineInfo( ) : valid(1), kc(NULL) 00139 { 00140 int i; 00141 00142 /* calculate pageshift value */ 00143 i = sysconf(_SC_PAGESIZE); 00144 pageshift = 0; 00145 while ((i >>= 1) > 0) pageshift++; 00146 00147 /* calculate an amount to shift to K values */ 00148 /* remember that log base 2 of 1024 is 10 (i.e.: 2^10 = 1024) */ 00149 pageshift -= 10; 00150 00151 /* now determine which pageshift function is appropriate for the 00152 result (have to because x << y is undefined for y < 0) */ 00153 if (pageshift > 0) 00154 { 00155 /* this is the most likely */ 00156 p_pagetok = pagetok_left; 00157 } 00158 else if (pageshift == 0) 00159 { 00160 p_pagetok = pagetok_none; 00161 } 00162 else 00163 { 00164 p_pagetok = pagetok_right; 00165 pageshift = -pageshift; 00166 } 00167 00168 long maxmem = sysconf(_SC_PHYS_PAGES); 00169 memory_total = pagetok (maxmem); 00170 00171 /* use kstat to update all processor information */ 00172 kupdate( ); 00173 00174 kstat_t *ks = kstat_lookup(kc, "unix", 0, "system_misc"); 00175 if (kstat_read(kc, ks, 0) == -1) { 00176 perror("kstat_read"); 00177 valid = 0; 00178 } 00179 kstat_named_t *kn = (kstat_named_t*) kstat_data_lookup(ks, "ncpus"); 00180 cpus = kn->value.ui32; 00181 } 00182 00183 void HostMachineInfo::kupdate( ) 00184 { 00185 kid_t nkcid; 00186 int i; 00187 static kid_t kcid = 0; 00188 00189 /* 00190 * 0. kstat_open 00191 */ 00192 00193 if (!kc) 00194 { 00195 kc = kstat_open(); 00196 if (!kc) 00197 { 00198 perror("kstat_open "); 00199 valid = 0; 00200 } 00201 kcid = kc->kc_chain_id; 00202 } 00203 00204 /* keep doing it until no more changes */ 00205 kcid_changed: 00206 00207 /* 00208 * 1. kstat_chain_update 00209 */ 00210 nkcid = kstat_chain_update(kc); 00211 if (nkcid) 00212 { 00213 /* UPDKCID will abort if nkcid is -1, so no need to check */ 00214 kcid = nkcid; 00215 } 00216 if (nkcid == -1) { 00217 perror("kstat_read "); 00218 valid = 0; 00219 } 00220 if (nkcid != 0) 00221 goto kcid_changed; 00222 } 00223 00224 00225 void HostMachineInfo::update_info( ) 00226 { 00227 static long freemem; 00228 static int swaptotal; 00229 static int swapfree; 00230 kstat_t *ks; 00231 kstat_named_t *kn; 00232 00233 ks = kstat_lookup(kc, "unix", 0, "system_pages"); 00234 if (kstat_read(kc, ks, 0) == -1) { 00235 perror("kstat_read"); 00236 valid = 0; 00237 } 00238 kn = (kstat_named_t*) kstat_data_lookup(ks, "freemem"); 00239 if (kn) 00240 freemem = kn->value.ul; 00241 00242 memory_free = pagetok (freemem); 00243 memory_used = memory_total - memory_free; 00244 00245 get_swapinfo(&swaptotal, &swapfree); 00246 swap_total = pagetok(swaptotal); 00247 swap_used = pagetok(swaptotal - swapfree); 00248 swap_free = pagetok(swapfree); 00249 } 00250 00251 #ifndef USE_ANONINFO 00252 void get_swapinfo(int *total, int *fr) 00253 00254 { 00255 #ifdef SC_AINFO 00256 struct anoninfo anon; 00257 00258 if (swapctl(SC_AINFO, &anon) == -1) { 00259 *total = *fr = 0; 00260 return; 00261 } 00262 *total = anon.ani_max; 00263 *fr = anon.ani_max - anon.ani_resv; 00264 #else 00265 int cnt, i; 00266 int t, f; 00267 struct swaptable *swt; 00268 struct swapent *ste; 00269 static char path[256]; 00270 00271 /* get total number of swap entries */ 00272 cnt = swapctl(SC_GETNSWP, 0); 00273 00274 /* allocate enough space to hold count + n swapents */ 00275 swt = (struct swaptable *)malloc(sizeof(int) + 00276 cnt * sizeof(struct swapent)); 00277 if (swt == NULL) 00278 { 00279 *total = 0; 00280 *fr = 0; 00281 return; 00282 } 00283 swt->swt_n = cnt; 00284 00285 /* fill in ste_path pointers: we don't care about the paths, so we point 00286 them all to the same buffer */ 00287 ste = &(swt->swt_ent[0]); 00288 i = cnt; 00289 while (--i >= 0) 00290 { 00291 ste++->ste_path = path; 00292 } 00293 00294 /* grab all swap info */ 00295 swapctl(SC_LIST, swt); 00296 00297 /* walk thru the structs and sum up the fields */ 00298 t = f = 0; 00299 ste = &(swt->swt_ent[0]); 00300 i = cnt; 00301 while (--i >= 0) 00302 { 00303 /* dont count slots being deleted */ 00304 if (!(ste->ste_flags & ST_INDEL) && 00305 !(ste->ste_flags & ST_DOINGDEL)) 00306 { 00307 t += ste->ste_pages; 00308 f += ste->ste_free; 00309 } 00310 ste++; 00311 } 00312 00313 /* fill in the results */ 00314 *total = t; 00315 *fr = f; 00316 free(swt); 00317 #endif /* SC_AINFO */ 00318 } 00319 #endif /* USE_ANONINFO */ 00320 00321 00322 } //# NAMESPACE CASA - END 00323 00324 # endif 00325 #endif