Fix potential core dump when closing ports at exit
[samplevnf.git] / VNFs / DPPD-PROX / stats_global.c
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <string.h>
18 #include <rte_cycles.h>
19 #include <inttypes.h>
20
21 #include "stats_global.h"
22 #include "stats_port.h"
23 #include "stats_task.h"
24
25 struct global_stats {
26         struct global_stats_sample sample[2];
27         struct global_stats_sample beg;
28         uint8_t  started_avg;
29         uint64_t start_tsc;
30         uint64_t end_tsc;
31 };
32
33 extern int last_stat;
34 static struct global_stats global_stats;
35
36 uint64_t stats_get_last_tsc(void)
37 {
38         return global_stats.sample[last_stat].tsc;
39 }
40
41 uint64_t stats_global_start_tsc(void)
42 {
43         return global_stats.start_tsc;
44 }
45
46 uint64_t stats_global_beg_tsc(void)
47 {
48         return global_stats.beg.tsc;
49 }
50
51 uint64_t stats_global_end_tsc(void)
52 {
53         return global_stats.end_tsc;
54 }
55
56 struct global_stats_sample *stats_get_global_stats(int last)
57 {
58         return &global_stats.sample[last == last_stat];
59 }
60
61 struct global_stats_sample *stats_get_global_stats_beg(void)
62 {
63         return (global_stats.beg.tsc < global_stats.sample[last_stat].tsc)? &global_stats.beg : NULL;
64 }
65
66 void stats_global_reset(void)
67 {
68         uint64_t now = rte_rdtsc();
69         uint64_t last_tsc = global_stats.sample[last_stat].tsc;
70         uint64_t prev_tsc = global_stats.sample[!last_stat].tsc;
71         uint64_t end_tsc = global_stats.end_tsc;
72
73         memset(&global_stats, 0, sizeof(struct global_stats));
74         global_stats.sample[last_stat].tsc = last_tsc;
75         global_stats.sample[!last_stat].tsc = prev_tsc;
76         global_stats.start_tsc = now;
77         global_stats.beg.tsc = now;
78         global_stats.end_tsc = end_tsc;
79 }
80
81 void stats_global_init(unsigned avg_start, unsigned duration)
82 {
83         uint64_t now = rte_rdtsc();
84
85         global_stats.start_tsc = now;
86         /* + 1 for rounding */
87         tsc_hz = rte_get_tsc_hz();
88         if (duration)
89                 global_stats.end_tsc = global_stats.start_tsc + (avg_start + duration + 1) * tsc_hz;
90
91         global_stats.beg.tsc = global_stats.start_tsc + avg_start * tsc_hz;
92 }
93
94 void stats_global_post_proc(void)
95 {
96         uint64_t *rx = &global_stats.sample[last_stat].host_rx_packets;
97         uint64_t *tx = &global_stats.sample[last_stat].host_tx_packets;
98         uint64_t *tsc = &global_stats.sample[last_stat].tsc;
99
100         stats_task_get_host_rx_tx_packets(rx, tx, tsc);
101         global_stats.sample[last_stat].nics_ierrors    = stats_port_get_ierrors();
102         global_stats.sample[last_stat].nics_imissed    = stats_port_get_imissed();
103         global_stats.sample[last_stat].nics_rx_packets = stats_port_get_rx_packets();
104         global_stats.sample[last_stat].nics_tx_packets = stats_port_get_tx_packets();
105
106         if (global_stats.sample[last_stat].tsc > global_stats.beg.tsc && !global_stats.started_avg) {
107                 global_stats.started_avg = 1;
108                 global_stats.beg = global_stats.sample[last_stat];
109         }
110 }