SST 12.1.0
Structural Simulation Toolkit
ssthandler.h
1// Copyright 2009-2022 NTESS. Under the terms
2// of Contract DE-NA0003525 with NTESS, the U.S.
3// Government retains certain rights in this software.
4//
5// Copyright (c) 2009-2022, NTESS
6// All rights reserved.
7//
8// This file is part of the SST software package. For license
9// information, see the LICENSE file in the top level directory of the
10// distribution.
11
12#ifndef SST_CORE_SSTHANDLER_H
13#define SST_CORE_SSTHANDLER_H
14
15#include "sst/core/profile/profiletool.h"
16#include "sst/core/sst_types.h"
17
18namespace SST {
19
20class Params;
21
22/**
23 Just a tag class for the various metadata that will need to be
24 stored in the simulation object to allow ProfileTools to get the
25 data they need.
26 */
28{
29public:
30 virtual ~HandlerMetaData() {}
31};
32
33// Base class for Profile tools for Handlers
35{
36public:
37 // Register with ELI as base API
38 SST_ELI_REGISTER_PROFILETOOL_API(SST::HandlerProfileToolAPI, Params&)
39
40protected:
41 HandlerProfileToolAPI(const std::string& name) : Profile::ProfileTool(name) {}
43
44public:
45 virtual uintptr_t registerHandler(const HandlerMetaData& mdata) = 0;
46
47 virtual void handlerStart(uintptr_t UNUSED(key)) {}
48 virtual void handlerEnd(uintptr_t UNUSED(key)) {}
49};
50
51// This file contains base classes for use as various handlers (object
52// encapsulating callback functions) in SST. The classes expect to
53// encapsulate a pointer to an object and a pointer to a member
54// function of the objects class. The classes also allow you to
55// optionally add one additional piece of static data to be passed
56// into the callback function along with any data provided by the
57// caller. There are two versions of this class, one that has no data
58// passed from the caller (ending with SSTHandlerNoArgs), and one that has
59// a single item passed from the caller (SSTHandler).
60
61// These classes provide the full functionality of the handlers and
62// can be added to a class with the "using" keyword, as follows (a
63// class can use any type name they'd like in place of HandlerBase and
64// Handler, though those names are preferred for consistency):
65
66// using HandlerBase = SSTHandlerBase<return_type_of_callback, arg_type_of_callback>;
67
68// template <typename classT, typename dataT = void>
69// using Handler = SSTHandler<return_type_of_callback, arg_type_of_callback, classT, dataT>;
70
71// Or:
72
73// using HandlerBase = SSTHandlerBaseNoArgs<return_type_of_callback>;
74
75// template <return_type_of_callback, typename classT, typename dataT = void>
76// using Handler = SSTHandlerNoArgs<return_type_of_callback, classT, dataT>;
77
78// The handlers are then instanced as follows:
79
80// new Class::Handler<Class>(this, &Class::callback_function)
81
82// Or:
83
84// new Class::Handler<Class,int>(this, &Class::callback_function, 1)
85
86
87/// Functor classes for Event handling
88
90{
91protected:
92 // This class will hold the id for the handler and the profiling
93 // tools attached to it, if profiling is enabled for this handler.
95 {
96 static std::atomic<HandlerId_t> id_counter;
97 HandlerId_t my_id;
98
99 public:
101
102 void handlerStart()
103 {
104 for ( auto& x : tools )
105 x.first->handlerStart(x.second);
106 }
107 void handlerEnd()
108 {
109 for ( auto& x : tools )
110 x.first->handlerEnd(x.second);
111 }
112
113 /**
114 Adds a profile tool the the list and registers this handler
115 with the profile tool
116 */
118 {
119 auto key = tool->registerHandler(mdata);
120 tools.push_back(std::make_pair(tool, key));
121 }
122
123 HandlerId_t getId() { return my_id; }
124
125 private:
126 std::vector<std::pair<HandlerProfileToolAPI*, uintptr_t>> tools;
127 };
128
129 // List of profiling tools attached to this handler
130 HandlerProfileToolList* profile_tools;
131
132
133public:
134 SSTHandlerBaseProfile() : profile_tools(nullptr) {}
135
136 virtual ~SSTHandlerBaseProfile()
137 {
138 if ( profile_tools ) delete profile_tools;
139 }
140
141 void addProfileTool(HandlerProfileToolAPI* tool, const HandlerMetaData& mdata)
142 {
143 if ( !profile_tools ) profile_tools = new HandlerProfileToolList();
144 profile_tools->addProfileTool(tool, mdata);
145 }
146
147 void transferProfilingInfo(SSTHandlerBaseProfile* handler)
148 {
149 if ( handler->profile_tools ) {
150 profile_tools = handler->profile_tools;
151 handler->profile_tools = nullptr;
152 }
153 }
154
155 /**
156 Get the ID for this Handler. Handler IDs are only used for
157 profiling, so if this function is called, it will also set
158 things up to accept ProfileTools.
159 */
160 HandlerId_t getId()
161 {
162 if ( !profile_tools ) profile_tools = new HandlerProfileToolList();
163 return profile_tools->getId();
164 }
165};
166
167
168/// Handlers with 1 handler defined argument to callback from caller
169template <typename returnT, typename argT>
171{
172 // Implementation of operator() to be done in child classes
173 virtual returnT operator_impl(argT) = 0;
174
175public:
176 ~SSTHandlerBase() {}
177
178 inline returnT operator()(argT arg)
179 {
180 if ( profile_tools ) {
181 // NotifyGuard guard(profile_tools);
182 // return operator_impl(arg);
183 profile_tools->handlerStart();
184 auto ret = operator_impl(arg);
185 profile_tools->handlerEnd();
186 return ret;
187 }
188 return operator_impl(arg);
189 }
190};
191
192
193template <typename argT>
194class SSTHandlerBase<void, argT> : public SSTHandlerBaseProfile
195{
196 // Implementation of operator() to be done in child classes
197 virtual void operator_impl(argT) = 0;
198
199public:
200 ~SSTHandlerBase() {}
201
202 inline void operator()(argT arg)
203 {
204 if ( profile_tools ) {
205 profile_tools->handlerStart();
206 operator_impl(arg);
207 profile_tools->handlerEnd();
208 return;
209 }
210 operator_impl(arg);
211 }
212};
213
214
215/**
216 * Handler class with user-data argument
217 */
218template <typename returnT, typename argT, typename classT, typename dataT = void>
219class SSTHandler : public SSTHandlerBase<returnT, argT>
220{
221private:
222 typedef returnT (classT::*PtrMember)(argT, dataT);
223 classT* object;
224 const PtrMember member;
225 dataT data;
226
227public:
228 /** Constructor
229 * @param object - Pointer to Object upon which to call the handler
230 * @param member - Member function to call as the handler
231 * @param data - Additional argument to pass to handler
232 */
233 SSTHandler(classT* const object, PtrMember member, dataT data) :
234 SSTHandlerBase<returnT, argT>(),
235 object(object),
236 member(member),
237 data(data)
238 {}
239
240 returnT operator_impl(argT arg) override { return (object->*member)(arg, data); }
241};
242
243
244/**
245 * Event Handler class with no user-data.
246 */
247template <typename returnT, typename argT, typename classT>
248class SSTHandler<returnT, argT, classT, void> : public SSTHandlerBase<returnT, argT>
249{
250private:
251 typedef returnT (classT::*PtrMember)(argT);
252 const PtrMember member;
253 classT* object;
254
255public:
256 /** Constructor
257 * @param object - Pointer to Object upon which to call the handler
258 * @param member - Member function to call as the handler
259 */
260 SSTHandler(classT* const object, PtrMember member) : SSTHandlerBase<returnT, argT>(), member(member), object(object)
261 {}
262
263 returnT operator_impl(argT arg) override { return (object->*member)(arg); }
264};
265
266
267/// Handlers with no arguments to callback from caller
268template <typename returnT>
270{
271
272protected:
273 virtual returnT operator_impl() = 0;
274
275public:
277
278 /** Handler function */
280
281 inline returnT operator()()
282 {
283 if ( profile_tools ) {
284 profile_tools->handlerStart();
285 auto ret = operator_impl();
286 profile_tools->handlerEnd();
287 return ret;
288 }
289 return operator_impl();
290 }
291};
292
293template <>
295{
296
297protected:
298 virtual void operator_impl() = 0;
299
300public:
302
303 /** Handler function */
305
306 inline void operator()()
307 {
308 if ( profile_tools ) {
309 profile_tools->handlerStart();
310 operator_impl();
311 profile_tools->handlerEnd();
312 return;
313 }
314 return operator_impl();
315 }
316};
317
318/**
319 * Event Handler class with user-data argument
320 */
321template <typename returnT, typename classT, typename dataT = void>
323{
324private:
325 typedef returnT (classT::*PtrMember)(dataT);
326 classT* object;
327 const PtrMember member;
328 dataT data;
329
330public:
331 /** Constructor
332 * @param object - Pointer to Object upon which to call the handler
333 * @param member - Member function to call as the handler
334 * @param data - Additional argument to pass to handler
335 */
336 SSTHandlerNoArgs(classT* const object, PtrMember member, dataT data) :
337 SSTHandlerBaseNoArgs<returnT>(),
338 object(object),
339 member(member),
340 data(data)
341 {}
342
343 void operator_impl() override { return (object->*member)(data); }
344};
345
346
347/**
348 * Event Handler class with no user-data.
349 */
350template <typename returnT, typename classT>
351class SSTHandlerNoArgs<returnT, classT, void> : public SSTHandlerBaseNoArgs<returnT>
352{
353private:
354 typedef returnT (classT::*PtrMember)();
355 const PtrMember member;
356 classT* object;
357
358public:
359 /** Constructor
360 * @param object - Pointer to Object upon which to call the handler
361 * @param member - Member function to call as the handler
362 */
363 SSTHandlerNoArgs(classT* const object, PtrMember member) :
364 SSTHandlerBaseNoArgs<returnT>(),
365 member(member),
366 object(object)
367 {}
368
369 void operator_impl() override { return (object->*member)(); }
370};
371
372} // namespace SST
373
374#endif // SST_CORE_SSTHANDLER_H
Just a tag class for the various metadata that will need to be stored in the simulation object to all...
Definition: ssthandler.h:28
Definition: ssthandler.h:35
Parameter store.
Definition: params.h:56
ProfileTool is a class loadable through the factory which allows dynamic addition of profiling capabi...
Definition: profiletool.h:30
virtual ~SSTHandlerBaseNoArgs()
Handler function.
Definition: ssthandler.h:304
Handlers with no arguments to callback from caller.
Definition: ssthandler.h:270
virtual ~SSTHandlerBaseNoArgs()
Handler function.
Definition: ssthandler.h:279
void addProfileTool(HandlerProfileToolAPI *tool, const HandlerMetaData &mdata)
Adds a profile tool the the list and registers this handler with the profile tool.
Definition: ssthandler.h:117
Functor classes for Event handling.
Definition: ssthandler.h:90
HandlerId_t getId()
Get the ID for this Handler.
Definition: ssthandler.h:160
Handlers with 1 handler defined argument to callback from caller.
Definition: ssthandler.h:171
SSTHandlerNoArgs(classT *const object, PtrMember member)
Constructor.
Definition: ssthandler.h:363
Event Handler class with user-data argument.
Definition: ssthandler.h:323
SSTHandlerNoArgs(classT *const object, PtrMember member, dataT data)
Constructor.
Definition: ssthandler.h:336
SSTHandler(classT *const object, PtrMember member)
Constructor.
Definition: ssthandler.h:260
Handler class with user-data argument.
Definition: ssthandler.h:220
SSTHandler(classT *const object, PtrMember member, dataT data)
Constructor.
Definition: ssthandler.h:233