Commit 0a67f9b1 authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

libnicbm: support for scheduled events

parent ff491d33
#include <set>
namespace nicbm {
#include <cassert>
......@@ -17,6 +19,13 @@ class DMAOp {
void *data;
};
class TimedEvent {
public:
virtual ~TimedEvent() { }
uint64_t time;
};
/**
* The Runner drives the main simulation loop. It's initialized with a reference
* to a device it should manage, and then once `runMain` is called, it will
......@@ -59,10 +68,23 @@ class Runner {
*/
virtual void eth_rx(uint8_t port, const void *data, size_t len)
= 0;
/**
* A timed event is due.
*/
virtual void timed_event(TimedEvent &ev);
};
protected:
struct event_cmp {
bool operator() (TimedEvent *a, TimedEvent *b)
{
return a->time < b->time;
}
};
Device &dev;
std::set<TimedEvent *, event_cmp> events;
uint64_t mac_addr;
struct nicsim_params nsparams;
struct cosim_pcie_proto_dev_intro dintro;
......@@ -79,6 +101,8 @@ class Runner {
void eth_recv(volatile struct cosim_eth_proto_n2d_recv *recv);
void poll_n2d();
bool event_next(uint64_t &retval);
void event_trigger();
public:
Runner(Device &dev_);
......@@ -90,6 +114,9 @@ class Runner {
void msi_issue(uint8_t vec);
void eth_send(const void *data, size_t len);
void event_schedule(TimedEvent &evt);
void event_cancel(TimedEvent &evt);
uint64_t time_ps() const;
uint64_t get_mac_addr() const;
};
......
......@@ -113,6 +113,16 @@ void Runner::msi_issue(uint8_t vec)
COSIM_PCIE_PROTO_D2H_OWN_HOST;
}
void Runner::event_schedule(TimedEvent &evt)
{
events.insert(&evt);
}
void Runner::event_cancel(TimedEvent &evt)
{
events.erase(&evt);
}
void Runner::h2d_read(volatile struct cosim_pcie_proto_h2d_read *read)
{
volatile union cosim_pcie_proto_d2h *msg;
......@@ -281,8 +291,33 @@ uint64_t Runner::get_mac_addr() const
return mac_addr;
}
bool Runner::event_next(uint64_t &retval)
{
if (events.empty())
return false;
retval = (*events.begin())->time;
return true;
}
void Runner::event_trigger()
{
auto it = events.begin();
if (it == events.end())
return;
TimedEvent *ev = *it;
// event is in the future
if (ev->time > main_time)
return;
events.erase(it);
dev.timed_event(*ev);
}
Runner::Runner(Device &dev_)
: dev(dev_)
: dev(dev_), events(event_cmp())
{
//mac_addr = lrand48() & ~(3ULL << 46);
srand48(time(NULL) ^ getpid());
......@@ -327,6 +362,8 @@ int Runner::runMain(int argc, char *argv[])
fprintf(stderr, "sync_pci=%d sync_eth=%d\n", nsparams.sync_pci,
nsparams.sync_eth);
bool is_sync = nsparams.sync_pci || nsparams.sync_eth;
while (!exiting) {
while (nicsim_sync(&nsparams, main_time)) {
fprintf(stderr, "warn: nicsim_sync failed (t=%lu)\n", main_time);
......@@ -335,9 +372,19 @@ int Runner::runMain(int argc, char *argv[])
do {
poll_h2d();
poll_n2d();
event_trigger();
if (is_sync) {
next_ts = netsim_next_timestamp(&nsparams);
} while ((nsparams.sync_pci || nsparams.sync_eth) &&
next_ts <= main_time && !exiting);
} else {
next_ts = main_time + 100000;
}
uint64_t ev_ts;
if (event_next(ev_ts) && ev_ts < next_ts)
next_ts = ev_ts;
} while (next_ts <= main_time && !exiting);
main_time = next_ts;
}
......@@ -345,3 +392,7 @@ int Runner::runMain(int argc, char *argv[])
nicsim_cleanup();
return 0;
}
void Runner::Device::timed_event(TimedEvent &te)
{
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment