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