1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <libc.h>
5#include "cputime.h"
6
7/*
8 * This returns the frequency of the TBR in cycles per second.
9 */
10static double GetTBRFreq(void) {
11	mach_timebase_info_data_t tinfo;
12	mach_timebase_info(&tinfo);
13
14	double machRatio = (double)tinfo.numer / (double)tinfo.denom;
15	return machRatio;
16}
17
18/*
19 * Return TBR Frequency, getting it lazily once. May not be thread safe.
20 */
21static double TbrFreqLocal = 0.0;		// ration for NANOSECONDS
22static double tbrFreq()
23{
24	if(TbrFreqLocal == 0.0) {
25		TbrFreqLocal = GetTBRFreq();
26		printf("machRatio %e\n", TbrFreqLocal);
27	}
28	return TbrFreqLocal;
29}
30
31// seconds
32double CPUTimeDeltaSec(CPUTime from, CPUTime to)
33{
34	CPUTime delta = to - from;
35	return (double)delta * (tbrFreq() * (double)1e-9);
36}
37
38// milliseconds
39double CPUTimeDeltaMs(CPUTime from, CPUTime to)
40{
41	CPUTime delta = to - from;
42	return (double)delta * (tbrFreq() * (double)1e-6);
43}
44
45// microseconds
46double CPUTimeDeltaUs(CPUTime from, CPUTime to)
47{
48	CPUTime delta = to - from;
49	return (double)delta * (tbrFreq() * (double)1e-3);
50}
51
52/*
53 * Calculate the average of an array of doubles. The lowest and highest values
54 * are discarded if there are more than two samples. Typically used to get an
55 * average of a set of values returned from CPUTimeDelta*().
56 */
57double CPUTimeAvg(
58	const double *array,
59	unsigned arraySize)
60{
61	double sum = 0;
62	double lowest = array[0];
63	double highest = array[0];
64
65	for(unsigned dex=0; dex<arraySize; dex++) {
66		double curr = array[dex];
67		sum += curr;
68		if(curr < lowest) {
69			lowest = curr;
70		}
71		if(curr > highest) {
72			highest = curr;
73		}
74	}
75	if(arraySize > 2) {
76		sum -= lowest;
77		sum -= highest;
78		arraySize -= 2;
79	}
80	return sum / (double)arraySize;
81}
82