102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectchar   netcpu_kstat_id[]="\
202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project@(#)netcpu_kstat.c  Version 2.4.0";
302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if HAVE_CONFIG_H
502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# include <config.h>
602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <stdio.h>
902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
1002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if HAVE_INTTYPES_H
1102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# include <inttypes.h>
1202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#else
1302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# if HAVE_STDINT_H
1402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#  include <stdint.h>
1502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# endif
1602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
1702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
1802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if HAVE_UNISTD_H
1902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# include <unistd.h>
2002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
2102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if HAVE_STRINGS_H
2202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# include <strings.h>
2302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
2402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#if STDC_HEADERS
2502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# include <stdlib.h>
2602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# include <stddef.h>
2702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#else
2802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# if HAVE_STDLIB_H
2902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#  include <stdlib.h>
3002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project# endif
3102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
3202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
3302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <kstat.h>
3402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <sys/sysinfo.h>
3502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
3602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "netsh.h"
3702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "netlib.h"
3802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
3902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project/* the lib_start_count and lib_end_count arrays hold the starting
4002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   and ending values of whatever is counting when the system is
4102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   idle. The rate at which this increments during a test is compared
4202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   with a previous calibrarion to arrive at a CPU utilization
4302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   percentage. raj 2005-01-26 */
4402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic uint64_t  lib_start_count[MAXCPUS];
4502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic uint64_t  lib_end_count[MAXCPUS];
4602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
4702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic  kstat_t *cpu_ks[MAXCPUS]; /* the addresses that kstat will
4802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                                     need to pull the cpu info from
4902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                                     the kstat interface.  at least I
5002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                                     think that is what this is :) raj
5102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                                     8/2000 */
5202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
5302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#define UPDKCID(nk,ok) \
5402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectif (nk == -1) { \
5502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  perror("kstat_read "); \
5602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  exit(1); \
5702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project} \
5802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectif (nk != ok)\
5902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  goto kcid_changed;
6002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
6102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic kstat_ctl_t *kc = NULL;
6202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic kid_t kcid = 0;
6302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
6402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project/* do the initial open of the kstat interface, get the chain id's all
6502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   straightened-out and set-up the addresses for get_kstat_idle to do
6602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   its thing.  liberally borrowed from the sources to TOP. raj 8/2000 */
6702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
6802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic int
6902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectopen_kstat()
7002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
7102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  kstat_t *ks;
7202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  kid_t nkcid;
7302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  int i;
7402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  int changed = 0;
7502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  static int ncpu = 0;
7602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
7702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  kstat_named_t *kn;
7802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
7902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (debug) {
8002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,"open_kstat: enter\n");
8102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fflush(where);
8202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
8302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
8402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /*
8502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   * 0. kstat_open
8602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   */
8702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
8802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (!kc)
8902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    {
9002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      kc = kstat_open();
9102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      if (!kc)
9202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        {
9302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project          perror("kstat_open ");
9402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project          exit(1);
9502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        }
9602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      changed = 1;
9702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      kcid = kc->kc_chain_id;
9802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
9902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#ifdef rickwasstupid
10002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  else {
10102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,"open_kstat double open!\n");
10202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fflush(where);
10302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    exit(1);
10402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
10502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#endif
10602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
10702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* keep doing it until no more changes */
10802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kcid_changed:
10902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
11002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (debug) {
11102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,"passing kcid_changed\n");
11202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fflush(where);
11302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
11402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
11502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /*
11602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   * 1.  kstat_chain_update
11702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project   */
11802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  nkcid = kstat_chain_update(kc);
11902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (nkcid)
12002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    {
12102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      /* UPDKCID will abort if nkcid is -1, so no need to check */
12202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      changed = 1;
12302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      kcid = nkcid;
12402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
12502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  UPDKCID(nkcid,0);
12602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
12702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (debug) {
12802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,"kstat_lookup for unix/system_misc\n");
12902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fflush(where);
13002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
13102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
13202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  ks = kstat_lookup(kc, "unix", 0, "system_misc");
13302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (kstat_read(kc, ks, 0) == -1) {
13402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    perror("kstat_read");
13502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    exit(1);
13602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
13702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
13802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
13902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (changed) {
14002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
14102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    /*
14202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     * 2. get data addresses
14302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     */
14402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
14502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    ncpu = 0;
14602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
14702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    kn = kstat_data_lookup(ks, "ncpus");
14802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (kn && kn->value.ui32 > lib_num_loc_cpus) {
14902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      fprintf(stderr,"number of CPU's mismatch!");
15002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      exit(1);
15102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
15202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
15302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    for (ks = kc->kc_chain; ks;
15402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project         ks = ks->ks_next)
15502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      {
15602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        if (strncmp(ks->ks_name, "cpu_stat", 8) == 0)
15702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project          {
15802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            nkcid = kstat_read(kc, ks, NULL);
15902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            /* if kcid changed, pointer might be invalid. we'll deal
16002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project               wtih changes at this stage, but will not accept them
16102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project               when we are actually in the middle of reading
16202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project               values. hopefully this is not going to be a big
16302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project               issue. raj 8/2000 */
16402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            UPDKCID(nkcid, kcid);
16502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
16602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if (debug) {
16702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              fprintf(where,"cpu_ks[%d] getting %p\n",ncpu,ks);
16802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              fflush(where);
16902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            }
17002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
17102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            cpu_ks[ncpu] = ks;
17202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            ncpu++;
17302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            if (ncpu > lib_num_loc_cpus)
17402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              {
17502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                /* with the check above, would we ever hit this? */
17602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                fprintf(stderr,
17702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                        "kstat finds too many cpus %d: should be %d\n",
17802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                        ncpu,lib_num_loc_cpus);
17902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                exit(1);
18002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              }
18102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project          }
18202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      }
18302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    /* note that ncpu could be less than ncpus, but that's okay */
18402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    changed = 0;
18502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
18602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
18702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
18802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project/* return the value of the idle tick counter for the specified CPU */
18902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectstatic long
19002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectget_kstat_idle(cpu)
19102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     int cpu;
19202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
19302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  cpu_stat_t cpu_stat;
19402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  kid_t nkcid;
19502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
19602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (debug) {
19702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,
19802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            "get_kstat_idle reading with kc %x and ks %p\n",
19902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            kc,
20002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project            cpu_ks[cpu]);
20102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
20202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
20302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  nkcid = kstat_read(kc, cpu_ks[cpu], &cpu_stat);
20402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* if kcid changed, pointer might be invalid, fail the test */
20502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  UPDKCID(nkcid, kcid);
20602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
20702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return(cpu_stat.cpu_sysinfo.cpu[CPU_IDLE]);
20802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
20902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kcid_changed:
21002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  perror("kcid changed midstream and I cannot deal with that!");
21102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  exit(1);
21202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
21302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
21402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid
21502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectcpu_util_init(void)
21602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
21702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  open_kstat();
21802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return;
21902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
22002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
22102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid
22202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectcpu_util_terminate(void)
22302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
22402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return;
22502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
22602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
22702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectint
22802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectget_cpu_method(void)
22902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
23002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return KSTAT;
23102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
23202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
23302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid
23402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectget_cpu_idle(uint64_t *res)
23502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
23602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
23702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  int i;
23802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
23902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* this open may be redundant */
24002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  open_kstat();
24102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
24202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  for (i = 0; i < lib_num_loc_cpus; i++){
24302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    res[i] = get_kstat_idle(i);
24402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
24502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return;
24602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
24702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
24802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectfloat
24902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectcalibrate_idle_rate(int iterations, int interval)
25002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
25102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
25202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  long
25302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    firstcnt[MAXCPUS],
25402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    secondcnt[MAXCPUS];
25502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
25602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  float
25702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    elapsed,
25802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    temp_rate,
25902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    rate[MAXTIMES],
26002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    local_maxrate;
26102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
26202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  long
26302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    sec,
26402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    usec;
26502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
26602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  int
26702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    i,
26802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    j;
26902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
27002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  struct  timeval time1, time2 ;
27102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  struct  timezone tz;
27202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
27302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (debug) {
27402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,"calling open_kstat from calibrate_kstat\n");
27502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fflush(where);
27602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
27702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
27802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  open_kstat();
27902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
28002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (iterations > MAXTIMES) {
28102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    iterations = MAXTIMES;
28202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
28302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
28402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  local_maxrate = (float)-1.0;
28502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
28602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  for(i = 0; i < iterations; i++) {
28702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    rate[i] = (float)0.0;
28802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    for (j = 0; j < lib_num_loc_cpus; j++) {
28902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      firstcnt[j] = get_kstat_idle(j);
29002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
29102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    gettimeofday (&time1, &tz);
29202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    sleep(interval);
29302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    gettimeofday (&time2, &tz);
29402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
29502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (time2.tv_usec < time1.tv_usec)
29602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      {
29702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        time2.tv_usec += 1000000;
29802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        time2.tv_sec -=1;
29902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      }
30002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    sec = time2.tv_sec - time1.tv_sec;
30102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    usec = time2.tv_usec - time1.tv_usec;
30202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    elapsed = (float)sec + ((float)usec/(float)1000000.0);
30302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
30402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if(debug) {
30502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      fprintf(where, "Calibration for kstat counter run: %d\n",i);
30602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      fprintf(where,"\tsec = %ld usec = %ld\n",sec,usec);
30702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      fprintf(where,"\telapsed time = %g\n",elapsed);
30802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
30902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
31002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    for (j = 0; j < lib_num_loc_cpus; j++) {
31102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      secondcnt[j] = get_kstat_idle(j);
31202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      if(debug) {
31302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        /* I know that there are situations where compilers know about */
31402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        /* long long, but the library functions do not... raj 4/95 */
31502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        fprintf(where,
31602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                "\tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lx\n",
31702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                j,
31802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                firstcnt[j],
31902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                firstcnt[j],
32002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                j,
32102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                secondcnt[j],
32202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project                secondcnt[j]);
32302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      }
32402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      /* we assume that it would wrap no more than once. we also */
32502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      /* assume that the result of subtracting will "fit" raj 4/95 */
32602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      temp_rate = (secondcnt[j] >= firstcnt[j]) ?
32702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        (float)(secondcnt[j] - firstcnt[j])/elapsed :
32802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project          (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed;
32902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      if (temp_rate > rate[i]) rate[i] = temp_rate;
33002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      if(debug) {
33102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        fprintf(where,"\trate[%d] = %g\n",i,rate[i]);
33202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project        fflush(where);
33302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      }
33402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      if (local_maxrate < rate[i]) local_maxrate = rate[i];
33502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
33602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
33702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if(debug) {
33802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fprintf(where,"\tlocal maxrate = %g per sec. \n",local_maxrate);
33902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    fflush(where);
34002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
34102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return local_maxrate;
34202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
34302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
34402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectfloat
34502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectcalc_cpu_util_internal(float elapsed_time)
34602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
34702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  int i;
34802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  float correction_factor;
34902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  float actual_rate;
35002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
35102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  lib_local_cpu_util = (float)0.0;
35202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* It is possible that the library measured a time other than */
35302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* the one that the user want for the cpu utilization */
35402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* calculations - for example, tests that were ended by */
35502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* watchdog timers such as the udp stream test. We let these */
35602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* tests tell up what the elapsed time should be. */
35702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
35802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  if (elapsed_time != 0.0) {
35902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    correction_factor = (float) 1.0 +
36002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      ((lib_elapsed - elapsed_time) / elapsed_time);
36102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
36202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  else {
36302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    correction_factor = (float) 1.0;
36402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
36502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
36602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  for (i = 0; i < lib_num_loc_cpus; i++) {
36702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
36802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    /* it would appear that on some systems, in loopback, nice is
36902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     *very* effective, causing the looper process to stop dead in its
37002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     tracks. if this happens, we need to ensure that the calculation
37102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     does not go south. raj 6/95 and if we run completely out of idle,
37202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     the same thing could in theory happen to the USE_KSTAT path. raj
37302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project     8/2000 */
37402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
37502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (lib_end_count[i] == lib_start_count[i]) {
37602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      lib_end_count[i]++;
37702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
37802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
37902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    actual_rate = (lib_end_count[i] > lib_start_count[i]) ?
38002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      (float)(lib_end_count[i] - lib_start_count[i])/lib_elapsed :
38102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      (float)(lib_end_count[i] - lib_start_count[i] +
38202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project	      MAXLONG)/ lib_elapsed;
38302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    if (debug) {
38402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      fprintf(where,
38502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              "calc_cpu_util: actual_rate on processor %d is %f start %lx end %lx\n",
38602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              i,
38702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              actual_rate,
38802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              lib_start_count[i],
38902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project              lib_end_count[i]);
39002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    }
39102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) /
39202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project      lib_local_maxrate * 100;
39302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project    lib_local_cpu_util += lib_local_per_cpu_util[i];
39402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  }
39502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  /* we want the average across all n processors */
39602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  lib_local_cpu_util /= (float)lib_num_loc_cpus;
39702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
39802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  lib_local_cpu_util *= correction_factor;
39902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return lib_local_cpu_util;
40002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
40102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
40202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
40302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
40402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid
40502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectcpu_start_internal(void)
40602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
40702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  get_cpu_idle(lib_start_count);
40802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  return;
40902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
41002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project
41102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectvoid
41202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectcpu_stop_internal(void)
41302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project{
41402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project  get_cpu_idle(lib_end_count);
41502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project}
416