SST  13.1.0
Structural Simulation Toolkit
timeVortexBinnedMap.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_IMPL_TIMEVORTEX_TIMEVORTEXBINNEDMAP_H
13 #define SST_CORE_IMPL_TIMEVORTEX_TIMEVORTEXBINNEDMAP_H
14 
15 #include <atomic>
16 #include <queue>
17 #include <sst/core/timeVortex.h>
18 #include <vector>
19 
20 namespace SST {
21 
22 class Output;
23 
24 namespace IMPL {
25 
26 
27 template <typename T>
28 class Pool
29 {
30 
31  std::vector<T*> pool;
32 
33 public:
34  ~Pool()
35  {
36  for ( auto x : pool ) {
37  delete x;
38  }
39  }
40 
41  T* remove()
42  {
43  if ( pool.empty() ) { pool.push_back(new T()); }
44  auto ret = pool.back();
45  pool.pop_back();
46  return ret;
47  }
48 
49  void insert(T* item) { pool.push_back(item); }
50 };
51 
52 /**
53  * Primary Event Queue
54  */
55 template <bool TS>
57 {
58 
59 private:
60  // Class to hold a vector and a delivery time
61  class TimeUnit
62  {
63  private:
64  SimTime_t sort_time;
65  std::vector<Activity*> activities;
66  bool sorted;
67 
68  CACHE_ALIGNED(SST::Core::ThreadSafe::Spinlock, tu_lock);
69 
70  public:
71  // Create with initial event
72  TimeUnit() : sorted(false) {}
73 
74  ~TimeUnit()
75  {
76  for ( auto x : activities ) {
77  delete x;
78  }
79  }
80 
81  inline SimTime_t getSortTime() { return sort_time; }
82  inline void setSortTime(SimTime_t time) { sort_time = time; }
83 
84 
85  // Inserts can happen by multiple threads
86  void insert(Activity* act)
87  {
88  if ( TS ) tu_lock.lock();
89  activities.push_back(act);
90  sorted = false;
91  if ( TS ) tu_lock.unlock();
92  }
93 
94  // pop only happens by one thread
95  Activity* pop()
96  {
97  if ( 0 == activities.size() ) return nullptr;
98  if ( !sorted ) sort();
99  auto ret = activities.back();
100  activities.pop_back();
101  return ret;
102  }
103 
104  // front only happens by one thread
105  Activity* front()
106  {
107  if ( 0 == activities.size() ) return nullptr;
108  if ( !sorted ) sort();
109  return activities.back();
110  }
111 
112  void sort();
113 
114  inline bool operator<(const TimeUnit& rhs) { return this->sort_time < rhs.sort_time; }
115 
116  /** To use with STL priority queues, that order in reverse. */
117  class pq_less
118  {
119  public:
120  /** Compare pointers */
121  inline bool operator()(const TimeUnit* lhs, const TimeUnit* rhs) { return lhs->sort_time > rhs->sort_time; }
122 
123  /** Compare references */
124  inline bool operator()(const TimeUnit& lhs, const TimeUnit& rhs) { return lhs.sort_time > rhs.sort_time; }
125  };
126  };
127 
128 
129 public:
132 
133  bool empty() override;
134  int size() override;
135  void insert(Activity* activity) override;
136  Activity* pop() override;
137  Activity* front() override;
138 
139 
140  /** Print the state of the TimeVortex */
141  void print(Output& out) const override;
142 
143  uint64_t getCurrentDepth() const override { return current_depth; }
144  uint64_t getMaxDepth() const override { return max_depth; }
145 
146 private:
147  // Should only ever be accessed by the "active" thread. Not safe
148  // for concurrent access.
149  TimeUnit* current_time_unit;
150 
151  typedef std::map<SimTime_t, TimeUnit*> mapType_t;
152 
153  // Accessed by multiple threads, must be locked when accessing
154  mapType_t map;
155  typename std::conditional<TS, std::atomic<uint64_t>, uint64_t>::type insertOrder;
156 
157  typename std::conditional<TS, std::atomic<uint64_t>, uint64_t>::type current_depth;
158 
159  // Should only ever be accessed by the "active" thread, or in a
160  // mutex. There are no internal mutexes.
161  Pool<TimeUnit> pool;
162 
163  CACHE_ALIGNED(SST::Core::ThreadSafe::Spinlock, slock);
164 };
165 
166 } // namespace IMPL
167 } // namespace SST
168 
169 #endif // SST_CORE_IMPL_TIMEVORTEX_TIMEVORTEXBINNEDMAP_H
Base class for all Activities in the SST Event Queue.
Definition: activity.h:46
Definition: threadsafe.h:122
Definition: timeVortexBinnedMap.h:29
To use with STL priority queues, that order in reverse.
Definition: timeVortexBinnedMap.h:118
bool operator()(const TimeUnit *lhs, const TimeUnit *rhs)
Compare pointers.
Definition: timeVortexBinnedMap.h:121
bool operator()(const TimeUnit &lhs, const TimeUnit &rhs)
Compare references.
Definition: timeVortexBinnedMap.h:124
Primary Event Queue.
Definition: timeVortexBinnedMap.h:57
bool empty() override
Returns true if the queue is empty.
Definition: timeVortexBinnedMap.cc:64
Activity * pop() override
Remove and return the next activity.
Definition: timeVortexBinnedMap.cc:126
int size() override
Returns the number of activities in the queue.
Definition: timeVortexBinnedMap.cc:74
Activity * front() override
Returns the next activity.
Definition: timeVortexBinnedMap.cc:150
void print(Output &out) const override
Print the state of the TimeVortex.
Definition: timeVortexBinnedMap.cc:165
void insert(Activity *activity) override
Insert a new activity into the queue.
Definition: timeVortexBinnedMap.cc:81
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file.
Definition: output.h:52
Parameter store.
Definition: params.h:56
Primary Event Queue.
Definition: timeVortex.h:26