SST  13.0.0
StructuralSimulationToolkit
ssthandler.h
1 // Copyright 2009-2023 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-2023, 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 
18 namespace SST {
19 
20 class 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 {
29 public:
30  virtual ~HandlerMetaData() {}
31 };
32 
33 // Base class for Profile tools for Handlers
35 {
36 public:
37  // Register with ELI as base API
38  SST_ELI_REGISTER_PROFILETOOL_API(SST::HandlerProfileToolAPI, Params&)
39 
40 protected:
41  HandlerProfileToolAPI(const std::string& name) : Profile::ProfileTool(name) {}
43 
44 public:
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 {
91 protected:
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 
133 public:
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
169 template <typename returnT, typename argT>
171 {
172  // Implementation of operator() to be done in child classes
173  virtual returnT operator_impl(argT) = 0;
174 
175 public:
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 
193 template <typename argT>
194 class SSTHandlerBase<void, argT> : public SSTHandlerBaseProfile
195 {
196  // Implementation of operator() to be done in child classes
197  virtual void operator_impl(argT) = 0;
198 
199 public:
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  */
218 template <typename returnT, typename argT, typename classT, typename dataT = void>
219 class SSTHandler : public SSTHandlerBase<returnT, argT>
220 {
221 private:
222  typedef returnT (classT::*PtrMember)(argT, dataT);
223  classT* object;
224  const PtrMember member;
225  dataT data;
226 
227 public:
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  */
247 template <typename returnT, typename argT, typename classT>
248 class SSTHandler<returnT, argT, classT, void> : public SSTHandlerBase<returnT, argT>
249 {
250 private:
251  typedef returnT (classT::*PtrMember)(argT);
252  const PtrMember member;
253  classT* object;
254 
255 public:
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
268 template <typename returnT>
270 {
271 
272 protected:
273  virtual returnT operator_impl() = 0;
274 
275 public:
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 
293 template <>
295 {
296 
297 protected:
298  virtual void operator_impl() = 0;
299 
300 public:
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  */
321 template <typename returnT, typename classT, typename dataT = void>
322 class SSTHandlerNoArgs : public SSTHandlerBaseNoArgs<returnT>
323 {
324 private:
325  typedef returnT (classT::*PtrMember)(dataT);
326  classT* object;
327  const PtrMember member;
328  dataT data;
329 
330 public:
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  */
350 template <typename returnT, typename classT>
351 class SSTHandlerNoArgs<returnT, classT, void> : public SSTHandlerBaseNoArgs<returnT>
352 {
353 private:
354  typedef returnT (classT::*PtrMember)();
355  const PtrMember member;
356  classT* object;
357 
358 public:
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
Handlers with 1 handler defined argument to callback from caller.
Definition: ssthandler.h:170
Handler class with user-data argument.
Definition: ssthandler.h:219
HandlerId_t getId()
Get the ID for this Handler.
Definition: ssthandler.h:160
Definition: action.cc:18
ProfileTool is a class loadable through the factory which allows dynamic addition of profiling capabi...
Definition: profiletool.h:29
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
Handlers with no arguments to callback from caller.
Definition: ssthandler.h:269
virtual ~SSTHandlerBaseNoArgs()
Handler function.
Definition: ssthandler.h:304
Just a tag class for the various metadata that will need to be stored in the simulation object to all...
Definition: ssthandler.h:27
Definition: ssthandler.h:34
Event Handler class with user-data argument.
Definition: ssthandler.h:322
Parameter store.
Definition: params.h:55
SSTHandlerNoArgs(classT *const object, PtrMember member, dataT data)
Constructor.
Definition: ssthandler.h:336
Functor classes for Event handling.
Definition: ssthandler.h:89
SSTHandler(classT *const object, PtrMember member, dataT data)
Constructor.
Definition: ssthandler.h:233
SSTHandler(classT *const object, PtrMember member)
Constructor.
Definition: ssthandler.h:260
SSTHandlerNoArgs(classT *const object, PtrMember member)
Constructor.
Definition: ssthandler.h:363
virtual ~SSTHandlerBaseNoArgs()
Handler function.
Definition: ssthandler.h:279