Skip to content

Commit afdbb67

Browse files
committed
Queue up state sends instead of sending from inside lock.
1 parent 7ca9064 commit afdbb67

16 files changed

+266
-268
lines changed

SerialPrograms/Source/Controllers/SuperscalarScheduler.cpp

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ void SuperscalarScheduler::clear() noexcept{
4040
m_pending_clear.store(false, std::memory_order_release);
4141
}
4242

43-
std::vector<std::shared_ptr<const SchedulerResource>> SuperscalarScheduler::current_live_commands(){
43+
SuperscalarScheduler::State SuperscalarScheduler::current_live_commands(){
4444
WallClock device_sent_time = m_device_sent_time;
45-
std::vector<std::shared_ptr<const SchedulerResource>> ret;
45+
State ret;
4646
for (auto& item : m_live_commands){
4747
if (item.second.busy_time <= device_sent_time && device_sent_time < item.second.done_time){
4848
ret.emplace_back(item.second.command);
@@ -61,11 +61,7 @@ void SuperscalarScheduler::clear_finished_commands(){
6161
}
6262
}
6363
}
64-
bool SuperscalarScheduler::iterate_schedule(const Cancellable* cancellable){
65-
if (cancellable){
66-
cancellable->throw_if_cancelled();
67-
}
68-
64+
bool SuperscalarScheduler::iterate_schedule(Schedule& schedule){
6965
// cout << "----------------------------> " << m_state_changes.size() << endl;
7066
// cout << "m_device_sent_time = " << std::chrono::duration_cast<Milliseconds>(m_device_sent_time - m_local_start) << endl;
7167

@@ -113,7 +109,9 @@ bool SuperscalarScheduler::iterate_schedule(const Cancellable* cancellable){
113109
m_state_changes.erase(iter);
114110
}
115111

116-
this->push_state(cancellable, duration, std::move(state));
112+
ScheduleEntry& entry = schedule.emplace_back();
113+
entry.duration = duration;
114+
entry.state = std::move(state);
117115

118116
// SpinLockGuard lg(m_lock);
119117

@@ -153,18 +151,18 @@ bool SuperscalarScheduler::iterate_schedule(const Cancellable* cancellable){
153151

154152
return true;
155153
}
156-
void SuperscalarScheduler::process_schedule(const Cancellable* cancellable){
154+
void SuperscalarScheduler::process_schedule(Schedule& schedule){
157155
// Any exception is either an unrecoverable error, or an async-cancel.
158156
// Both cases should clear the scheduler.
159157
try{
160-
while (iterate_schedule(cancellable));
158+
while (iterate_schedule(schedule));
161159
}catch (...){
162160
clear();
163161
throw;
164162
}
165163
}
166164

167-
void SuperscalarScheduler::issue_wait_for_all(const Cancellable* cancellable){
165+
void SuperscalarScheduler::issue_wait_for_all(Schedule& schedule){
168166
if (m_pending_clear.load(std::memory_order_acquire)){
169167
clear();
170168
return;
@@ -177,9 +175,9 @@ void SuperscalarScheduler::issue_wait_for_all(const Cancellable* cancellable){
177175
// << endl;
178176
m_device_issue_time = std::max(m_device_issue_time, m_max_free_time);
179177
m_max_free_time = m_device_issue_time;
180-
process_schedule(cancellable);
178+
process_schedule(schedule);
181179
}
182-
void SuperscalarScheduler::issue_nop(const Cancellable* cancellable, WallDuration delay){
180+
void SuperscalarScheduler::issue_nop(Schedule& schedule, WallDuration delay){
183181
if (delay <= WallDuration::zero()){
184182
return;
185183
}
@@ -196,12 +194,9 @@ void SuperscalarScheduler::issue_nop(const Cancellable* cancellable, WallDuratio
196194
m_device_issue_time = next_issue_time;
197195
m_max_free_time = std::max(m_max_free_time, m_device_issue_time);
198196
m_local_last_activity = current_time();
199-
process_schedule(cancellable);
197+
process_schedule(schedule);
200198
}
201-
void SuperscalarScheduler::issue_wait_for_resource(
202-
const Cancellable* cancellable,
203-
size_t resource_id
204-
){
199+
void SuperscalarScheduler::issue_wait_for_resource(Schedule& schedule, size_t resource_id){
205200
if (m_pending_clear.load(std::memory_order_acquire)){
206201
clear();
207202
return;
@@ -219,10 +214,10 @@ void SuperscalarScheduler::issue_wait_for_resource(
219214
m_local_last_activity = current_time();
220215
}
221216

222-
process_schedule(cancellable);
217+
process_schedule(schedule);
223218
}
224219
void SuperscalarScheduler::issue_to_resource(
225-
const Cancellable* cancellable,
220+
Schedule& schedule,
226221
std::shared_ptr<const SchedulerResource> resource,
227222
WallDuration delay, WallDuration hold, WallDuration cooldown
228223
){
@@ -268,7 +263,7 @@ void SuperscalarScheduler::issue_to_resource(
268263
m_max_free_time = std::max(m_max_free_time, m_device_issue_time);
269264
m_local_last_activity = current_time();
270265

271-
process_schedule(cancellable);
266+
process_schedule(schedule);
272267
}
273268

274269

SerialPrograms/Source/Controllers/SuperscalarScheduler.h

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
#include <set>
1212
#include <map>
1313
#include <atomic>
14+
#include "Common/Compiler.h"
15+
#include "Common/Cpp/Time.h"
1416
#include "Common/Cpp/AbstractLogger.h"
15-
#include "Common/Cpp/CancellableScope.h"
17+
//#include "Common/Cpp/CancellableScope.h"
1618

1719
namespace PokemonAutomation{
1820

@@ -37,6 +39,14 @@ class SchedulerResource{
3739

3840

3941
class SuperscalarScheduler{
42+
public:
43+
using State = std::vector<std::shared_ptr<const SchedulerResource>>;
44+
struct ScheduleEntry{
45+
WallDuration duration;
46+
State state;
47+
};
48+
using Schedule = std::vector<ScheduleEntry>;
49+
4050
public:
4151
SuperscalarScheduler(Logger& logger, WallDuration flush_threshold);
4252

@@ -53,7 +63,9 @@ class SuperscalarScheduler{
5363
public:
5464
// These are the standard "issue" commands.
5565
//
56-
// These functions may or may not block.
66+
// These functions are non-blocking and will append any new schedule
67+
// entries to "schedule".
68+
//
5769
// These are not thread-safe with each other.
5870
//
5971

@@ -66,52 +78,30 @@ class SuperscalarScheduler{
6678

6779
// Wait until the pipeline has completely cleared and all resources have
6880
// returned to the ready state.
69-
void issue_wait_for_all(const Cancellable* cancellable);
81+
void issue_wait_for_all(Schedule& schedule);
7082

7183
// Issue a do-nothing command for the specified delay.
7284
// This will advance the issue timestamp.
73-
void issue_nop(const Cancellable* cancellable, WallDuration delay);
85+
void issue_nop(Schedule& schedule, WallDuration delay);
7486

7587
// Wait until the specified resource is ready to be used.
7688
// This will advance the issue timestamp until the resource is ready.
77-
void issue_wait_for_resource(
78-
const Cancellable* cancellable,
79-
size_t resource_id
80-
);
89+
void issue_wait_for_resource(Schedule& schedule, size_t resource_id);
8190

8291
// Issue a resource with the specified timing parameters.
8392
void issue_to_resource(
84-
const Cancellable* cancellable,
93+
Schedule& schedule,
8594
std::shared_ptr<const SchedulerResource> resource,
8695
WallDuration delay, WallDuration hold, WallDuration cooldown
8796
);
8897

8998

90-
protected:
91-
//
92-
// This class will automatically call "push_state()" when a state is ready.
93-
// The child class should send/queue this state to the device/Switch.
94-
//
95-
// This function is allowed to block. In other words, it can wait until
96-
// there is space in the queue before returning.
97-
//
98-
// This will always be called inside one of the above "issue_XXX()"
99-
// functions. Implementations of this method should be aware of this
100-
// re-entrancy when this gets called on them with respect to locking.
101-
//
102-
virtual void push_state(
103-
const Cancellable* cancellable,
104-
WallDuration duration,
105-
std::vector<std::shared_ptr<const SchedulerResource>> state
106-
) = 0;
107-
108-
10999
private:
110100
void clear() noexcept;
111-
std::vector<std::shared_ptr<const SchedulerResource>> current_live_commands();
101+
State current_live_commands();
112102
void clear_finished_commands();
113-
bool iterate_schedule(const Cancellable* cancellable);
114-
void process_schedule(const Cancellable* cancellable);
103+
bool iterate_schedule(Schedule& schedule);
104+
void process_schedule(Schedule& schedule);
115105

116106

117107
private:

0 commit comments

Comments
 (0)