loadavg.c
上传用户:zibowangxu
上传日期:2007-01-04
资源大小:331k
文件大小:12k
源码类别:

Ftp客户端

开发平台:

Unix_Linux

  1. /****************************************************************************    
  2.   Copyright (c) 1999 WU-FTPD Development Group.  
  3.   All rights reserved.
  4.   
  5.   Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 
  6.     The Regents of the University of California.
  7.   Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. 
  8.   Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. 
  9.   Portions Copyright (c) 1989 Massachusetts Institute of Technology. 
  10.   Portions Copyright (c) 1998 Sendmail, Inc. 
  11.   Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P.  Allman. 
  12.   Portions Copyright (c) 1997 by Stan Barber. 
  13.   Portions Copyright (c) 1997 by Kent Landfield. 
  14.   Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 
  15.     Free Software Foundation, Inc.   
  16.   
  17.   Use and distribution of this software and its source code are governed  
  18.   by the terms and conditions of the WU-FTPD Software License ("LICENSE"). 
  19.   
  20.   If you did not receive a copy of the license, it may be obtained online 
  21.   at http://www.wu-ftpd.org/license.html. 
  22.   
  23.   $Id: loadavg.c,v 1.4 1999/08/24 23:41:39 wuftpd Exp $ 
  24.   
  25. ****************************************************************************/
  26. #include "loadavg.h"
  27. /*
  28.    **  GETLA -- get the current load average
  29.    **
  30.    **      This code stolen from la.c.
  31.    **
  32.    **      Parameters:
  33.    **              none.
  34.    **
  35.    **      Returns:
  36.    **              The current load average as an integer.
  37.    **
  38.    **      Side Effects:
  39.    **              none.
  40.  */
  41. /* try to guess what style of load average we have */
  42. #define LA_ZERO         1 /* always return load average as zero */
  43. #define LA_INT          2 /* read kmem for avenrun; interpret as long */
  44. #define LA_FLOAT        3 /* read kmem for avenrun; interpret as float */
  45. #define LA_SUBR         4 /* call getloadavg */
  46. #define LA_MACH         5 /* MACH load averages (as on NeXT boxes) */
  47. #define LA_SHORT        6 /* read kmem for avenrun; interpret as short */
  48. #define LA_PROCSTR      7 /* read string ("1.17") from /proc/loadavg */
  49. #define LA_READKSYM     8 /* SVR4: use MIOC_READKSYM ioctl call */
  50. #define LA_DGUX         9 /* special DGUX implementation */
  51. #define LA_HPUX         10 /* special HPUX implementation */
  52. #define LA_IRIX6        11 /* special IRIX 6.2 implementation */
  53. #define LA_KSTAT        12 /* special Solaris kstat(3k) implementation */
  54. #define LA_DEVSHORT     13 /* read short from a device */
  55. #define LA_ALPHAOSF     14 /* Digital UNIX (OSF/1 on Alpha) table() call */
  56. /* do guesses based on general OS type */
  57. #ifndef LA_TYPE
  58. #define LA_TYPE        LA_ZERO
  59. #endif
  60. #ifndef FSHIFT
  61. #if defined(unixpc)
  62. #define FSHIFT        5
  63. #endif
  64. #if defined(__alpha) || defined(IRIX)
  65. #define FSHIFT        10
  66. #endif
  67. #endif
  68. #ifndef FSHIFT
  69. #define FSHIFT         8
  70. #endif
  71. #ifndef FSCALE
  72. #define FSCALE         (1 << FSHIFT)
  73. #endif
  74. #ifndef LA_AVENRUN
  75. #ifdef SYSTEM5
  76. #define LA_AVENRUN    "avenrun"
  77. #else
  78. #define LA_AVENRUN    "_avenrun"
  79. #endif
  80. #endif
  81. /* _PATH_KMEM should be defined in <paths.h> */
  82. #ifndef _PATH_KMEM
  83. #define _PATH_KMEM     "/dev/kmem"
  84. #endif
  85. #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
  86. #include <nlist.h>
  87. /* _PATH_UNIX should be defined in <paths.h> */
  88. #ifndef _PATH_UNIX
  89. #if defined(SYSTEM5)
  90. #define _PATH_UNIX    "/unix"
  91. #else
  92. #define _PATH_UNIX    "/vmunix"
  93. #endif
  94. #endif
  95. #ifdef _AUX_SOURCE
  96. struct nlist Nl[2];
  97. #else
  98. struct nlist Nl[] =
  99. {
  100.     {LA_AVENRUN},
  101.     {0},
  102. };
  103. #endif
  104. #define X_AVENRUN       0
  105. int getla()
  106. {
  107.     static int kmem = -1;
  108. #if LA_TYPE == LA_INT
  109.     long avenrun[3];
  110. #else
  111. #if LA_TYPE == LA_SHORT
  112.     short avenrun[3];
  113. #else
  114.     double avenrun[3];
  115. #endif
  116. #endif
  117.     extern int errno;
  118.     extern off_t lseek();
  119.     if (kmem < 0) {
  120. #ifdef _AUX_SOURCE
  121. strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN);
  122. Nl[1].n_name[0] = '';
  123. #endif
  124. #if defined(_AIX3) || defined(_AIX4)
  125. if (knlist(Nl, 1, sizeof Nl[0]) < 0)
  126. #else
  127. if (nlist(_PATH_UNIX, Nl) < 0)
  128. #endif
  129.     return (-1);
  130. if (Nl[X_AVENRUN].n_value == 0)
  131.     return (-1);
  132. #ifdef NAMELISTMASK
  133. Nl[X_AVENRUN].n_value &= NAMELISTMASK;
  134. #endif
  135. kmem = open(_PATH_KMEM, 0, 0);
  136. if (kmem < 0)
  137.     return (-1);
  138. (void) fcntl(kmem, F_SETFD, 1);
  139.     }
  140.     if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
  141. read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
  142. /* thank you Ian */
  143. return (-1);
  144. #if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
  145.     return ((int) (avenrun[0] + FSCALE / 2) >> FSHIFT);
  146. #else /* LA_TYPE == LA_FLOAT */
  147.     return ((int) (avenrun[0] + 0.5));
  148. #endif
  149. }
  150. #endif /* LA_TYPE == LA_INT or LA_SHORT or LA_FLOAT */
  151. #if LA_TYPE == LA_READKSYM
  152. #include <sys/ksym.h>
  153. getla()
  154. {
  155.     static int kmem = -1;
  156.     long avenrun[3];
  157.     extern int errno;
  158.     struct mioc_rksym mirk;
  159.     if (kmem < 0) {
  160. kmem = open("/dev/kmem", 0, 0);
  161. if (kmem < 0)
  162.     return (-1);
  163. (void) fcntl(kmem, F_SETFD, 1);
  164.     }
  165.     mirk.mirk_symname = LA_AVENRUN;
  166.     mirk.mirk_buf = avenrun;
  167.     mirk.mirk_buflen = sizeof(avenrun);
  168.     if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
  169. return -1;
  170.     return ((int) (avenrun[0] + FSCALE / 2) >> FSHIFT);
  171. }
  172. #endif /* LA_TYPE == LA_READKSYM */
  173. #if LA_TYPE == LA_DGUX
  174. #include <sys/dg_sys_info.h>
  175. int getla()
  176. {
  177.     struct dg_sys_info_load_info load_info;
  178.     dg_sys_info((long *) &load_info,
  179. DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
  180.     return ((int) (load_info.one_minute + 0.5));
  181. }
  182. #endif /* LA_TYPE == LA_DGUX */
  183. #if LA_TYPE == LA_HPUX
  184. /* forward declarations to keep gcc from complaining */
  185. struct pst_dynamic;
  186. struct pst_status;
  187. struct pst_static;
  188. struct pst_vminfo;
  189. struct pst_diskinfo;
  190. struct pst_processor;
  191. struct pst_lv;
  192. struct pst_swapinfo;
  193. #include <sys/param.h>
  194. #include <sys/pstat.h>
  195. int getla()
  196. {
  197.     struct pst_dynamic pstd;
  198.     if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
  199.              (size_t) 1, 0) == -1)
  200.             return 0;
  201.     return (int) (pstd.psd_avg_1_min + 0.5);
  202. }
  203. #endif /* LA_TYPE == LA_HPUX */
  204. #if LA_TYPE == LA_SUBR
  205. int getla()
  206. {
  207.     double avenrun[3];
  208.     if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
  209. return (-1);
  210.     return ((int) (avenrun[0] + 0.5));
  211. }
  212. #endif /* LA_TYPE == LA_SUBR */
  213. #if LA_TYPE == LA_MACH
  214. /*
  215.    **  This has been tested on NEXTSTEP release 2.1/3.X.
  216.  */
  217. #if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
  218. #include <mach/mach.h>
  219. #else
  220. #include <mach.h>
  221. #endif
  222. int getla()
  223. {
  224.     processor_set_t default_set;
  225.     kern_return_t error;
  226.     unsigned int info_count;
  227.     struct processor_set_basic_info info;
  228.     host_t host;
  229.     error = processor_set_default(host_self(), &default_set);
  230.     if (error != KERN_SUCCESS)
  231. return -1;
  232.     info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
  233.     if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
  234.    &host, (processor_set_info_t) & info,
  235.    &info_count) != KERN_SUCCESS)
  236. return -1;
  237.     return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
  238. }
  239. #endif /* LA_TYPE == LA_MACH */
  240. #if LA_TYPE == LA_PROCSTR
  241. /*
  242.    **  Read /proc/loadavg for the load average.  This is assumed to be
  243.    **  in a format like "0.15 0.12 0.06".
  244.    **
  245.    **      Initially intended for Linux.  This has been in the kernel
  246.    **      since at least 0.99.15.
  247.  */
  248. #include <stdio.h>
  249. #ifndef _PATH_LOADAVG
  250. #define _PATH_LOADAVG "/proc/loadavg"
  251. #endif
  252. int getla()
  253. {
  254.     double avenrun;
  255.     register int result;
  256.     FILE *fp;
  257.     fp = fopen(_PATH_LOADAVG, "r");
  258.     if (fp == NULL)
  259. return -1;
  260.     result = fscanf(fp, "%lf", &avenrun);
  261.     fclose(fp);
  262.     if (result != 1)
  263. return -1;
  264.     return ((int) (avenrun + 0.5));
  265. }
  266. #endif /* LA_TYPE == LA_PROCSTR */
  267. #if LA_TYPE == LA_IRIX6
  268. #include <sys/sysmp.h>
  269. int getla(void)
  270. {
  271.     static int kmem = -1;
  272.     int avenrun[3];
  273.     if (kmem < 0) {
  274. kmem = open(_PATH_KMEM, 0, 0);
  275. if (kmem < 0)
  276.     return -1;
  277. (void) fcntl(kmem, F_SETFD, 1);
  278.     }
  279.     if (lseek(kmem, (sysmp(MP_KERNADDR, MPKA_AVENRUN) & 0x7fffffff), SEEK_SET) == -1 ||
  280. read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
  281. return -1;
  282.     return ((int) (avenrun[0] + FSCALE / 2) >> FSHIFT);
  283. }
  284. #endif
  285. #if LA_TYPE == LA_KSTAT
  286. #include <kstat.h>
  287. int getla()
  288. {
  289.     static kstat_ctl_t *kc = NULL;
  290.     static kstat_t *ksp = NULL;
  291.     kstat_named_t *ksn;
  292.     int la;
  293.     if (kc == NULL) /* if not initialized before */
  294. kc = kstat_open();
  295.     if (kc == NULL)
  296. return -1;
  297.     if (ksp == NULL)
  298. ksp = kstat_lookup(kc, "unix", 0, "system_misc");
  299.     if (ksp == NULL)
  300. return -1;
  301.     if (kstat_read(kc, ksp, NULL) < 0)
  302. return -1;
  303.     ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
  304.     la = ((double) ksn->value.ul + FSCALE / 2) / FSCALE;
  305.     /* kstat_close(kc); /o do not close for fast access */
  306.     return la;
  307. }
  308. #endif /* LA_TYPE == LA_KSTAT */
  309. #if LA_TYPE == LA_DEVSHORT
  310. /*
  311.    **  Read /dev/table/avenrun for the load average.  This should contain
  312.    **  three shorts for the 1, 5, and 15 minute loads.  We only read the
  313.    **  first, since that's all we care about.
  314.    **
  315.    **      Intended for SCO OpenServer 5.
  316.  */
  317. #ifndef _PATH_AVENRUN
  318. #define _PATH_AVENRUN "/dev/table/avenrun"
  319. #endif
  320. int getla()
  321. {
  322.     static int afd = -1;
  323.     short avenrun;
  324.     int loadav;
  325.     int r;
  326.     errno = EBADF;
  327.     if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1) {
  328. if (errno != EBADF)
  329.     return -1;
  330. afd = open(_PATH_AVENRUN, O_RDONLY | O_SYNC);
  331. if (afd < 0) {
  332.     sm_syslog(LOG_ERR, NOQID,
  333.       "can't open %s: %m",
  334.       _PATH_AVENRUN);
  335.     return -1;
  336. }
  337.     }
  338.     r = read(afd, &avenrun, sizeof avenrun);
  339.     loadav = (int) (avenrun + FSCALE / 2) >> FSHIFT;
  340.     return loadav;
  341. }
  342. #endif /* LA_TYPE == LA_DEVSHORT */
  343. #if LA_TYPE == LA_ALPHAOSF
  344. struct rtentry;
  345. struct mbuf;
  346. #include <sys/table.h>
  347. int getla()
  348. {
  349.     int ave = 0;
  350.     struct tbl_loadavg tab;
  351.     if (table (TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1)
  352. return (-1);
  353.     if (tab.tl_lscale)
  354. ave = (tab.tl_avenrun.l[0] + (tab.tl_lscale / 2)) / tab.tl_lscale;
  355.     else
  356. ave = (int) (tab.tl_avenrun.d[0] + 0.5);
  357.     return ave;
  358. }
  359. #endif
  360. #if LA_TYPE == LA_ZERO
  361. int getla()
  362. {
  363.     return (0);
  364. }
  365. #endif /* LA_TYPE == LA_ZERO */
  366. /*
  367.  * Copyright 1989 Massachusetts Institute of Technology
  368.  *
  369.  * Permission to use, copy, modify, distribute, and sell this software and its
  370.  * documentation for any purpose is hereby granted without fee, provided that
  371.  * the above copyright notice appear in all copies and that both that
  372.  * copyright notice and this permission notice appear in supporting
  373.  * documentation, and that the name of M.I.T. not be used in advertising or
  374.  * publicity pertaining to distribution of the software without specific,
  375.  * written prior permission.  M.I.T. makes no representations about the
  376.  * suitability of this software for any purpose.  It is provided "as is"
  377.  * without express or implied warranty.
  378.  *
  379.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  380.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  381.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  382.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  383.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  384.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  385.  *
  386.  * Authors:  Many and varied...
  387.  */
  388. /* Non Apollo stuff removed by Don Lewis 11/15/93 */
  389. #ifdef apollo
  390. #undef volatile
  391. #include <apollo/base.h>
  392. /* ARGSUSED */
  393. int getloadavg(call_data)
  394.      caddr_t call_data; /* pointer to (double) return value */
  395. {
  396.     double *avenrun = (double *) call_data;
  397.     int i;
  398.     status_$t st;
  399.     long loadav[3];
  400.     proc1_$get_loadav(loadav, &st);
  401.     *avenrun = loadav[0] / (double) (1 << 16);
  402.     return (0);
  403. }
  404. #endif /* apollo */