summaryrefslogtreecommitdiff
path: root/src/hal/components/latencybins.comp
blob: 37c658b14524edbbac45cd83f56f36010c89a9a4 (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
component latencybins
"""comp utility for scripts/latencyhistogram

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 pbinvalue,nbinvalue,pextra,nextra 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)

   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 pbinvalue;
pin out s32 nbinvalue;
pin out s32 pextra;
pin out s32 nextra;

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

function _ nofp;
variable __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;

license "GPL";
;;

__s64     now = rtapi_get_time();
__s32   lat32 = (__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;
  pextra = 0; nextra = 0;
  for (i = 0; i <= binmax; i++) {
    pbins[i] = 0; nbins[i] = 0;
  }
} else {
  latency = lat32;
  i = lat32/nsbinsize;
  if (i >= 0) {
     if (i > binmax) {
       pextra++;
     } else {
       pbins[i]++;
     }
  } else {
     i = -i;
     if (i > binmax) {
       nextra++;
     } else {
       nbins[i]++;
     }
  }
}

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;
}