SST  11.1.0
StructuralSimulationToolkit
link.h
1 // Copyright 2009-2021 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-2021, 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_LINK_H
13 #define SST_CORE_LINK_H
14 
15 #include "sst/core/event.h"
16 #include "sst/core/sst_types.h"
17 #include "sst/core/timeConverter.h"
18 
19 namespace SST {
20 
21 #define _LINK_DBG(fmt, args...) __DBG(DBG_LINK, Link, fmt, ##args)
22 
23 class TimeConverter;
24 class LinkPair;
25 class Simulation_impl;
26 class ActivityQueue;
27 
28 class UnitAlgebra;
29 
30 /** Link between two components. Carries events */
31 class alignas(64) Link
32 {
33  enum Type_t : uint16_t { POLL, HANDLER, SYNC, UNINITIALIZED };
34  enum Mode_t : uint16_t { INIT, RUN, COMPLETE };
35 
36 public:
37  friend class LinkPair;
38  friend class RankSync;
39  friend class ThreadSync;
40  friend class Simulation_impl;
41  friend class SyncManager;
42  friend class ComponentInfo;
43 
44  /** Create a new link with a given ID */
45 #if !SST_BUILDING_CORE
46  Link(LinkId_t id) __attribute__((
47  deprecated("this function was not intended to be used outside of SST core and will be removed in SST 12.")));
48 #else
49  Link(LinkId_t id);
50 #endif
51 
52  virtual ~Link();
53 
54  /** Set additional Latency to be added to events being sent out of this link
55  * @param cycles Number of Cycles to be added
56  * @param timebase Base Units of cycles
57  */
58  void addSendLatency(int cycles, const std::string& timebase);
59 
60  /** Set additional Latency to be added to events being sent out of this link
61  * @param cycles Number of Cycles to be added
62  * @param timebase Base Units of cycles
63  */
64  void addSendLatency(SimTime_t cycles, TimeConverter* timebase);
65 
66  /** Set additional Latency to be added on to events coming in on this link.
67  * @param cycles Number of Cycles to be added
68  * @param timebase Base Units of cycles
69  */
70  void addRecvLatency(int cycles, const std::string& timebase);
71 
72  /** Set additional Latency to be added on to events coming in on this link.
73  * @param cycles Number of Cycles to be added
74  * @param timebase Base Units of cycles
75  */
76  void addRecvLatency(SimTime_t cycles, TimeConverter* timebase);
77 
78  /** Set the callback function to be called when a message is
79  * delivered. Not available for Polling links.
80  * @param functor Functor to call when message is delivered
81  */
82  void setFunctor(Event::HandlerBase* functor);
83 
84  /** Replace the callback function to be called when a message is
85  * delivered. Any previous handler will be deleted.
86  * Not available for Polling links.
87  * @param functor Functor to call when message is delivered
88  */
89  void replaceFunctor(Event::HandlerBase* functor);
90 
91  /** Specifies that this link has no callback, and is poll-based only */
92 #if !SST_BUILDING_CORE
93  void setPolling() __attribute__((
94  deprecated("this function was not intended to be used outside of SST core and will be removed in SST 12.")));
95 #else
96  void setPolling();
97 #endif
98 
99  /** Send an event over the link with additional delay. Sends an event
100  * over a link with an additional delay specified with a
101  * TimeConverter. I.e. the total delay is the link's delay + the
102  * additional specified delay.
103  * @param delay - additional delay
104  * @param tc - time converter to specify units for the additional delay
105  * @param event - the Event to send
106  */
107  inline void send(SimTime_t delay, TimeConverter* tc, Event* event)
108  {
109  send_impl(tc->convertToCoreTime(delay), event);
110  }
111 
112  /** Send an event with additional delay. Sends an event over a link
113  * with additional delay specified by the Link's default
114  * timebase.
115  * @param delay The additional delay, in units of the default Link timebase
116  * @param event The event to send
117  */
118  inline void send(SimTime_t delay, Event* event) { send_impl(delay * defaultTimeBase, event); }
119 
120  /** Send an event with the Link's default delay
121  * @param event The event to send
122  */
123  inline void send(Event* event) { send_impl(0, event); }
124 
125 
126  /** Retrieve a pending event from the Link. For links which do not
127  * have a set event handler, they can be polled with this function.
128  * Returns nullptr if there is no pending event.
129  * Not available for HANDLER-type links.
130  * @return Event if one is available
131  * @return nullptr if no Event is available
132  */
133  Event* recv();
134 
135  /** Manually set the default detaulTimeBase
136  * @param tc TimeConverter object for the timebase
137  */
139 
140  /** Return the default Time Base for this link
141  * @return the default Time Base for this link
142  */
144 
145  /** Return the default Time Base for this link
146  * @return the default Time Base for this link
147  */
148  const TimeConverter* getDefaultTimeBase() const;
149 
150  /** Causes an event to be delivered to the registered callback */
151 #if !SST_BUILDING_CORE
152  inline void deliverEvent(Event* event) const __attribute__((
153  deprecated("this function was not intended to be used outside of SST core and will be removed in SST 12.")))
154  {
155 #else
156  inline void deliverEvent(Event* event) const
157  {
158 #endif
159  (*pair_rFunctor)(event);
160  }
161 
162  /** Return the ID of this link
163  * @return the unique ID for this link
164  */
165  LinkId_t getId() { return id; }
166 
167  /** Send data during the init() or complete() phase.
168  * @param data event to send
169  */
170  void sendUntimedData(Event* data);
171 
172  /** Receive an event (if any) during the init() or complete() phase.
173  * @return Event if one is available
174  * @return nullptr if no Event is available
175  */
177 
178  /** Send data during the init() or complete() phase.
179  * Same as sendUntimedData()
180  * @param init_data data to send
181  */
182  void sendInitData(Event* init_data) { sendUntimedData(init_data); }
183 
184  /** Receive an event (if any) during the init() or complete() phase.
185  * Same as recvUntimedData()
186  * @return Event if one is available
187  * @return nullptr if no Event is available
188  */
190 
191  /** Return whether link has been configured
192  * @return whether link is configured
193  */
194  bool isConfigured() { return type != UNINITIALIZED; }
195 
196 #ifdef __SST_DEBUG_EVENT_TRACKING__
197  void setSendingComponentInfo(const std::string& comp_in, const std::string& type_in, const std::string& port_in)
198  {
199  comp = comp_in;
200  ctype = type_in;
201  port = port_in;
202  }
203 
204  const std::string& getSendingComponentName() { return comp; }
205  const std::string& getSendingComponentType() { return ctype; }
206  const std::string& getSendingPort() { return port; }
207 
208 #endif
209 
210 protected:
211  Link();
212 
213  void setAsSyncLink() { type = SYNC; }
214 
215  /** Send an event over the link with additional delay. Sends an event
216  * over a link with an additional delay specified with a
217  * TimeConverter. I.e. the total delay is the link's delay + the
218  * additional specified delay.
219  * @param delay - additional total delay to add
220  * @param event - the Event to send
221  */
222  void send_impl(SimTime_t delay, Event* event);
223 
224  // Since Links are found in pairs, I will keep all the information
225  // needed for me to send and deliver an event to the other side of
226  // the link. That means, that I mostly keep my pair's
227  // information. The one consequence, is that polling links will
228  // have to pull the data from the pair, but since this is a less
229  // common case, that's okay (this decision makes the common case
230  // faster and the less common case slower).
231 
232  /** Queue of events to be received by the owning component */
234 
235  /** Receive functor. This functor is set when the link is connected.
236  Determines what the receiver wants to be called
237  */
239 
240  /** Timebase used if no other timebase is specified. Used to specify
241  the units for added delays when sending, such as in
242  Link::send(). Often set by the Component::registerClock()
243  function if the regAll argument is true.
244  */
245  SimTime_t defaultTimeBase;
246 
247  /** Latency of the link. It is used by the partitioner as the
248  weight. This latency is added to the delay put on the event by
249  the component.
250  */
251  SimTime_t latency;
252 
253  /** Pointer to the opposite side of this link */
255 
256 private:
257  SimTime_t& current_time;
258  Type_t type;
259  Mode_t mode;
260  LinkId_t id;
261 
262  Link(const Link& l);
263 
264  /** Set minimum link latency */
265  void setLatency(Cycle_t lat);
266 
267  void sendUntimedData_sync(Event* data);
268  void finalizeConfiguration();
269  void prepareForComplete();
270 
271 
272 #ifdef __SST_DEBUG_EVENT_TRACKING__
273  std::string comp;
274  std::string ctype;
275  std::string port;
276 #endif
277 };
278 
279 /** Self Links are links from a component to itself */
280 class SelfLink : public Link
281 {
282 public:
283  SelfLink() : Link()
284  {
285  pair_link = this;
286  latency = 0;
287  }
288 };
289 
290 } // namespace SST
291 
292 #endif // SST_CORE_LINK_H
Definition: syncManager.h:102
Definition: ssthandler.h:100
A class to convert between a component's view of time and the core's view of time.
Definition: timeConverter.h:26
Definition: syncManager.h:32
SimTime_t convertToCoreTime(SimTime_t time) const
Converts from the component's view to the core's view of time.
Definition: timeConverter.h:36
Definition: syncManager.h:67
Main control class for a SST Simulation.
Definition: simulation_impl.h:74
Defines a pair of links (to define a connected link)
Definition: linkPair.h:23
Definition: componentInfo.h:39
Base Class for a queue of Activities.
Definition: activityQueue.h:21
Base class for Events - Items sent across links to communicate between components.
Definition: event.h:31