Line data Source code
1 : //
2 : // MIDAS analyzer example 3: C++ flow analyzer
3 : //
4 : // K.Olchanski
5 : //
6 :
7 : #include <stdio.h>
8 :
9 : #include "manalyzer.h"
10 : #include "midasio.h"
11 :
12 : class Object1 : public TAFlowEvent
13 : {
14 : public:
15 : int fIntValue = 0;
16 :
17 0 : Object1(TAFlowEvent* flow, int value)
18 0 : : TAFlowEvent(flow)
19 : {
20 0 : fIntValue = value;
21 : }
22 : };
23 :
24 : class Object2 : public TAFlowEvent
25 : {
26 : public:
27 : std::string fStringValue;
28 :
29 0 : Object2(TAFlowEvent* flow, const std::string& stringValue)
30 0 : : TAFlowEvent(flow)
31 : {
32 0 : fStringValue = stringValue;
33 0 : }
34 : };
35 :
36 : class Object3 : public TAFlowEvent
37 : {
38 : public:
39 : double* fPtrValue = NULL;
40 :
41 0 : Object3(TAFlowEvent* flow, double* doublePtr)
42 0 : : TAFlowEvent(flow)
43 : {
44 0 : fPtrValue = doublePtr;
45 : }
46 :
47 0 : ~Object3() // dtor
48 0 : {
49 0 : if (fPtrValue) {
50 0 : delete fPtrValue;
51 0 : fPtrValue = NULL;
52 : }
53 0 : }
54 : };
55 :
56 : class Example1: public TARunObject
57 : {
58 : public:
59 0 : Example1(TARunInfo* runinfo)
60 0 : : TARunObject(runinfo)
61 : {
62 0 : printf("Example1::ctor, run %d, file %s\n", runinfo->fRunNo, runinfo->fFileName.c_str());
63 0 : fModuleName = "Example1";
64 0 : fModuleOrder = 1;
65 0 : }
66 :
67 0 : ~Example1()
68 0 : {
69 0 : printf("Example1::dtor!\n");
70 0 : }
71 :
72 0 : TAFlowEvent* Analyze(TARunInfo* runinfo, TMEvent* event, TAFlags* flags, TAFlowEvent* flow)
73 : {
74 0 : printf("Example1::Analyze, run %d, event serno %d, id 0x%04x, data size %d\n", runinfo->fRunNo, event->serial_number, (int)event->event_id, event->data_size);
75 :
76 0 : flow = new Object1(flow, 10);
77 0 : flow = new Object2(flow, "some text");
78 :
79 0 : return flow;
80 : }
81 :
82 0 : TAFlowEvent* AnalyzeFlowEvent(TARunInfo* runinfo, TAFlags* flags, TAFlowEvent* flow)
83 : {
84 : // This function doesn't analyze anything, so we use flags
85 : // to have the profiler ignore it
86 0 : *flags |= TAFlag_SKIP_PROFILE;
87 0 : return flow;
88 : }
89 : };
90 :
91 : class Example2: public TARunObject
92 : {
93 : public:
94 0 : Example2(TARunInfo* runinfo)
95 0 : : TARunObject(runinfo)
96 : {
97 0 : printf("Example2::ctor, run %d, file %s\n", runinfo->fRunNo, runinfo->fFileName.c_str());
98 0 : fModuleName = "Example2";
99 0 : fModuleOrder = 2;
100 0 : }
101 :
102 0 : ~Example2()
103 0 : {
104 0 : printf("Example2::dtor!\n");
105 0 : }
106 :
107 0 : void PreEndRun(TARunInfo* runinfo)
108 : {
109 0 : TAFlowEvent* flow = NULL;
110 :
111 0 : printf("Example2::PreEndRun, run %d\n", runinfo->fRunNo);
112 :
113 0 : double *dptr = new double;
114 0 : *dptr = 17.1;
115 :
116 0 : flow = new Object3(flow, dptr);
117 :
118 0 : runinfo->AddToFlowQueue(flow);
119 0 : }
120 :
121 0 : TAFlowEvent* Analyze(TARunInfo* runinfo, TMEvent* event, TAFlags* flags, TAFlowEvent* flow)
122 : {
123 0 : printf("Example2::Analyze, run %d, event serno %d, id 0x%04x, data size %d\n", runinfo->fRunNo, event->serial_number, (int)event->event_id, event->data_size);
124 :
125 0 : double *dptr = new double;
126 0 : *dptr = 3.14;
127 :
128 0 : flow = new Object3(flow, dptr);
129 :
130 0 : return flow;
131 : }
132 :
133 0 : TAFlowEvent* AnalyzeFlowEvent(TARunInfo* runinfo, TAFlags* flags, TAFlowEvent* flow)
134 : {
135 0 : printf("Example2::AnalyzeFlowEvent, run %d\n", runinfo->fRunNo);
136 :
137 : // example iterating over flow events
138 :
139 0 : if (flow) {
140 : TAFlowEvent* f = flow;
141 0 : while (f) {
142 0 : Object1* o1 = dynamic_cast<Object1*>(f);
143 0 : Object2* o2 = dynamic_cast<Object2*>(f);
144 0 : Object3* o3 = dynamic_cast<Object3*>(f);
145 :
146 0 : printf("flow event %p, o1: %p, o2: %p, o3: %p\n", f, o1, o2, o3);
147 :
148 0 : if (o1)
149 0 : printf("object1 int value: %d\n", o1->fIntValue);
150 :
151 0 : if (o2)
152 0 : printf("object2 string value: %s\n", o2->fStringValue.c_str());
153 :
154 0 : if (o3)
155 0 : printf("object3 pointer to double value: %f\n", *o3->fPtrValue);
156 :
157 0 : f = f->fNext;
158 : }
159 : }
160 :
161 : // example of profiling a custom time window
162 0 : TAClock start_time = TAClockNow();
163 :
164 : // example direct get of flow events
165 0 : if (flow) {
166 0 : Object1* o1 = flow->Find<Object1>();
167 0 : Object2* o2 = flow->Find<Object2>();
168 0 : Object3* o3 = flow->Find<Object3>();
169 :
170 0 : if (o1)
171 0 : printf("find object1 int value: %d\n", o1->fIntValue);
172 :
173 0 : if (o2)
174 0 : printf("find object2 string value: %s\n", o2->fStringValue.c_str());
175 :
176 0 : if (o3)
177 0 : printf("find object3 pointer to double value: %f\n", *o3->fPtrValue);
178 : }
179 :
180 0 : flow = new TAUserProfilerFlow(flow, "FindObjects", start_time);
181 :
182 : // example of locking threads to execute code that isnt thread safe across modules
183 : // At time of writing root (v6.16) fitting tools are not thread safe...
184 :
185 0 : if (flow) {
186 0 : Object1* o1 = flow->Find<Object1>();
187 0 : if (o1) {
188 : //Lock while in the scope of these brackets
189 0 : std::lock_guard<std::mutex> lock(runinfo->fMtInfo->gfLock);
190 0 : printf("Do some function here... maybe some fitting function from root that isn't threadsafe\n");
191 0 : }
192 : }
193 :
194 0 : return flow;
195 : }
196 : };
197 :
198 : static TARegister tar1(new TAFactoryTemplate<Example1>);
199 : static TARegister tar2(new TAFactoryTemplate<Example2>);
200 :
201 : /* emacs
202 : * Local Variables:
203 : * tab-width: 8
204 : * c-basic-offset: 3
205 : * indent-tabs-mode: nil
206 : * End:
207 : */
|