/
counters.go
119 lines (101 loc) · 3.29 KB
/
counters.go
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
package tgconsumer
/*
#include "../../csrc/tgconsumer/rx.h"
#include "../../csrc/tgconsumer/token.h"
#include "../../csrc/tgconsumer/tx.h"
*/
import "C"
import (
"fmt"
"math"
"time"
"unsafe"
"github.com/usnistgov/ndn-dpdk/core/runningstat"
"github.com/usnistgov/ndn-dpdk/dpdk/eal"
)
// PacketCounters is a group of network layer packet counters.
type PacketCounters struct {
NInterests uint64 `json:"nInterests"`
NData uint64 `json:"nData"`
NNacks uint64 `json:"nNacks"`
}
// ComputeDataRatio returns NData/NInterests.
func (cnt PacketCounters) ComputeDataRatio() float64 {
return float64(cnt.NData) / float64(cnt.NInterests)
}
// ComputeNackRatio returns NNacks/NInterests.
func (cnt PacketCounters) ComputeNackRatio() float64 {
return float64(cnt.NNacks) / float64(cnt.NInterests)
}
func (cnt PacketCounters) String() string {
return fmt.Sprintf("%dI %dD(%0.2f%%) %dN(%0.2f%%)",
cnt.NInterests,
cnt.NData, cnt.ComputeDataRatio()*100.0,
cnt.NNacks, cnt.ComputeNackRatio()*100.0)
}
// RttCounters contains RTT statistics.
type RttCounters struct {
runningstat.Snapshot
}
func (cnt RttCounters) String() string {
ms := cnt.Scale(1.0 / float64(time.Millisecond))
return fmt.Sprintf("%0.3f/%0.3f/%0.3f/%0.3fms(%dsamp)", ms.Min(), ms.Mean(), ms.Max(), ms.Stdev(), ms.Len())
}
// PatternCounters contains per-pattern counters.
type PatternCounters struct {
PacketCounters
Rtt RttCounters `json:"rtt"`
}
func (cnt PatternCounters) String() string {
return fmt.Sprintf("%s rtt=%s", cnt.PacketCounters, cnt.Rtt)
}
// Counters contains consumer counters.
type Counters struct {
PacketCounters
NAllocError uint64 `json:"nAllocError"`
Rtt RttCounters `json:"rtt"`
PerPattern []PatternCounters `json:"perPattern"`
}
func (cnt Counters) String() string {
s := fmt.Sprintf("%s %dalloc-error rtt=%s", cnt.PacketCounters, cnt.NAllocError, cnt.Rtt)
for i, pcnt := range cnt.PerPattern {
s += fmt.Sprintf(", pattern(%d) %s", i, pcnt)
}
return s
}
// ReadCounters retrieves counters.
func (consumer *Consumer) ReadCounters() (cnt Counters) {
rttScale := eal.GetNanosInTscUnit() * math.Exp2(C.TGCONSUMER_TIMING_PRECISION)
for i := 0; i < int(consumer.rxC.nPatterns); i++ {
crP := consumer.rxC.pattern[i]
ctP := consumer.txC.pattern[i]
rtt := runningstat.FromPtr(unsafe.Pointer(&crP.rtt)).Read().Scale(rttScale)
var pcnt PatternCounters
pcnt.NInterests = uint64(ctP.nInterests)
pcnt.NData = uint64(crP.nData)
pcnt.NNacks = uint64(crP.nNacks)
pcnt.Rtt.Snapshot = rtt
cnt.PerPattern = append(cnt.PerPattern, pcnt)
cnt.NInterests += pcnt.NInterests
cnt.NData += pcnt.NData
cnt.NNacks += pcnt.NNacks
cnt.Rtt.Snapshot = cnt.Rtt.Snapshot.Add(rtt)
}
cnt.NAllocError = uint64(consumer.txC.nAllocError)
return cnt
}
// ClearCounters clears counters.
// Both RX and TX threads should be stopped before calling this, otherwise race conditions may occur.
func (consumer *Consumer) ClearCounters() {
nPatterns := int(consumer.rxC.nPatterns)
for i := 0; i < nPatterns; i++ {
consumer.clearCounter(i)
}
}
func (consumer *Consumer) clearCounter(index int) {
consumer.rxC.pattern[index].nData = 0
consumer.rxC.pattern[index].nNacks = 0
rtt := runningstat.FromPtr(unsafe.Pointer(&consumer.rxC.pattern[index].rtt))
rtt.Clear(true)
consumer.txC.pattern[index].nInterests = 0
}