aboutsummaryrefslogtreecommitdiffstats
path: root/src/hal/components/latencybins.comp
blob: 665dff7e5e81ed1a7ad6ccfe96ed62428834fe96 (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
135
136
137
138
component latencybins
"""comp utility for scripts/latency-histogram

Usage:
  Read availablebins pin for the number of bins available.
  Set the maxbinnumber pin for the number of \(+- bins.
    Ensure maxbinnumber <= availablebins
    For maxbinnumber = N, the bins are numbered:
       \-N ... 0 ... + N bins
    (the \-0 bin is not populated)
    (total effective bins = 2*maxbinnumber +1)
  Set nsbinsize pin for the binsize (ns)
  Iterate:
    Set index pin to a bin number: 0 <= index <= maxbinnumber.
    Read check pin and verify that check pin == index pin.
    Read output pins:
         pbinvalue is count for bin = +index
         nbinvalue is count for bin = \-index
         pextra    is count for all bins > maxbinnumber
         nextra    is count for all bins < maxbinnumber
         latency-min is max negative latency
         latency-max is max positive latency

   If index is out of range ( index < 0 or index > maxbinnumber)
   then pbinvalue = nbinvalue = \-1.
   The reset pin may be used to restart.
   The latency pin outputs the instantaneous latency.

Maintainers note: hardcoded for MAXBINNUMBER==1000
""";

pin in  s32 maxbinnumber = 1000;  // MAXBINNUMBER
pin in  s32 index;  //use s32 to avoid 0x hex display in hal
pin in  bit reset;
pin in  s32 nsbinsize;

pin out s32 check;
pin out s32 latency;
pin out s32 latency_max;
pin out s32 latency_min;
pin out s32 pbinvalue;
pin out s32 nbinvalue;
pin out s32 pextra;
pin out s32 nextra;
pin out s32 variance;

// user may interrogate available bins to determine this compiled-in limit
pin out s32 availablebins = 1000; // MAXBINNUMBER

function _ nofp;
variable rtapi_s64  last_timer = 0;
variable int    last_binmax = 0;
variable int    first = 1;
variable int    pbins[1001]; // MAXBINNUMBER+1
variable int    nbins[1001]; // MAXBINNUMBER+1
variable int    binmax = 0;

variable rtapi_u32 nsamples;
variable rtapi_u64 sum;
variable rtapi_u64 sq_sum;

license "GPL";
author "Dewey Garrett";
;;

rtapi_s64     now = rtapi_get_time();
rtapi_s32   lat32 = (rtapi_s32)(now - last_timer - period);
                //(2^31-1)*1nS = 2.147 seconds max

int i;

last_timer = now;

binmax =  maxbinnumber;
if (binmax > availablebins) binmax = availablebins;
last_binmax = binmax;

if (reset) {first = 1;}

if (   first
     || binmax != last_binmax
     || nsbinsize == 0  // important to avoid divide by zero
  ) {
  first = 0;
  latency = 0;
  latency_min = 0x7FFFFFFF;
  latency_max = 0x80000000;
  pextra = 0; nextra = 0;
  for (i = 0; i <= binmax; i++) {
    pbins[i] = 0; nbins[i] = 0;
  }
  nsamples = 0;
  sum = 0;
  sq_sum = 0;
} else {
  latency = lat32;
  i = lat32/nsbinsize;
  if (lat32 > latency_max) latency_max = lat32;
  if (lat32 < latency_min) latency_min = lat32;
  if (i >= 0) {
     if (i > binmax) {
       pextra++;
     } else {
       pbins[i]++;
     }
  } else {
     i = -i;
     if (i > binmax) {
       nextra++;
     } else {
       nbins[i]++;
     }
  }
  nsamples++;
  sum    += lat32;
  sq_sum += lat32 * lat32;
  if (nsamples > 1) {
    // note: division required is: u64/u32
    rtapi_u64 dividend;
    rtapi_u64 divisor;
    dividend = sq_sum - rtapi_div_u64(sum * sum,nsamples);
    divisor  = nsamples -1;
    variance = rtapi_div_u64(dividend,divisor);
  }
}

check = index; // user should verify check==index for reading values
// -1 value indicates illegal index
if (index < 0) {
  pbinvalue = -1;
  nbinvalue = -1;
} else if (index <=binmax) {
  pbinvalue = pbins[index];
  nbinvalue = nbins[index];
} else {
  pbinvalue = -1;
  nbinvalue = -1;
}
bues.ch cgit interface