]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/src/Experiment.h
Update year range in gprofng copyright notices
[thirdparty/binutils-gdb.git] / gprofng / src / Experiment.h
CommitLineData
76bdc726 1/* Copyright (C) 2021-2023 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#ifndef _EEXPERIMENT_H
22#define _EEXPERIMENT_H
23
24// The experiment class is responsible for managing all the data
25// for an individual experiment
26
27#include "Metric.h"
28#include "Histable.h"
29#include "Stats_data.h"
30#include "DefaultMap.h"
31#include "HeapMap.h"
32
33class Data_window;
34class DbeFile;
35class CallStack;
36class JMethod;
37class Sample;
38class SegMem;
39class LoadObject;
40class SourceFile;
41class UserLabel;
42class PRBTree;
43class Emsg;
44class Emsgqueue;
45struct JThread;
46struct GCEvent;
47class FileData;
48class Module;
49class Experiment;
50template <class ITEM> class Vector;
51
52#define JTHREAD_DEFAULT ((JThread*)0)
53#define JTHREAD_NONE ((JThread*)-1)
54
55// When we perform the pipelined optimization on resolve_frame_info() and add_stack()
56// this is the number of iterations one phase works on before passing on the work to
57// the next phase
58
59#define CSTCTX_CHUNK_SZ 10000
60#define PIPELINE_QUEUE_SZ_HI 8
61#define PIPELINE_QUEUE_SZ_LOW 2
62
63// the add_stack_ctx structure contains the intermediate state (context) after
64// CSTCTX_CHUNK_SZ number of iterations to pass on the work to another thread to
65// operate on the next stage
66typedef struct
67{
68 Vector<DbeInstr*> *natpcs;
69 Vector<Histable*> *jpcs;
70 long idx;
71 FramePacket *frp;
72 hrtime_t tstamp;
73 uint32_t thrid;
74 bool last_ctx;
75} cstk_ctx;
76
77// To minimize threadpool overhead, the granularity of a job submitted is made larger:
78// containing a chunk of iterations (of size CSTCTX_CHUNK_SZ)
79typedef struct
80{
81 cstk_ctx* cstCtxAr[CSTCTX_CHUNK_SZ];
82 int last_idx;
83 long idx_begin;
84 long idx_end;
85 DataDescriptor *dDscr;
86 Experiment *exp;
87 void *cstk;
88} cstk_ctx_chunk;
89
90class Experiment : public Histable, public DbeMessages
91{
92public:
93
94 enum Exp_status
95 {
96 SUCCESS,
97 INCOMPLETE,
98 FAILURE
99 };
100
101 Experiment ();
102 virtual ~Experiment ();
103
104 virtual Histable_type
105 get_type ()
106 {
107 return EXPERIMENT;
108 };
109 virtual Vector<Histable*> *get_comparable_objs ();
110
111 int groupId;
112 Experiment *founder_exp; // parent of this experiment
113 Vector<Experiment*> *children_exps; // children of this experiment
114
115 // Configuration Information
116 char *hostname; // Hosthame (e.g. mymachine)
6094a48e 117 hrtime_t start_sec; // Starting timeval secs.
bb368aad
VM
118 char *username; // name of person performing the test
119 char *architecture; // Architecture name ("sun4")
120 Platform_t platform; // Sparc,Sparcv9,Intel
121 WSize_t wsize; // word size: may be w32 or w64
122 int clock; // CPU clock frequency, Mhz
123 int varclock; // Set if CPU clock frequency can change: turbo-mode
124 int maxclock; // max. CPU clock frequency on MP machine
125 int minclock; // min. CPU clock frequency on MP machine
126 int ncpus; // count of CPUs where expt was recorded
127 int hw_cpuver; // CPU version from libcpc
128 char *machinemodel; // machine model of machine on which experiment was recorded
129 char *os_version; // Operating system name
130 int page_size; // Page size (bytes)
131 int npages; // Number of page size
132 int exp_maj_version; // major version number of current experiment
133 int exp_min_version; // minor version number of current experiment
134 int hex_field_width; // number of digits in hex form of address
135 // for current experiment, i.e. 8 for 32bit addresses
136 int broken; // If SP_JCMD_RUN line not seen
137 int obsolete; // If pointer file experiment detected
138 bool hwc_default; // True if HW counters were enabled by default
139 int hwc_bogus; // Count of bogus HWC packets
140 int hwc_lost_int; // Count of packets reflecting lost interrupt
141 int hwc_scanned; // If the HWC packets have been scanned
142 int invalid_packet; // Count of invalid packets
143 bool exec_started; // True if exec was called, and exec error not yet seen
144 bool dataspaceavail; // True if dataspace data is in the experiment
145 bool leaklistavail; // True if leaklist data is in the experiment
146 bool heapdataavail; // True if heap data is in the experiment
147 bool racelistavail; // true if there are race events in the experiment
148 bool iodataavail; // true if there are io events in the experiment
149 bool deadlocklistavail; // true if there are deadlock events in the experiment
150 bool timelineavail; // true if there are valid timestamps in the experiment
151 bool ifreqavail; // True if instruction-frequency data is in the experiment
152 bool ompavail; // true if there is OpenMP data in the experiment
153 bool has_java;
154 char *uarglist; // argv[] array, as a string
155 char *utargname; // basename of argv[0] extracted from uarglist
156 char *ucwd; // working directory
157 char *cversion; // collector version string
158 char *dversion; // driver version string (er_kernel)
159 char *jversion; // Java version string (java profiling)
160
161 // Open the named experiment record and process log file
162 Exp_status open (char *directory_name);
163
164 // Update experiment (read and process new data)
165 Exp_status update ();
166
167 // Returns collector parameters for the current sample selection
168 Collection_params *
169 get_params ()
170 {
171 return &coll_params;
172 }
173
174 Exp_status
175 get_status ()
176 {
177 return status;
178 }
179
180 // Returns the number of samples. For use by FilterNumeric
181 int
182 nsamples ()
183 {
184 return samples->size ();
185 }
186
187 // Release any releasable memory.
188 void purge ();
189
190 void resetShowHideStack ();
191 int save_notes (char*, bool);
192 int delete_notes (bool);
193 Experiment *getBaseFounder (); // returns topmost founder or this if no descendents
194
195 hrtime_t
196 getStartTime ()
197 {
198 return exp_start_time;
199 }
200 hrtime_t getRelativeStartTime (); // delta between start and founder's start
201
202 hrtime_t
203 getWallStartSec ()
204 {
205 return start_sec;
206 }
207
208 hrtime_t
209 getLastEvent ()
210 {
211 if (last_event != ZERO_TIME)
212 return last_event;
213 return exp_start_time;
214 }
215
216 hrtime_t
217 getGCDuration ()
218 {
219 return gc_duration;
220 }
221
222 int
223 getPID ()
224 {
225 return pid;
226 }
227
228 int
229 getUserExpId ()
230 {
231 return userExpId;
232 }
233
234 int
235 getExpIdx ()
236 {
237 return expIdx;
238 }
239
240 void
241 setExpIdx (int idx)
242 {
243 expIdx = idx;
244 }
245
246 void
247 setUserExpId (int idx)
248 {
249 userExpId = idx;
250 }
251
252 void
253 setTinyThreshold (int limit)
254 {
255 tiny_threshold = limit;
256 }
257
258 bool
259 isDiscardedTinyExperiment ()
260 {
261 return discardTiny;
262 }
263
264 Exp_status open_epilogue ();
265 void read_experiment_data (bool read_ahead);
266 static int copy_file_to_archive (const char *name, const char *aname, int hide_msg);
267 static int copy_file_to_common_archive (const char *name, const char *aname,
268 int hide_msg, const char *common_archive, int relative_path = 0);
269 static int copy_file (char *name, char *aname, int hide_msg,
270 char *common_archive = NULL, int relative_path = 0);
271
272 // get_raw_events()
273 // action: get unfiltered packets, loading them if required
274 // parameters: data_id (see ProfData_type)
275 DataDescriptor *get_raw_events (int data_id);
276 Vector<DataDescriptor*> *getDataDescriptors ();
277
278 // Some DATA_* types are derived from others, e.g. DATA_HEAPSZ is derived from DATA_HEAP
279 // The following hooks support derived DataViews
280 int base_data_id (int data_id); // returns base data_id type (ProfData_type DATA_*)
281 DataView *create_derived_data_view (int data_id, DataView *dview);
282
283 Vector<BaseMetric*>*
284 get_metric_list ()
285 {
286 return metrics;
287 }
288
289 char *
290 get_expt_name ()
291 {
292 return expt_name; // Return the pathname to the experiment
293 };
294
295 Vector<char*> *get_descendants_names ();
296 char *get_fndr_arch_name ();
297 char *get_arch_name ();
298 char *getNameInArchive (const char *fname, bool archiveFile = false);
299 char *checkFileInArchive (const char *fname, bool archiveFile = false);
300 DbeFile *findFileInArchive (const char *className, const char *runTimePath);
301 DbeFile *findFileInArchive (const char *fname);
302 bool create_dir (char *dname);
303
304 Vaddr
305 ret_stack_base ()
306 {
307 return stack_base;
308 };
309
310 // Map a virtual address to a PC pair
311 DbeInstr *map_Vaddr_to_PC (Vaddr addr, hrtime_t ts);
312 DbeInstr *map_jmid_to_PC (Vaddr mid, int lineno, hrtime_t ts);
313 Sample *map_event_to_Sample (hrtime_t ts);
314 GCEvent *map_event_to_GCEvent (hrtime_t ts);
315
316 DataView *
317 getOpenMPdata ()
318 {
319 return openMPdata;
320 }
321
322 time_t
323 get_mtime ()
324 {
325 return mtime;
326 }
327
328 Emsg *fetch_comments (void); // fetch the queue of comment messages
329 Emsg *fetch_runlogq (void); // fetch the queue of run log messages
330 Emsg *fetch_errors (void); // fetch the queue of error messages
331 Emsg *fetch_warnings (void); // fetch the queue of warning messages
332 Emsg *fetch_notes (void); // fetch the queue of notes messages
333 Emsg *fetch_ifreq (void); // fetch the queue of ifreq messages
334 Emsg *fetch_pprocq (void); // fetch the queue of post-processing messages
335
336 // message queues
337 Emsgqueue *commentq; // comments for the experiment header
338 Emsgqueue *runlogq; // used temporarily; after log file processing,
339 // messages are appended to the commentq
340 Emsgqueue *errorq; // error messages
341 Emsgqueue *warnq; // warning messages
342 Emsgqueue *notesq; // user-written notes messages
343 Emsgqueue *pprocq; // postprocessing messages
344 Emsgqueue *ifreqq; // Instruction frequency data, from count experiment
345 Map<const char*, LoadObject*> *loadObjMap;
346 Vector<LoadObject*> *loadObjs;
347 void append (LoadObject *lo);
348 LoadObject *createLoadObject (const char *path, uint64_t chksum = 0);
349 LoadObject *createLoadObject (const char *path, const char *runTimePath);
350 SourceFile *get_source (const char *path);
351 void set_clock (int clk);
352
353 CallStack *
354 callTree ()
355 {
356 return cstack;
357 }
358
359 CallStack *
360 callTreeShowHide ()
361 {
362 return cstackShowHide;
363 }
364
365 uint32_t mapTagValue (Prop_type, uint64_t value);
366 Histable *getTagObj (Prop_type, uint32_t idx);
367 Vector<Histable*> *getTagObjs (Prop_type);
368
369 JThread *map_pckt_to_Jthread (uint32_t tid, hrtime_t tstamp);
370 JThread *get_jthread (uint32_t tid);
371
372 Vector<JThread*> *
373 get_jthreads ()
374 {
375 return jthreads;
376 }
377
378 Vector<GCEvent*> *
379 get_gcevents ()
380 {
381 return gcevents;
382 }
383
384 bool need_swap_endian;
385 Collection_params coll_params; // Collection params
386
387 // Ranges for threads, lwps, cpu
388 uint64_t min_thread;
389 uint64_t max_thread;
390 uint64_t thread_cnt;
391 uint64_t min_lwp;
392 uint64_t max_lwp;
393 uint64_t lwp_cnt;
394 uint64_t min_cpu;
395 uint64_t max_cpu;
396 uint64_t cpu_cnt;
397 uint64_t dsevents; // count of dataspace events
398 uint64_t dsnoxhwcevents; /* count of ds events that could be be validated
399 * because of no branch target info */
400
401 PacketDescriptor *newPacketDescriptor (int kind, DataDescriptor *dDscr);
402 PacketDescriptor *getPacketDescriptor (int kind);
403
404 // debugging aids -- dump_stacks, dump_map
405 void dump_stacks (FILE *);
406 void dump_map (FILE *);
407
408 // These methods are used in nightly performance regression testing
409 void DBG_memuse (Sample *);
410 void DBG_memuse (const char *sname);
411 void init_cache ();
412
413 DefaultMap<int64_t, FileData*> *
414 getFDataMap ()
415 {
416 return fDataMap;
417 }
418 CallStack *cstack;
419
420protected:
421
422 Exp_status status; // Error status
423 Vector<SegMem*> *seg_items; // Master list of seg_items
424 CallStack *cstackShowHide;
425 PRBTree *maps; // All maps in (Vaddr,time)
426
427 hrtime_t gc_duration; // wall-clock hrtime of total GC intervals
428 hrtime_t exp_start_time; // wall-clock hrtime at exp start
429 hrtime_t last_event; // wall-clock hrtime of last known sample or log.xml entry
430 hrtime_t non_paused_time; // sum of periods where data collection is active (not paused)
431 hrtime_t resume_ts; // tracks log.xml start/resume times
432 void update_last_event (hrtime_t ts /*wall time (not 0-based)*/);
433
434 char *expt_name; // name of experiment
435 char *arch_name; // <experiment>/archive
436 char *fndr_arch_name; // <founder_experiment>/archive
ab11c890
VM
437 char *dyntext_name; // <experiment>/dyntext
438
bb368aad
VM
439 int yyparse (); // Allow yyparse actions to access
440 Vaddr stack_base; // Stack base
441
442 // Write experiment header to comment queue
443 void write_header ();
444 void write_coll_params ();
445
446 Exp_status find_expdir (char *directory_name);
447
448 // Invoke the parser to process a file.
449 void read_data_file (const char*, const char*);
450 int read_log_file ();
451 void read_labels_file ();
452 void read_notes_file ();
453 void read_archives ();
454 int read_java_classes_file ();
455 void read_map_file ();
456 int read_overview_file ();
457 int read_dyntext_file ();
458 void read_omp_file ();
459 void read_omp_preg ();
460 void read_omp_task ();
461 void read_ifreq_file ();
462 void read_frameinfo_file ();
463
464 // Functions to process the log and loadobjects file entries
465 // They are deliberately made virtual to overload them
466 // in er_export.
467 virtual int process_arglist_cmd (char *, char *);
468 virtual int process_desc_start_cmd (char *, hrtime_t, char *, char *, int, char *);
469 virtual int process_desc_started_cmd (char *, hrtime_t, char *, char *, int, char *);
470 virtual int process_fn_load_cmd (Module *mod, char *fname, Vaddr vaddr, int fsize, hrtime_t ts);
471 virtual int process_fn_unload_cmd (char *, Vaddr, hrtime_t);
472 virtual int process_hwcounter_cmd (char *, int, char *, char *, int, int, int, char *);
473 virtual int process_hwsimctr_cmd (char *, int, char *, char *, char*, int, int, int, int, int);
474 virtual int process_jcm_load_cmd (char*, Vaddr, Vaddr, int, hrtime_t);
475 virtual int process_jcm_unload_cmd (char*, Vaddr, hrtime_t);
476 virtual int process_Linux_kernel_cmd (hrtime_t);
477 virtual int process_jthr_end_cmd (char *, uint64_t, Vaddr, Vaddr, hrtime_t);
478 virtual int process_jthr_start_cmd (char *, char *, char *, char *, uint64_t, Vaddr, Vaddr, hrtime_t);
479 virtual int process_gc_end_cmd (hrtime_t);
480 virtual int process_gc_start_cmd (hrtime_t);
481 virtual int process_sample_cmd (char *, hrtime_t, int id, char *lbl);
482 virtual int process_sample_sig_cmd (char *, int);
483 virtual int process_seg_map_cmd (char *, hrtime_t, Vaddr, int, int, int64_t, int64_t, int64_t, char *);
484 virtual int process_seg_unmap_cmd (char *, hrtime_t, Vaddr);
485
486 // creation time for experiment
487 time_t mtime;
488 hrtime_t exp_rel_start_time; // start of exp. relative to founder
489 bool exp_rel_start_time_set;
490 Vector<UserLabel*> *userLabels; // List of er_labels
491 int userExpId; // user value for EXPID
492 int expIdx; // DbeSession exp identifier
493 PRBTree *jmaps; // JAVA_CLASSES: (id,time)->Histable
494 Experiment* baseFounder; // outermost experiment (null until lazily computed)
495
496 // Represents a file in experiment
497 class ExperimentFile;
498
499 // XML handler to parse various experiment files
500 class ExperimentHandler;
501 class ExperimentLabelsHandler;
502
503 uint64_t readPacket (Data_window *dwin, Data_window::Span *span);
504 void readPacket (Data_window *dwin, char *ptr, PacketDescriptor *pDscr,
505 DataDescriptor *dDscr, int arg, uint64_t pktsz);
506
507 // read data
508 DataDescriptor *get_profile_events ();
509 DataDescriptor *get_sync_events ();
510 DataDescriptor *get_hwc_events ();
511 DataDescriptor *get_heap_events ();
512 DataDescriptor *get_heapsz_events ();
513 DataDescriptor *get_iotrace_events ();
514 DataDescriptor *get_race_events ();
515 DataDescriptor *get_deadlock_events ();
516 DataDescriptor *get_sample_events ();
517 DataDescriptor *get_gc_events ();
518 DataDescriptor *getDataDescriptor (int data_id);
519 DataDescriptor *newDataDescriptor (int data_id, int flags = 0,
520 DataDescriptor *master_dDscr = NULL);
521
522 // Frame info data structures and methods
523 struct UIDnode;
524 struct RawFramePacket;
525
526 Vector<RawFramePacket*>*frmpckts; // frame info data
527 static int frUidCmp (const void*, const void*);
528 RawFramePacket *find_frame_packet (uint64_t uid);
529
530 static const int CHUNKSZ = 16384;
531 long nnodes;
532 long nchunks;
533 UIDnode **chunks;
534 UIDnode **uidHTable;
535 Vector<UIDnode*> *uidnodes;
536 bool resolveFrameInfo;
537 bool discardTiny;
538 int tiny_threshold; /* optimize away tiny experiments which ran
539 * for less than specified time (ms): default 0 */
540
541 static int uidNodeCmp (const void *a, const void *b);
542 UIDnode *add_uid (Data_window *dwin, uint64_t uid, int size, uint32_t *array, uint64_t link_uid);
543 UIDnode *add_uid (Data_window *dwin, uint64_t uid, int size, uint64_t *array, uint64_t link_uid);
544 UIDnode *new_uid_node (uint64_t uid, uint64_t val);
545 UIDnode *get_uid_node (uint64_t uid, uint64_t val);
546 UIDnode *get_uid_node (uint64_t uid);
547 UIDnode *find_uid_node (uint64_t uid);
548
549 ExperimentFile *logFile;
550
551 // Data descriptors
552 Vector<DataDescriptor*> *dataDscrs;
553 Vector<PacketDescriptor*> *pcktDscrs;
554 long blksz; // binary data file block size
555
556 // Processed data packets
557 DataView *openMPdata; // OMP fork events
558
559 // Map events to OpenMP parallel regions and tasks
560 Map2D<uint32_t, hrtime_t, uint64_t> *mapPRid;
561 Map2D<uint32_t, hrtime_t, void*> *mapPReg;
562 Map2D<uint32_t, hrtime_t, void*> *mapTask;
563
564 // Archive content
565 Map<const char*, DbeFile *> *archiveMap;
566 Map<const char*, SourceFile*>*sourcesMap;
567
568 void init ();
569 void fini ();
570 void post_process ();
571 void constructJavaStack (FramePacket *, UIDnode *, Map<uint64_t, uint64_t> *);
572 void resolve_frame_info (DataDescriptor*);
573 void cleanup_cstk_ctx_chunk ();
574 void register_metric (Metric::Type type);
575 void register_metric (Hwcentry *ctr, const char* aux, const char* username);
576
577 Sample *sample_last_used;
578 GCEvent *gcevent_last_used;
579 char *first_sample_label;
580 Module *get_jclass (const char *className, const char *fileName);
581 LoadObject *get_j_lo (const char *className, const char *fileName);
582
583 Vector<BaseMetric*> *metrics;
584 Vector<JThread*> *jthreads; // master list of Java threads
585 Vector<JThread*> *jthreads_idx; // index in the master list
586 Vector<GCEvent*> *gcevents;
587 Vector<UnmapChunk*> *heapUnmapEvents;
588 Vector<Sample*> *samples; // Array of Sample pointers
589
590 DefaultMap<int64_t, FileData*> *fDataMap; // list of FileData objects using the virtual File descriptor as the key
591 DefaultMap<int, int64_t> *vFdMap; // list of virtual file descrptors using the file descriptor as the key
592
593 Vector<Vector<Histable*>*> *tagObjs; // tag objects
594 bool sparse_threads;
595
596 SegMem **smemHTable; // hash table for SegMem's
597 DbeInstr **instHTable; // hash table for DbeInstr
598 Map<unsigned long long, JMethod*> *jmidHTable; // hash table for jmid
599
600 // identity of target process
601 int pid;
602 int ppid;
603 int pgrp;
604 int sid;
605
606 // Map file processing related data
607 struct MapRecord
608 {
609
610 enum
611 {
612 LOAD, UNLOAD
613 } kind;
614 Histable *obj;
615 Vaddr base;
616 Size size;
617 hrtime_t ts;
618 uint64_t foff;
619 };
620
621 void mrec_insert (MapRecord *mrec);
622 SegMem *update_ts_in_maps (Vaddr addr, hrtime_t ts);
623 int read_warn_file ();
624 LoadObject *get_dynfunc_lo (const char *loName);
625 Function *create_dynfunc (Module *mod, char *fname, int64_t vaddr, int64_t fsize);
626 char *get_archived_name (const char *fname, bool archiveFile = false);
627
628 Vector<MapRecord*> *mrecs;
629
630private:
631 void add_evt_time_to_profile_events (DataDescriptor *dDscr);
632 DataView *create_heapsz_data_view (DataView *heap_dview);
633 void compute_heapsz_data_view (DataView *heapsz_dview);
634};
635
636struct JThread
637{
638 JThread *next;
639 char *name;
640 char *group_name;
641 char *parent_name;
642 uint32_t tid; // system thread id
643 Vaddr jthr; // recorded Java thread id
644 Vaddr jenv; // recorded JNIEnv id
645 uint32_t jthr_id; // internal JThread object id
646 hrtime_t start;
647 hrtime_t end;
648
649 JThread ()
650 {
651 name = NULL;
652 group_name = NULL;
653 parent_name = NULL;
654 }
655
656 ~JThread ()
657 {
658 free (name);
659 free (group_name);
660 free (parent_name);
661 }
662 bool is_system ();
663};
664
665struct GCEvent
666{
667
668 GCEvent ()
669 {
670 id = -1;
671 }
672
673 ~GCEvent () { }
674
675 hrtime_t start;
676 hrtime_t end;
677 int id;
678};
679
680class ExperimentLoadCancelException
681{
682public:
683
684 ExperimentLoadCancelException () { };
685
686 ~ExperimentLoadCancelException () { };
687};
688
689
690#endif /* _EEXPERIMENT_H */