⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getloadavg.c

📁 功能强大的ftp服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static processor_set_t default_set;static int getloadavg_initialized;# endif /* NeXT */# ifdef UMAXstatic unsigned int cpus = 0;static unsigned int samples;# endif /* UMAX */# ifdef DGUXstatic struct dg_sys_info_load_info load_info;	/* what-a-mouthful! */# endif /* DGUX */# ifdef LOAD_AVE_TYPE/* File descriptor open to /dev/kmem or VMS load ave driver.  */static int channel;/* Nonzero iff channel is valid.  */static int getloadavg_initialized;/* Offset in kmem to seek to read load average, or 0 means invalid.  */static long offset;#  if !defined(VMS) && !defined(sgi) && !defined(__linux__)static struct nlist nl[2];#  endif /* Not VMS or sgi */#  ifdef SUNOS_5static kvm_t *kd;#  endif /* SUNOS_5 */# endif /* LOAD_AVE_TYPE *//* Put the 1 minute, 5 minute and 15 minute load averages   into the first NELEM elements of LOADAVG.   Return the number written (never more than 3, but may be less than NELEM),   or -1 if an error occurred.  */int getloadavg(double loadavg[], int nelem){    int elem = 0;			/* Return value.  */# ifdef NO_GET_LOAD_AVG#  define LDAV_DONE    /* Set errno to zero to indicate that there was no particular error;     this function just can't work at all on this system.  */    errno = 0;    elem = -1;# endif    # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT)    /* Use libkstat because we don't have to be root.  */#  define LDAV_DONE    kstat_ctl_t *kc;    kstat_t *ksp;    kstat_named_t *kn;        if ((kc = kstat_open()) == 0) {        return -1;    }    if ((ksp = kstat_lookup(kc, "unix", 0, "system_misc")) == 0) {        out_kstat:        kstat_close(kc);        return -1;    }    if (kstat_read(kc, ksp, 0) == -1) {        goto out_kstat;    }    if ((kn = kstat_data_lookup(ksp, "avenrun_1min")) == 0) {        /* Return -1 if no load average information is available.  */        nelem = 0;        elem = -1;    } else if (nelem >= 1) {        loadavg[elem++] = (double) kn->value.ul / FSCALE;    }    if (nelem >= 2) {        kn = kstat_data_lookup(ksp, "avenrun_5min");        if (kn != 0) {            loadavg[elem++] = (double) kn->value.ul / FSCALE;            if (nelem >= 3) {                kn = kstat_data_lookup(ksp, "avenrun_15min");                if (kn != 0) {                    loadavg[elem++] = (double) kn->value.ul / FSCALE;                }	    }	}    }    kstat_close(kc);# endif /* HAVE_LIBKSTAT */# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)    /* Use pstat_getdynamic() because we don't have to be root.  */#  define LDAV_DONE#  undef LOAD_AVE_TYPE    struct pst_dynamic dyn_info;        if (pstat_getdynamic(&dyn_info, sizeof dyn_info, 0, 0) < 0) {        return -1;    }    if (nelem > 0) {        loadavg[elem++] = dyn_info.psd_avg_1_min;    }    if (nelem > 1) {        loadavg[elem++] = dyn_info.psd_avg_5_min;    }    if (nelem > 2) {        loadavg[elem++] = dyn_info.psd_avg_15_min;    }# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */# if !defined (LDAV_DONE) && defined (__linux__)#  define LDAV_DONE#  undef LOAD_AVE_TYPE    #  ifndef LINUX_LDAV_FILE#   define LINUX_LDAV_FILE "/proc/loadavg"#  endif        char ldavgbuf[40];    double load_ave[3];    int fd;    ssize_t count;    if ((fd = open(LINUX_LDAV_FILE, O_RDONLY | O_NOFOLLOW)) == -1) {        return -1;    }    count = read(fd, ldavgbuf, (size_t) 40U);    (void) close(fd);    if (count <= (ssize_t) 0) {        return -1;    }    count = sscanf(ldavgbuf, "%lf %lf %lf",                   &load_ave[0], &load_ave[1], &load_ave[2]);    if (count < 1) {        return -1;    }    for (elem = 0; elem < nelem && elem < count; elem++) {        loadavg[elem] = load_ave[elem];    }        return elem;# endif /* __linux__ */# if !defined (LDAV_DONE) && defined (__NetBSD__)#  define LDAV_DONE#  undef LOAD_AVE_TYPE#  ifndef NETBSD_LDAV_FILE#   define NETBSD_LDAV_FILE "/kern/loadavg"#  endif    FILE *fp;        unsigned long int load_ave[3], scale;    int count;    if ((fp = fopen(NETBSD_LDAV_FILE, "r")) == NULL) {        return -1;    }    count = fscanf(fp, "%lu %lu %lu %lu\n",                   &load_ave[0], &load_ave[1], &load_ave[2],                   &scale);    (void) fclose(fp);    if (count != 4) {        return -1;    }    for (elem = 0; elem < nelem; elem++) {        loadavg[elem] = (double) load_ave[elem] / (double) scale;    }        return elem;# endif /* __NetBSD__ */# if !defined (LDAV_DONE) && defined (NeXT)#  define LDAV_DONE    /* The NeXT code was adapted from iscreen 3.2.  */    host_t host;    struct processor_set_basic_info info;    unsigned info_count;    /* We only know how to get the 1-minute average for this system,     so even if the caller asks for more than 1, we only return 1.  */    if (!getloadavg_initialized) {        if (processor_set_default(host_self(), &default_set)             == KERN_SUCCESS) {            getloadavg_initialized = 1;        }    }    if (getloadavg_initialized) {        info_count = PROCESSOR_SET_BASIC_INFO_COUNT;        if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO, &host,                               (processor_set_info_t) &info, &info_count)            != KERN_SUCCESS) {            getloadavg_initialized = 0;        } else {            if (nelem > 0) {                loadavg[elem++] = (double) info.load_average / LOAD_SCALE;            }	}    }    if (!getloadavg_initialized) {        return -1;    }# endif /* NeXT */# if !defined (LDAV_DONE) && defined (UMAX)#  define LDAV_DONE    /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not     have a /dev/kmem.  Information about the workings of the running kernel     can be gathered with inq_stats system calls.     We only know how to get the 1-minute average for this system.  */    struct proc_summary proc_sum_data;    struct stat_descr proc_info;    double load;    register unsigned int i, j;    if (cpus == 0) {        register unsigned int c, i;        struct cpu_config conf;        struct stat_descr desc;                desc.sd_next = 0;        desc.sd_subsys = SUBSYS_CPU;        desc.sd_type = CPUTYPE_CONFIG;        desc.sd_addr = (char *) &conf;        desc.sd_size = sizeof conf;                if (inq_stats(1, &desc)) {            return -1;        }        c = 0;        for (i = 0; i < conf.config_maxclass; ++i) {            struct class_stats stats;            bzero((char *) &stats, sizeof stats);                        desc.sd_type = CPUTYPE_CLASS;            desc.sd_objid = i;            desc.sd_addr = (char *) &stats;            desc.sd_size = sizeof stats;                        if (inq_stats(1, &desc)) {                return -1;            }                        c += stats.class_numcpus;	}        cpus = c;        samples = cpus < 2 ? 3 : (2 * cpus / 3);    }    proc_info.sd_next = 0;    proc_info.sd_subsys = SUBSYS_PROC;    proc_info.sd_type = PROCTYPE_SUMMARY;    proc_info.sd_addr = (char *) &proc_sum_data;    proc_info.sd_size = sizeof (struct proc_summary);    proc_info.sd_sizeused = 0;    if (inq_stats(1, &proc_info) != 0) {        return -1;    }        load = proc_sum_data.ps_nrunnable;    j = 0;    for (i = samples - 1; i > 0; --i) {        load += proc_sum_data.ps_nrun[j];        if (j++ == PS_NRUNSIZE) {            j = 0;        }    }    if (nelem > 0) {        loadavg[elem++] = load / samples / cpus;    }# endif /* UMAX */# if !defined (LDAV_DONE) && defined (DGUX)#  define LDAV_DONE    /* This call can return -1 for an error, but with good args     it's not supposed to fail.  The first argument is for no     apparent reason of type `long int *'.  */        dg_sys_info((long int *) &load_info,                 DG_SYS_INFO_LOAD_INFO_TYPE,                 DG_SYS_INFO_LOAD_VERSION_0);        if (nelem > 0) {        loadavg[elem++] = load_info.one_minute;    }        if (nelem > 1) {        loadavg[elem++] = load_info.five_minute;    }    if (nelem > 2) {        loadavg[elem++] = load_info.fifteen_minute;    }# endif /* DGUX */# if !defined (LDAV_DONE) && defined (apollo)#  define LDAV_DONE    /*      * Apollo code from lisch@mentorg.com (Ray Lischner).     *      * This system call is not documented.  The load average is obtained as     * three long integers, for the load average over the past minute,     * five minutes, and fifteen minutes.  Each value is a scaled integer,     * with 16 bits of integer part and 16 bits of fraction part.     *      * I'm not sure which operating system first supported this system call,     * but I know that SR10.2 supports it.       */        extern void proc1_$get_loadav();    unsigned long load_ave[3];    proc1_$get_loadav(load_ave);    if (nelem > 0) {        loadavg[elem++] = load_ave[0] / 65536.0;    }    if (nelem > 1) {        loadavg[elem++] = load_ave[1] / 65536.0;    }    if (nelem > 2) {        loadavg[elem++] = load_ave[2] / 65536.0;    }# endif /* apollo */# if !defined (LDAV_DONE) && defined (OSF_MIPS)#  define LDAV_DONE    struct tbl_loadavg load_ave;    table(TBL_LOADAVG, 0, &load_ave, 1, sizeof load_ave);    loadavg[elem++] =         (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[0] :         (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));# endif	/* OSF_MIPS */# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))#  define LDAV_DONE  /* A faithful emulation is going to have to be saved for a rainy day.  */    for ( ; elem < nelem; elem++) {        loadavg[elem] = 0.0;    }# endif  /* __MSDOS__ || WINDOWS32 */# if !defined (LDAV_DONE) && defined (OSF_ALPHA)#  define LDAV_DONE    struct tbl_loadavg load_ave;    table(TBL_LOADAVG, 0, &load_ave, 1, sizeof load_ave);    for (elem = 0; elem < nelem; elem++) {        loadavg[elem] =             (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[elem]             : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));    }# endif /* OSF_ALPHA */# if !defined (LDAV_DONE) && defined (VMS)  /* VMS specific code -- read from the Load Ave driver.  */    LOAD_AVE_TYPE load_ave[3];#  ifdef eunice    struct {        int dsc$w_length;        char *dsc$a_pointer;    } descriptor;#  endif    /* Attempt to open the channel.  */#  ifdef eunice    descriptor.dsc$w_length = 18;    descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";#  else    $DESCRIPTOR(descriptor, "LAV0:");#  endif    if (sys$assign(&descriptor, &channel, 0, 0) & 1) {        return -1;    }    /* Read the load average vector.  */    if (!(sys$qiow(0, channel, IO$_READVBLK, 0, 0, 0,                   load_ave, 12, 0, 0, 0, 0) & 1)) {        sys$dassgn(channel);        return -1;    }    sys$dassgn(channel);    # endif /* VMS */# if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS)  /* UNIX-specific code -- read the average from /dev/kmem.  */#  define LDAV_PRIVILEGED		/* This code requires special installation.  */    LOAD_AVE_TYPE load_ave[3];  /* Get the address of LDAV_SYMBOL.  */    if (offset == 0L) {#  ifndef sgi#   ifndef NLIST_STRUCT        strncpy(nl[0].n_name, LDAV_SYMBOL,                 sizeof (nl[0].n_name) - (size_t) 1U);        (nl[0].n_name)[sizeof (nl[0].n_name) - (size_t) 1U] = 0;        *(nl[1].n_name) = 0;#   else /* NLIST_STRUCT */#    ifdef NLIST_NAME_UNION        nl[0].n_un.n_name = LDAV_SYMBOL;        nl[1].n_un.n_name = 0;#    else /* not NLIST_NAME_UNION */        nl[0].n_name = LDAV_SYMBOL;        nl[1].n_name = 0;#    endif /* not NLIST_NAME_UNION */#   endif /* NLIST_STRUCT */        #   ifndef SUNOS_5        if (#    if !(defined (_AIX) && !defined (ps2))            nlist(KERNEL_FILE, nl)#    else  /* _AIX */            knlist(nl, 1, sizeof nl[0])#    endif            >= 0) {  /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */#    ifdef FIXUP_KERNEL_SYMBOL_ADDR	    FIXUP_KERNEL_SYMBOL_ADDR(nl);#    endif	    offset = nl[0].n_value;        }#   endif /* !SUNOS_5 */#  else  /* sgi */        int ldav_off;        ldav_off = sysmp(MP_KERNADDR, MPKA_AVENRUN);        if (ldav_off != -1) {            offset = (long) ldav_off & 0x7fffffff;        }#  endif /* sgi */    }#  ifndef SUNOS_5    if ((channel = open("/dev/kmem", 0)) == -1) {        return -1;    }    /* Set the channel to close on exec, so it does not     litter any child's descriptor table.  */#   ifdef FD_SETFD#    ifndef FD_CLOEXEC#     define FD_CLOEXEC 1#    endif    (void) fcntl(channel, F_SETFD, FD_CLOEXEC);#   endif#  else /* SUNOS_5 */        /* We pass 0 for the kernel, corefile, and swapfile names	 to use the currently running kernel.  */    if ((kd = kvm_open(0, 0, 0, O_RDONLY, 0)) == 0) {        return -1;    }    /* nlist the currently running kernel.  */    kvm_nlist(kd, nl);    offset = nl[0].n_value;#  endif /* SUNOS_5 */    /* No offset => don't read */    if (offset == 0L) {#  ifndef SUNOS_5        (void) close(channel);#  else        kvm_close(kd);#  endif        return -1;    }    /* Try to read the load.  */#  ifndef SUNOS_5        if (lseek(channel, offset, SEEK_SET) == -1L ||            read(channel, (char *) load_ave, sizeof load_ave)	  != sizeof load_ave) {            close(channel);            return -1;	}#  else  /* SUNOS_5 */      if (kvm_read(kd, offset, (char *) load_ave, sizeof load_ave)	  != sizeof load_ave) {          kvm_close(kd);          return -1;      }#  endif /* SUNOS_5 */# endif /* LOAD_AVE_TYPE and not VMS */# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS.  */    if (nelem > 0) {        loadavg[elem++] = LDAV_CVT(load_ave[0]);    }    if (nelem > 1) {        loadavg[elem++] = LDAV_CVT(load_ave[1]);    }    if (nelem > 2) {        loadavg[elem++] = LDAV_CVT(load_ave[2]);    }#  define LDAV_DONE# endif /* !LDAV_DONE && LOAD_AVE_TYPE */# ifdef LDAV_DONE    return elem;# else  /* Set errno to zero to indicate that there was no particular error;     this function just can't work at all on this system.  */    errno = 0;        return -1;# endif}#endif /* ! HAVE_GETLOADAVG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -