aboutsummaryrefslogtreecommitdiff
path: root/src/netcpu_sysctl.c
blob: ed7035a8871a39ccbb383dfccdaecce626d8feef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
char   netcpu_sysctl_id[]="\
@(#)netcpu_sysctl.c  Version 2.6.0";

#if HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdio.h>
#include <unistd.h>

#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
# if HAVE_STDINT_H
#  include <stdint.h>
# endif
#endif

#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#if HAVE_LIMITS_H
# include <limits.h>
# ifndef LONG_LONG_MAX
#  define LONG_LONG_MAX LLONG_MAX
# endif /* LONG_LONG_MAX */
#endif

#ifdef __NetBSD__
#define	CP_TIME_TYPE	uint64_t
#else
#define	CP_TIME_TYPE	long
#endif

#include <errno.h>

/* need to have some sort of check for sys/sysctl.h versus sysctl.h */
#include <sys/sysctl.h>


/* this has been liberally cut and pasted from <sys/resource.h> on
   FreeBSD. in general, this would be a bad idea, but I don't want to
   have to do a _KERNEL define to get these and that is what
   sys/resource.h seems to want. raj 2002-03-03 */
#define CP_USER         0
#define CP_NICE         1
#define CP_SYS          2
#define CP_INTR         3
#define CP_IDLE         4
#define CPUSTATES       5


#include "netsh.h"
#include "netlib.h"

static CP_TIME_TYPE lib_start_count[CPUSTATES];
static CP_TIME_TYPE lib_end_count[CPUSTATES];

void
cpu_util_init(void)
{
  return;
}

void
cpu_util_terminate(void)
{
  return;
}

int
get_cpu_method(void)
{
  return SYSCTL;
}

static void
get_cpu_time(CP_TIME_TYPE *cpu_time)
{
  size_t cpu_time_len = CPUSTATES * sizeof (cpu_time[0]);

  if (sysctlbyname("kern.cp_time", cpu_time, &cpu_time_len, NULL, 0) == -1) {
      fprintf (stderr, "Cannot get CPU time!\n");
      exit (1);
  }
}

/* calibrate_sysctl  - perform the idle rate calculation using the
   sysctl call - typically on BSD */

float
calibrate_idle_rate(int iterations, int interval)
{
  return sysconf (_SC_CLK_TCK);
}

float
calc_cpu_util_internal(float elapsed_time)
{
  CP_TIME_TYPE sum_idle, sum_busy;
  int i;

  memset(&lib_local_cpu_stats, 0, sizeof(lib_local_cpu_stats));

  for (sum_busy = 0, i = 0; i < CPUSTATES; i++) {
    if (i != CP_IDLE)
      sum_busy += lib_end_count[i] - lib_start_count[i];
  }

  sum_idle = lib_end_count[CP_IDLE] - lib_start_count[CP_IDLE];
  lib_local_cpu_stats.cpu_util = (float)sum_busy / (float)(sum_busy + sum_idle);
  lib_local_cpu_stats.cpu_util *= 100.0;

  return lib_local_cpu_stats.cpu_util;

}
void
cpu_start_internal(void)
{
  get_cpu_time(lib_start_count);
}

void
cpu_stop_internal(void)
{
  get_cpu_time(lib_end_count);
}