1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#include "config.h"
22//#include <search.h>     //  For the tsearch stuff
23#include <assert.h>
24//#include <stdlib.h>
25#include "Table.h"
26#include "Sample.h"
27#include "Stats_data.h"
28#include "util.h"
29#include "i18n.h"
30
31//XXX:	The fundamental problem with this package of routines is that
32//XXX:	they should look a lot more like overview data. The result
33//XXX:	is that it is not possible to share as much code as would
34//XXX:	otherwise be possible.
35
36int
37Stats_data::size ()
38{
39  // Return the number of Stats_item values associated with "this".
40  if (stats_items == NULL)
41    return 0;
42  return stats_items->size ();
43}
44
45Stats_data::Stats_item
46Stats_data::fetch (int index)
47{
48  // Routine will return the "index"'th Stats_item associated with "this".
49  assert (index >= 0 && index < stats_items->size ());
50  return *(stats_items->fetch (index));
51}
52
53Stats_data::Stats_data ()
54{
55  // this constructor for use with sum()
56  packets = NULL;
57  stats_items = NULL;
58}
59
60Stats_data::Stats_data (DataView *_packets)
61{
62  packets = _packets;
63  stats_items = NULL;
64  compute_data ();  // reads all data
65}
66
67Stats_data::~Stats_data ()
68{
69  if (stats_items)
70    {
71      stats_items->destroy ();
72      delete stats_items;
73    }
74}
75
76void
77Stats_data::sum (Stats_data *data)
78{
79  int index;
80  Stats_item *stats_item, *data_item;
81  if (stats_items == NULL)
82    {
83      stats_items = new Vector<Stats_item*>;
84      Vec_loop (Stats_item*, data->stats_items, index, data_item)
85      {
86	stats_item = create_stats_item (data_item->value.ll, data_item->label);
87	stats_items->append (stats_item);
88      }
89    }
90  else
91    {
92      Vec_loop (Stats_item*, data->stats_items, index, data_item)
93      {
94	stats_items->fetch (index)->value.ll += data_item->value.ll;
95      }
96    }
97}
98
99Stats_data::Stats_item *
100Stats_data::create_stats_item (long long v, char *l)
101{
102  Stats_data::Stats_item *st_it;
103  st_it = new Stats_data::Stats_item;
104  st_it->label = l;
105  st_it->value.sign = false;
106  st_it->value.ll = v;
107  st_it->value.tag = VT_LLONG;
108  return st_it;
109}
110
111PrUsage *
112Stats_data::fetchPrUsage (long index)
113{
114  // Return the data values corresponding to the "index"'th sample.
115  PrUsage *prusage;
116  if (packets->getSize () > 0)
117    {
118      Sample* sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, index);
119      prusage = sample->get_usage ();
120      if (prusage != NULL)
121	return prusage;
122    }
123  return new PrUsage;
124}
125
126void
127Stats_data::compute_data ()
128{
129  Stats_data::Stats_item *stats_item;
130  PrUsage *tots, *temp;
131  stats_items = new Vector<Stats_data::Stats_item*>;
132
133  // Precomputation is needed.
134  long size = packets->getSize ();
135  tots = new PrUsage ();
136  for (long index = 0; index < size; index++)
137    {
138      temp = fetchPrUsage (index);
139      tots->pr_tstamp += temp->pr_tstamp;
140      tots->pr_create += temp->pr_create;
141      tots->pr_term += temp->pr_term;
142      tots->pr_rtime += temp->pr_rtime;
143      tots->pr_utime += temp->pr_utime;
144      tots->pr_stime += temp->pr_stime;
145      tots->pr_ttime += temp->pr_ttime;
146      tots->pr_tftime += temp->pr_tftime;
147      tots->pr_dftime += temp->pr_dftime;
148      tots->pr_kftime += temp->pr_kftime;
149      tots->pr_slptime += temp->pr_slptime;
150      tots->pr_ltime += temp->pr_ltime;
151      tots->pr_wtime += temp->pr_wtime;
152      tots->pr_stoptime += temp->pr_stoptime;
153      tots->pr_minf += temp->pr_minf;
154      tots->pr_majf += temp->pr_majf;
155      tots->pr_nswap += temp->pr_nswap;
156      tots->pr_inblk += temp->pr_inblk;
157      tots->pr_oublk += temp->pr_oublk;
158      tots->pr_msnd += temp->pr_msnd;
159      tots->pr_mrcv += temp->pr_mrcv;
160      tots->pr_sigs += temp->pr_sigs;
161      tots->pr_vctx += temp->pr_vctx;
162      tots->pr_ictx += temp->pr_ictx;
163      tots->pr_sysc += temp->pr_sysc;
164      tots->pr_ioch += temp->pr_ioch;
165    }
166  stats_item = create_stats_item ((long long) tots->pr_minf,
167				  GTXT ("Minor Page Faults"));
168  stats_items->append (stats_item);
169  stats_item = create_stats_item ((long long) tots->pr_majf,
170				  GTXT ("Major Page Faults"));
171  stats_items->append (stats_item);
172  stats_item = create_stats_item ((long long) tots->pr_nswap,
173				  GTXT ("Process swaps"));
174  stats_items->append (stats_item);
175  stats_item = create_stats_item ((long long) tots->pr_inblk,
176				  GTXT ("Input blocks"));
177  stats_items->append (stats_item);
178  stats_item = create_stats_item ((long long) tots->pr_oublk,
179				  GTXT ("Output blocks"));
180  stats_items->append (stats_item);
181  stats_item = create_stats_item ((long long) tots->pr_msnd,
182				  GTXT ("Messages sent"));
183  stats_items->append (stats_item);
184  stats_item = create_stats_item ((long long) tots->pr_mrcv,
185				  GTXT ("Messages received"));
186  stats_items->append (stats_item);
187  stats_item = create_stats_item ((long long) tots->pr_sigs,
188				  GTXT ("Signals handled"));
189  stats_items->append (stats_item);
190  stats_item = create_stats_item ((long long) tots->pr_vctx,
191				  GTXT ("Voluntary context switches"));
192  stats_items->append (stats_item);
193  stats_item = create_stats_item ((long long) tots->pr_ictx,
194				  GTXT ("Involuntary context switches"));
195  stats_items->append (stats_item);
196  stats_item = create_stats_item ((long long) tots->pr_sysc,
197				  GTXT ("System calls"));
198  stats_items->append (stats_item);
199  stats_item = create_stats_item ((long long) tots->pr_ioch,
200				  GTXT ("Characters of I/O"));
201  stats_items->append (stats_item);
202  delete tots;
203}
204