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 
36 int
size()37 Stats_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 
45 Stats_data::Stats_item
fetch(int index)46 Stats_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 
Stats_data()53 Stats_data::Stats_data ()
54 {
55   // this constructor for use with sum()
56   packets = NULL;
57   stats_items = NULL;
58 }
59 
Stats_data(DataView * _packets)60 Stats_data::Stats_data (DataView *_packets)
61 {
62   packets = _packets;
63   stats_items = NULL;
64   compute_data ();  // reads all data
65 }
66 
~Stats_data()67 Stats_data::~Stats_data ()
68 {
69   if (stats_items)
70     {
71       stats_items->destroy ();
72       delete stats_items;
73     }
74 }
75 
76 void
sum(Stats_data * data)77 Stats_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 
99 Stats_data::Stats_item *
create_stats_item(long long v,char * l)100 Stats_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 
111 PrUsage *
fetchPrUsage(long index)112 Stats_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 
126 void
compute_data()127 Stats_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