]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/src/Ovw_data.cc
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gprofng / src / Ovw_data.cc
CommitLineData
fd67aa11 1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
bb368aad
VM
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 <memory.h>
23#include <values.h>
24#include <assert.h>
25#include "Data_window.h"
26#include "Exp_Layout.h"
27#include "Table.h"
28#include "Ovw_data.h"
29#include "Sample.h"
30#include "data_pckts.h"
31#include "util.h"
32#include "i18n.h"
33
34void
35Ovw_data::sum (Ovw_data *data)
36{
37 Ovw_item data_totals = data->get_totals ();
38 if (totals == NULL)
39 {
40 totals = reset_item (new Ovw_item);
41 *totals = data_totals;
42 totals->start.tv_sec = totals->end.tv_sec = -1;
43 totals->start.tv_nsec = totals->end.tv_nsec = 0;
44 }
45 else
46 {
47 tsadd (&totals->duration, &data_totals.duration);
48 tsadd (&totals->tlwp, &data_totals.tlwp);
49 if (tstodouble (totals->duration) != 0)
50 totals->nlwp = tstodouble (totals->tlwp) / tstodouble (totals->duration);
51
52 for (int i = 0, size = totals->size; i < size; i++)
53 tsadd (&totals->values[i].t, &data_totals.values[i].t);
54 }
55}
56
57Ovw_data::Ovw_item *
58Ovw_data::reset_item (Ovw_data::Ovw_item *item)
59{
60 memset (item, 0, sizeof (*item));
61 return item;
62}
63
64Ovw_data::Ovw_item
65Ovw_data::get_totals ()
66{
67 // This routine will return the totals values for item in the sample.
68 // Compute maximums and totals only once, and save the result.
69 // On subsequent calls, just return the saved result.
70 // If maximums is NULL, then totals is also NULL
71 if (totals != NULL)
72 return *totals;
73
74 timestruc_t zero = {0, 0};
75 totals = reset_item (new Ovw_item);
76 totals->start.tv_sec = MAXINT; // new
77 totals->start.tv_nsec = MAXINT; // new
78 totals->start_label = totals->end_label = NTXT ("Total");
79 totals->type = VT_HRTIME;
80
81 int nsampsel = 0;
82 for (int index = 0; index < size (); index++)
83 {
84 Ovw_item item = fetch (index);
85 nsampsel++;
86
87 // Compute totals
88 for (int i = 0; i < OVW_NUMVALS + 1; i++)
89 tsadd (&totals->values[i].t, &item.values[i].t);
90
91 int_max (&totals->states, item.states);
92 tsadd (&totals->total.t, &item.total.t);
93 int_max (&totals->size, item.size);
94 tsadd (&totals->duration, &item.duration);
95 tsadd (&totals->tlwp, &item.tlwp);
96 totals->number += item.number;
97 if (tscmp (&totals->start, &item.start) > 0)
98 totals->start = item.start;
99 if (tscmp (&totals->end, &item.end) < 0)
100 totals->end = item.end;
101 }
102
103 if (totals->start.tv_sec == MAXINT && totals->start.tv_nsec == MAXINT)
104 totals->start = zero;
105 totals->nlwp = tstodouble (totals->tlwp) / tstodouble (totals->duration);
106
107 if (nsampsel == 0)
108 {
109 totals->size = OVW_NUMVALS + 1;
110 totals->start.tv_sec = totals->end.tv_sec = -1;
111 totals->start.tv_nsec = totals->end.tv_nsec = 0;
112 totals->nlwp = -1;
113 }
114 return *totals;
115}
116
117Ovw_data::Ovw_item
118Ovw_data::get_labels ()
119{
120 Ovw_item ovw_item;
121 Value *values;
122 memset (&ovw_item, 0, sizeof (Ovw_item));
123 values = &ovw_item.values[0];
124
125 char *stateUNames[/*LMS_NUM_STATES*/] = LMS_STATE_USTRINGS;
126 values[0].l = dbe_strdup (GTXT ("Leftover"));
127 values[OVW_LMS_USER + 1].l = stateUNames[LMS_USER];
128 values[OVW_LMS_SYSTEM + 1].l = stateUNames[LMS_SYSTEM];
129 values[OVW_LMS_WAIT_CPU + 1].l = stateUNames[LMS_WAIT_CPU];
130 values[OVW_LMS_USER_LOCK + 1].l = stateUNames[LMS_USER_LOCK];
131 values[OVW_LMS_TFAULT + 1].l = stateUNames[LMS_TFAULT];
132 values[OVW_LMS_DFAULT + 1].l = stateUNames[LMS_DFAULT];
133 values[OVW_LMS_KFAULT + 1].l = stateUNames[LMS_KFAULT];
134 values[OVW_LMS_SLEEP + 1].l = stateUNames[LMS_SLEEP];
135 values[OVW_LMS_STOPPED + 1].l = stateUNames[LMS_STOPPED];
136 values[OVW_LMS_TRAP + 1].l = stateUNames[LMS_TRAP];
137
138 ovw_item.size = OVW_NUMVALS + 1;
139 ovw_item.states = 0;
140 ovw_item.type = VT_LABEL;
141 return ovw_item;
142}
143
144Ovw_data::Ovw_data ()
145{
146 packets = NULL;
147 ovw_items = new Vector<Ovw_item*>;
148 totals = NULL;
149}
150
151Ovw_data::Ovw_data (DataView *_packets, hrtime_t exp_start)
152{
153 packets = _packets;
154 ovw_items = new Vector<Ovw_item*>;
155 totals = NULL;
156 long npackets = packets->getSize ();
157 for (long index = 0; index < npackets; index++)
158 {
159 Ovw_item *ovw_item = new Ovw_item;
160 memset (ovw_item, 0, sizeof (Ovw_item));
161 Sample *sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, index);
162 extract_data (ovw_item, sample);
163 hr2timestruc (&ovw_item->start, sample->get_start_time () - exp_start);
164 hr2timestruc (&ovw_item->end, sample->get_end_time () - exp_start);
165 // No need to check for duration, as duration has to be > 0.
166 // If not, it would have been found out in yyparse.
167 tssub (&ovw_item->duration, &ovw_item->end, &ovw_item->start);
168 ovw_item->number = sample->get_number ();
169 ovw_item->start_label = sample->get_start_label ();
170 ovw_item->end_label = sample->get_end_label ();
171
172 int size = ovw_item->size;
173 for (int j = 0; j < size; j++)
174 tsadd (&ovw_item->tlwp, &ovw_item->values[j].t);
175 if (tstodouble (ovw_item->duration) != 0)
176 ovw_item->nlwp = tstodouble (ovw_item->tlwp) /
177 tstodouble (ovw_item->duration);
178 ovw_items->append (ovw_item);
179 }
180}
181
182Ovw_data::~Ovw_data ()
183{
184 ovw_items->destroy ();
185 delete ovw_items;
186 delete totals;
187}
188
189void
190Ovw_data::extract_data (Ovw_data::Ovw_item *ovw_item, Sample *sample)
191{
192 // This routine break out the data in "data" into buckets in "ovw_item"
193 int index;
194 int states;
195 timestruc_t sum, rtime;
196 timestruc_t zero = {0, 0};
197 Value *values;
198 PrUsage *prusage = sample->get_usage ();
199 if (prusage == NULL)
200 prusage = new PrUsage;
201
202 values = &ovw_item->values[0];
203 hr2timestruc (&values[OVW_LMS_USER + 1].t, prusage->pr_utime);
204 hr2timestruc (&values[OVW_LMS_SYSTEM + 1].t, prusage->pr_stime);
205 hr2timestruc (&values[OVW_LMS_WAIT_CPU + 1].t, prusage->pr_wtime);
206 hr2timestruc (&values[OVW_LMS_USER_LOCK + 1].t, prusage->pr_ltime);
207 hr2timestruc (&values[OVW_LMS_TFAULT + 1].t, prusage->pr_tftime);
208 hr2timestruc (&values[OVW_LMS_DFAULT + 1].t, prusage->pr_dftime);
209 hr2timestruc (&values[OVW_LMS_TRAP + 1].t, prusage->pr_ttime);
210 hr2timestruc (&values[OVW_LMS_KFAULT + 1].t, prusage->pr_kftime);
211 hr2timestruc (&values[OVW_LMS_SLEEP + 1].t, prusage->pr_slptime);
212 hr2timestruc (&values[OVW_LMS_STOPPED + 1].t, prusage->pr_stoptime);
213 ovw_item->size = OVW_NUMVALS + 1;
214
215 //XXX: Compute values[0] as rtime - sum_of(other_times)
216 sum = zero;
217 states = 0;
218 for (index = 1; index < ovw_item->size; index++)
219 {
220 if (values[index].t.tv_sec != 0 || values[index].t.tv_nsec != 0)
221 states++;
222 tsadd (&sum, &values[index].t);
223 }
224
225 // If the sum of all times is greater than rtime then adjust
226 // rtime to be equal to sum and also adjust the pr_rtime field
227 hr2timestruc (&rtime, prusage->pr_rtime);
228 if (tscmp (&sum, &rtime) > 0)
229 {
230 ovw_item->total.t = sum;
231 values[0].t = zero;
232 }
233 else
234 {
235 ovw_item->total.t = rtime;
236 tssub (&rtime, &rtime, &sum);
237 tsadd (&values[0].t, &rtime);
238 states++;
239 }
240 ovw_item->type = VT_HRTIME;
241 ovw_item->states = states;
242}