Skip to content

Commit a5c733c

Browse files
committed
minor bugfixes. trying to get the simulator to work
1 parent e4e233c commit a5c733c

File tree

14 files changed

+162
-37
lines changed

14 files changed

+162
-37
lines changed

include/scl/simulation/context.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <cstddef>
2121
#include <type_traits>
22+
#include <iostream>
2223

2324
#include "scl/simulation/event.h"
2425
#include "scl/simulation/network_description.h"
@@ -96,6 +97,10 @@ class SimulatorContext final {
9697
return m_network_desc.size();
9798
}
9899

100+
Simulator::Result toResult() {
101+
return Simulator::Result{std::move(m_events)};
102+
}
103+
99104
private:
100105
NetworkDescription m_network_desc;
101106
std::vector<EventList> m_events;

include/scl/simulation/event.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,6 @@ class SleepEvent final : public Event {
410410
Time::Duration m_duration;
411411
};
412412

413-
namespace details {
414-
415413
/**
416414
* @brief Tracks events added by a party during simulation.
417415
*
@@ -474,5 +472,4 @@ class EventList final {
474472
std::vector<std::unique_ptr<Event>> m_events;
475473
};
476474

477-
} // namespace details
478475
} // namespace scl

include/scl/simulation/runtime.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class SimulatorRuntime final : public Runtime {
3232
static const std::size_t MANAGE_PID = static_cast<std::size_t>(-1);
3333

3434
public:
35-
SimulatorRuntime(SimulatorContext& sim_ctx) : m_sim_ctx(sim_ctx) {}
35+
SimulatorRuntime(SimulatorContext& sim_ctx)
36+
: m_sim_ctx(sim_ctx), m_current_pid(MANAGE_PID) {}
3637

3738
void schedule(std::coroutine_handle<> coroutine,
3839
std::function<bool()>&& predicate) override;

include/scl/simulation/simulator.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ concept ProtocolBuilder = requires(BUILDER builder) {
4545
*/
4646
class Simulator final {
4747
public:
48+
class Result final {
49+
public:
50+
Result(std::vector<EventList>&& events) : m_events(std::move(events)) {}
51+
std::size_t numberOfParties() const {
52+
return m_events.size();
53+
}
54+
EventList& operator[](std::size_t i) {
55+
return m_events[i];
56+
}
57+
58+
private:
59+
std::vector<EventList> m_events;
60+
};
4861
/**
4962
* @brief A simulation hook.
5063
*
@@ -66,7 +79,7 @@ class Simulator final {
6679
* sim.addHook(EventType::BEGIN_EVENT, printHook);
6780
* @endcode
6881
*/
69-
struct SimulationHook {
82+
struct SimulationHook final {
7083
/**
7184
* @brief Type definition of hook functions.
7285
*/
@@ -87,12 +100,12 @@ class Simulator final {
87100
* @brief Run the simulation.
88101
*/
89102
template <ProtocolBuilder BUILDER>
90-
void run(BUILDER builder, NetworkDescription network_desc) {
103+
Result run(BUILDER builder, NetworkDescription network_desc) {
91104
auto protocol = builder();
92105
if (protocol.size() != network_desc.size()) {
93106
throw std::logic_error("protocols do not match network definition");
94107
}
95-
run(std::move(protocol), network_desc);
108+
return run(std::move(protocol), network_desc);
96109
}
97110

98111
/**
@@ -116,8 +129,8 @@ class Simulator final {
116129
private:
117130
std::vector<SimulationHook> m_hooks;
118131

119-
void run(std::vector<std::unique_ptr<Protocol>>&& protocols,
120-
NetworkDescription network_desc);
132+
Result run(std::vector<std::unique_ptr<Protocol>>&& protocols,
133+
NetworkDescription network_desc);
121134
};
122135

123136
} // namespace scl

include/scl/time.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ struct Time {
4848
* @brief Convert a timestamp to milliseconds.
4949
*/
5050
inline long double timeToMillis(Time::Duration time) {
51-
using namespace std::chrono;
52-
return duration<long double, std::milli>(time).count();
51+
return std::chrono::duration<long double, std::milli>(time).count();
5352
}
5453

5554
/**

src/scl/simulation/channel.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525

2626
using namespace scl;
2727

28-
// This suspends a coroutine, while enabling it to be resumed again at any time.
29-
#define SUSPEND co_await []() { return true; }
30-
3128
void details::SimulatedChannel::close() {
3229
if (!m_closed) {
3330
m_ctx.addEvent<CloseEvent>(m_ctx.elapsedTime(), m_id);
@@ -87,7 +84,9 @@ Task<void> waitForData(details::Transport* transport,
8784
const auto diff = std::max(ctx.elapsedTimeOf(id.remote) - event->time(),
8885
Time::Duration::zero());
8986
event->increaseOffset(diff);
90-
SUSPEND;
87+
88+
// Suspend this coroutine.
89+
co_await []() { return true; };
9190
}
9291
}
9392

@@ -128,7 +127,7 @@ Task<bool> waitOrTimeout(details::Transport* transport,
128127

129128
if (stime >= event->time()) {
130129
// sender_time >= our_time. Two cases, based on how far ahead the sender
131-
// is of us.
130+
// is relative to us.
132131
//
133132
// |---------- time ----------|
134133
// | | |
@@ -138,8 +137,8 @@ Task<bool> waitOrTimeout(details::Transport* transport,
138137
// In the first case, we know that we're gonna timeout, so we can
139138
// advance our clock to the timeout mark, and return true.
140139
//
141-
// In the second case, we can advance our clock a little bit (see the
142-
// bumpTime function) and then suspend. We need to move our clock a
140+
// In the second case, we can advance our clock a little bit (the
141+
// timeout_wait_interval) and then suspend. We need to move our clock a
143142
// little bit to avoid deadlocks.
144143

145144
if (stime > event->time() + timeout) {
@@ -153,7 +152,8 @@ Task<bool> waitOrTimeout(details::Transport* transport,
153152
timeout -= timeout_wait_interval;
154153
}
155154

156-
SUSPEND;
155+
// Suspend this coroutine.
156+
co_await []() { return true; };
157157
}
158158

159159
// there is data available within the timeout

src/scl/simulation/event.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ void writeNumeric(std::ostream& stream, std::string_view key, std::size_t n) {
3131
stream << "\"" << key << "\":" << n;
3232
}
3333

34+
void writeNumeric(std::ostream& stream, std::string_view key, long double n) {
35+
stream << "\"" << key << "\":" << n;
36+
}
37+
3438
void writeString(std::ostream& stream,
3539
std::string_view key,
3640
std::string_view val) {
@@ -195,6 +199,6 @@ struct InitialEvent final : public Event {
195199

196200
} // namespace
197201

198-
details::EventList::EventList() {
202+
EventList::EventList() {
199203
add<InitialEvent>();
200204
}

src/scl/simulation/network_description.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ const ChannelDescription DEFAULT_LAN_PARAMS = {.bandwith = 100000000000,
3131
.latency_jitter = 0,
3232
.loss = 0.0};
3333

34+
const ChannelDescription DEFAULT_WAN_PARAMS = {.bandwith = 1000000000,
35+
.latency = 10000,
36+
.latency_jitter = 0,
37+
.loss = 0.0};
38+
3439
const ChannelDescription DEFAULT_LOCAL_PARAMS = {
3540
.bandwith = std::numeric_limits<std::size_t>::max(),
3641
.latency = 0,
@@ -52,6 +57,21 @@ NetworkDescription NetworkDescription::createDefaultLAN(std::size_t size) {
5257
return NetworkDescription{channels, ignored, size};
5358
}
5459

60+
NetworkDescription NetworkDescription::createDefaultWAN(std::size_t size) {
61+
std::unordered_map<ChannelId, ChannelDescription> channels;
62+
std::unordered_map<ChannelId, JitterSampler> ignored;
63+
64+
for (std::size_t i = 0; i < size; i++) {
65+
channels[ChannelId(i, i)] = DEFAULT_LOCAL_PARAMS;
66+
for (std::size_t j = i + 1; j < size; j++) {
67+
channels[ChannelId(i, j)] = DEFAULT_WAN_PARAMS;
68+
channels[ChannelId(j, i)] = DEFAULT_WAN_PARAMS;
69+
}
70+
}
71+
72+
return NetworkDescription{channels, ignored, size};
73+
}
74+
5575
NetworkDescription::ChannelParameters descriptionToParams(
5676
const ChannelDescription& desc) {
5777
return NetworkDescription::ChannelParameters{.bandwidth = desc.bandwith,

src/scl/simulation/simulator.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "scl/simulation/simulator.h"
1919

2020
#include <algorithm>
21+
#include <iostream>
2122
#include <memory>
2223

2324
#include "scl/net/loopback.h"
@@ -86,7 +87,7 @@ class ProtocolBatch final {
8687
// Main per-party protocol loop.
8788
Task<void> runProtocol(std::unique_ptr<Protocol> protocol,
8889
details::Context ctx,
89-
Env&& env) {
90+
Env env) {
9091
// Executing a protocol for a party goes more or less as follows:
9192
// 1. Emit a START event
9293
// 2. Emit a BEGIN event (signals the beginning of a Protocol)
@@ -171,8 +172,8 @@ std::vector<Network> createNetworks(details::SimulatorContext& sim_ctx) {
171172
return networks;
172173
}
173174

174-
// Clock implementation which will provide a party with a sensible value, when
175-
// called.
175+
// Ensures that parties get a sensible value when reading their clock in a
176+
// simulation.
176177
class FakeClock final : public Clock {
177178
public:
178179
FakeClock(details::Context ctx) : m_ctx(ctx) {}
@@ -199,18 +200,23 @@ Task<void> simulate(std::vector<std::unique_ptr<Protocol>>&& protocols,
199200
Env{networks[pid], std::make_unique<FakeClock>(ctx)}));
200201
}
201202

203+
// runs the simulation.
202204
co_await ProtocolBatch(std::move(protocol_tasks));
203205
}
204206

205207
} // namespace
206208

207-
void Simulator::run(std::vector<std::unique_ptr<Protocol>>&& protocols,
208-
NetworkDescription network_definition) {
209+
Simulator::Result Simulator::run(
210+
std::vector<std::unique_ptr<Protocol>>&& protocols,
211+
NetworkDescription network_definition) {
209212
if (!protocols.empty()) {
210213
auto sim_ctx = details::SimulatorContext::create(network_definition,
211214
std::move(m_hooks));
212215
auto runtime = std::make_unique<details::SimulatorRuntime>(sim_ctx);
213216

214217
runtime->run(simulate(std::move(protocols), sim_ctx));
218+
return sim_ctx.toResult();
215219
}
220+
221+
return Simulator::Result({});
216222
}

src/scl/simulation/transport.cc

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,6 @@ long double rttSeconds(std::size_t latency_us) {
7878
return std::chrono::microseconds(2 * latency_us) / 1.0s;
7979
}
8080

81-
// Utility function that does the reverse of the above.
82-
Time::Duration convert(long double v) {
83-
const auto t0 = std::chrono::duration<long double>(v);
84-
return std::chrono::duration_cast<Time::Duration>(t0);
85-
}
86-
8781
// calculate the throughput of a channel.
8882
long double throughput(NetworkDescription::ChannelParameters params) {
8983
const auto rtt_secs = rttSeconds(params.latency);
@@ -107,17 +101,23 @@ long double throughput(NetworkDescription::ChannelParameters params) {
107101
return std::min(tp, (long double)params.bandwidth);
108102
}
109103

104+
// Utility function that does the reverse of the above.
105+
Time::Duration convert(long double v) {
106+
const auto t0 = std::chrono::duration<long double>(v);
107+
return std::chrono::duration_cast<Time::Duration>(t0);
108+
}
109+
110110
// compute the time it takes to send n bytes on a channel.
111111
Time::Duration recvTimeOffset(std::size_t n,
112112
NetworkDescription::ChannelParameters params) {
113113
const long double total_size = completeDataSize(n);
114114
const long double tp = throughput(params);
115115

116-
// the min here is needed in case we're sending very small amounts of
116+
// the max here is needed in case we're sending very small amounts of
117117
// data. I.e., regardless of how good the channel is, we cannot send data
118118
// faster than the latency.
119119
const long double delay =
120-
std::min(total_size / tp, rttSeconds(params.latency));
120+
std::max(total_size / tp, rttSeconds(params.latency));
121121

122122
return convert(delay);
123123
}
@@ -129,7 +129,9 @@ Time::Duration computeDelay(Time::Duration rt,
129129
Time::Duration st,
130130
std::size_t n,
131131
NetworkDescription::ChannelParameters params) {
132-
return std::max(st + recvTimeOffset(n, params) - rt, Time::Duration::zero());
132+
const auto x = st + recvTimeOffset(n, params) - rt;
133+
std::cout << recvTimeOffset(n, params) << "\n";
134+
return std::max(x, Time::Duration::zero());
133135
}
134136

135137
} // namespace

0 commit comments

Comments
 (0)