Automatic date update in version.in
[binutils-gdb.git] / gprofng / src / Ovw_data.cc
blob2cd57180783e5cc2a82f6867244262ff926ab504
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2 Contributed by Oracle.
4 This file is part of GNU Binutils.
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.
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.
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. */
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"
34 void
35 Ovw_data::sum (Ovw_data *data)
37 Ovw_item data_totals = data->get_totals ();
38 if (totals == NULL)
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;
45 else
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);
52 for (int i = 0, size = totals->size; i < size; i++)
53 tsadd (&totals->values[i].t, &data_totals.values[i].t);
57 Ovw_data::Ovw_item *
58 Ovw_data::reset_item (Ovw_data::Ovw_item *item)
60 memset (item, 0, sizeof (*item));
61 return item;
64 Ovw_data::Ovw_item
65 Ovw_data::get_totals ()
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;
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;
81 int nsampsel = 0;
82 for (int index = 0; index < size (); index++)
84 Ovw_item item = fetch (index);
85 nsampsel++;
87 // Compute totals
88 for (int i = 0; i < OVW_NUMVALS + 1; i++)
89 tsadd (&totals->values[i].t, &item.values[i].t);
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;
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);
107 if (nsampsel == 0)
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;
114 return *totals;
117 Ovw_data::Ovw_item
118 Ovw_data::get_labels ()
120 Ovw_item ovw_item;
121 Value *values;
122 memset (&ovw_item, 0, sizeof (Ovw_item));
123 values = &ovw_item.values[0];
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];
138 ovw_item.size = OVW_NUMVALS + 1;
139 ovw_item.states = 0;
140 ovw_item.type = VT_LABEL;
141 return ovw_item;
144 Ovw_data::Ovw_data ()
146 packets = NULL;
147 ovw_items = new Vector<Ovw_item*>;
148 totals = NULL;
151 Ovw_data::Ovw_data (DataView *_packets, hrtime_t exp_start)
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++)
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 ();
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);
182 Ovw_data::~Ovw_data ()
184 ovw_items->destroy ();
185 delete ovw_items;
186 delete totals;
189 void
190 Ovw_data::extract_data (Ovw_data::Ovw_item *ovw_item, Sample *sample)
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;
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;
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++)
220 if (values[index].t.tv_sec != 0 || values[index].t.tv_nsec != 0)
221 states++;
222 tsadd (&sum, &values[index].t);
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)
230 ovw_item->total.t = sum;
231 values[0].t = zero;
233 else
235 ovw_item->total.t = rtime;
236 tssub (&rtime, &rtime, &sum);
237 tsadd (&values[0].t, &rtime);
238 states++;
240 ovw_item->type = VT_HRTIME;
241 ovw_item->states = states;