fixed bug in attaching nics to hosts, changed documentation format and generator (buggy but usable)

This commit is contained in:
2025-09-14 00:40:53 -04:00
parent 9ab64e18a4
commit c4141cd683
40 changed files with 5223 additions and 577 deletions

View File

@@ -1,9 +1,15 @@
# core/error.h
## Free functions
### `std::mutex &error_mutex() noexcept;`
### `inline T&& show(std::string_view name, T&& value) noexcept { ... }`
### `std::lock_guard<std::mutex> lock(error_mutex());`
### `inline T&& eval_and_show(std::string_view expr, T&& value) noexcept { ... }`
### `std::lock_guard<std::mutex> lock(error_mutex());`
## `dofs::log_error`
`void log_error(std::string_view type, std::string_view message, std::optional<uint64_t> timestamp = std::nullopt) noexcept;`
## `DOFS_ERROR`
`#define DOFS_ERROR(TYPE, MSG)`
## `DOFS_ERROR_ST`
`#define DOFS_ERROR_ST(TYPE, SRC, MSG, TS)`
## `DOFS_ERROR_T`
`#define DOFS_ERROR_T(TYPE, MSG, TS)`
## `DOFS_EVAL`
`#define DOFS_EVAL(EXPR)`
## `DOFS_SHOW`
`#define DOFS_SHOW(VAR)`
## `FORMAT`
`#define FORMAT(VAR)`

View File

@@ -1,10 +1,32 @@
# core/host.h
## `Host::Host`
`Host(Simulator *const sim, NodeId id) noexcept`
## class NetworkNic — public interface
Binds a host to a simulator under the `NodeId` id.
### `Host(Simulator *const sim, NodeId id) noexcept;`
### `virtual ~Host() = default;`
### `NetworkNic *nic() const noexcept { ... }`
### `void attach_nic(NetworkNic* nic) noexcept;`
### `void detach_nic(NetworkNic* nic) noexcept;`
### `Host(const Host &) = delete;`
## `Host::Host`
`Host(const Host &) = delete`
Binds a host to a simulator under the `NodeId` id.
## `Host::attach_nic`
`void attach_nic(NetworkNic *nic) noexcept`
Attaches a `NetworkNic` to the host.
## `Host::detach_nic`
`void detach_nic(NetworkNic *nic) noexcept`
Detaches a `NetworkNic` to the host.
## `Host::nic`
`NetworkNic *nic() const noexcept`
## `Host::operator=`
`Host &operator=(const Host &) = delete`
## `Host::recv_flow`
`virtual void recv_flow(NodeId src, FlowId flow, FlowPriority priority, Bytes flow_size) = 0`
## `Host::recv_frame`
`virtual void recv_frame(const Packet &frame) = 0`
## `Host::recv_mgmt_msg`
`virtual void recv_mgmt_msg(std::unique_ptr<struct MgmtMsg> msg) = 0`
## `Host::~Host`
`virtual ~Host() = default`

View File

@@ -1,13 +1,31 @@
# core/logger.h
## class Logger — public interface
### `Logger(std::string_view path, bool append) noexcept;`
### `~Logger() noexcept;`
### `Logger(const Logger &) = delete;`
### `Logger(Logger &&) = delete;`
### `bool is_open() const noexcept { ... }`
### `void write_line(std::string_view line) noexcept;`
### `void flush() noexcept;`
### `void close() noexcept;`
### `std::string_view path() const noexcept { ... }`
## `Logger::Logger`
`Logger(Logger &&) = delete`
## `Logger::Logger`
`Logger(const Logger &) = delete`
## `Logger::Logger`
`Logger(std::string_view path, bool append) noexcept`
## `Logger::close`
`void close() noexcept`
## `Logger::flush`
`void flush() noexcept`
## `Logger::is_open`
`bool is_open() const noexcept`
## `Logger::operator=`
`Logger &operator=(Logger &&) = delete`
## `Logger::operator=`
`Logger &operator=(const Logger &) = delete`
## `Logger::path`
`std::string_view path() const noexcept`
## `Logger::write_line`
`void write_line(std::string_view line) noexcept`
## `Logger::~Logger`
`~Logger() noexcept`
## `dofs::close`
`void close() noexcept;`
## `dofs::flush`
`void flush() noexcept;`
## `dofs::write_line`
`void write_line(std::string_view line) noexcept;`
## `open`
`private: bool open(std::ios::openmode mode) noexcept;`

View File

@@ -1,13 +1,21 @@
# core/node.h
## class Node — public interface
### `Node(Simulator *const sim, NodeId id, NodeType type) noexcept;`
### `virtual ~Node() = default;`
### `NodeId id() const noexcept;`
### `NodeStatus status() const noexcept;`
### `NodeType type() const noexcept;`
### `void set_status(NodeStatus s) noexcept;`
### `void boot(Time boottime_ns);`
### `void reboot(Time boottime_ns);`
### `Node(const Node &) = delete;`
## `Node::Node`
`Node(Simulator *const sim, NodeId id, NodeType type) noexcept`
## `Node::Node`
`Node(const Node &) = delete`
## `Node::boot`
`void boot(Time boottime_ns)`
## `Node::id`
`NodeId id() const noexcept`
## `Node::operator=`
`Node &operator=(const Node &) = delete`
## `Node::reboot`
`void reboot(Time boottime_ns)`
## `Node::set_status`
`void set_status(NodeStatus s) noexcept`
## `Node::status`
`NodeStatus status() const noexcept`
## `Node::type`
`NodeType type() const noexcept`
## `Node::~Node`
`virtual ~Node() = default`

View File

@@ -1,16 +1,45 @@
# core/rng.h
## class Rng — public interface
### `: _eng(seed) { ... }`
### `void seed(seed_type s) noexcept { ... }`
### `_eng.seed(s);`
### `double uniform01() { ... }`
### `Int uniform_range(Int lo_inclusive, Int hi_exclusive) { ... }`
### `Int uniform_range(Int hi_exclusive) { ... }`
### `double uniform_range(double lo_inclusive, double hi_exclusive) { ... }`
### `std::uint64_t poisson(double lambda) { ... }`
### `T choose_weighted(const std::vector<std::pair<double, T>>& items) { ... }`
### `return choose_weighted_impl(items.begin(), items.end());`
### `T choose_weighted(std::initializer_list<std::pair<double, T>> items) { ... }`
### `return choose_weighted_impl(items.begin(), items.end());`
## `Rng::Rng`
`explicit Rng(seed_type seed = default_seed()) noexcept : _eng(seed)`
## `Rng::choose_weighted`
`template<typename T> template<typename T> T choose_weighted(const std::vector<std::pair<double, T>> &items)`
## `Rng::choose_weighted`
`template<typename T> template<typename T> T choose_weighted(std::initializer_list<std::pair<double, T>> items)`
## `Rng::poisson`
`std::uint64_t poisson(double lambda)`
## `Rng::seed`
`void seed(seed_type s) noexcept`
## `Rng::uniform01`
`double uniform01()`
## `Rng::uniform_range`
`double uniform_range(double lo_inclusive, double hi_exclusive)`
## `Rng::uniform_range`
`template<typename Int,
typename = std::enable_if_t<std::is_integral<Int>::value>> template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>> Int uniform_range(Int hi_exclusive)`
## `Rng::uniform_range`
`template<typename Int,
typename = std::enable_if_t<std::is_integral<Int>::value>> template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>> Int uniform_range(Int lo_inclusive, Int hi_exclusive)`
## `choose_weighted`
`template <typename T> T choose_weighted(const std::vector<std::pair<double, T>> &items){`
## `choose_weighted`
`template <typename T> T choose_weighted(std::initializer_list<std::pair<double, T>> items){`
## `choose_weighted_impl`
`return choose_weighted_impl(items.begin(), items.end());`
## `choose_weighted_impl`
`return choose_weighted_impl(items.begin(), items.end());`
## `choose_weighted_impl`
`template <typename Iter> auto choose_weighted_impl(Iter first, Iter last) -> typename std::iterator_traits<Iter>::value_type::second_type{`
## `default_seed`
`static constexpr seed_type default_seed() noexcept{`
## `dofs::seed`
`void seed(seed_type s) noexcept{`
## `poisson`
`std::uint64_t poisson(double lambda){`
## `uniform01`
`double uniform01(){`
## `uniform_range`
`Int uniform_range(Int hi_exclusive){`
## `uniform_range`
`Int uniform_range(Int lo_inclusive, Int hi_exclusive){`
## `uniform_range`
`double uniform_range(double lo_inclusive, double hi_exclusive){`

View File

@@ -1,27 +1,49 @@
# core/simulator.h
## Free functions
### `std::numeric_limits<InstanceId>::max();`
### `std::numeric_limits<LinkId>::max();`
## class Rng — public interface
### `Simulator() = default;`
### `static std::pair<InstanceId, Simulator *> create_simulator(InstanceId id);`
### `static Simulator *get_simulator(InstanceId id) noexcept;`
### `Time now() const noexcept;`
### `EventId schedule_at(Time abs_time, F&& f, Args&&... args) { ... }`
### `_event_pq.push(std::move(it));`
### `EventId schedule_after(Time delay, F&& f, Args&&... args) { ... }`
### `bool cancel(EventId id);`
### `bool run_next();`
### `void run_until(Time end_time);`
### `void lock() noexcept;`
### `bool is_locked() const noexcept { ... }`
### `void flush_after(Time grace) noexcept;`
### `Rng* create_rng(std::uint64_t seed);`
### `Rng* get_rng() noexcept;`
### `Rng const* get_rng() const noexcept;`
### `Link* get_link(LinkId id) noexcept;`
### `Link const* get_link(LinkId id) const noexcept;`
## `Simulator::Cmp::operator`
`bool operator()(const Item &a, const Item &b) const noexcept`
## `Simulator::Simulator`
`Simulator() = default`
## `Simulator::cancel`
`bool cancel(EventId id)`
## `Simulator::create_link`
`std::pair<LinkId, Link *> create_link(NetworkNode *a, PortId a_port, NetworkNode *b, PortId b_port, Time latency, double bandwidth_gbps)`
## `Simulator::create_rng`
`Rng *create_rng(std::uint64_t seed)`
## `Simulator::create_simulator`
`static std::pair<InstanceId, Simulator *> create_simulator(InstanceId id)`
## `Simulator::flush_after`
`void flush_after(Time grace) noexcept`
## `Simulator::get_link`
`Link *get_link(LinkId id) noexcept`
## `Simulator::get_link`
`Link const *get_link(LinkId id) const noexcept`
## `Simulator::get_rng`
`Rng *get_rng() noexcept`
## `Simulator::get_rng`
`Rng const *get_rng() const noexcept`
## `Simulator::get_simulator`
`static Simulator *get_simulator(InstanceId id) noexcept`
## `Simulator::is_locked`
`bool is_locked() const noexcept`
## `Simulator::lock`
`void lock() noexcept`
## `Simulator::now`
`Time now() const noexcept`
## `Simulator::run_next`
`bool run_next()`
## `Simulator::run_until`
`void run_until(Time end_time)`
## `Simulator::schedule_after`
`template<class F, class... Args> template<class F, class... Args> EventId schedule_after(Time delay, F&&f, Args&&... args)`
## `Simulator::schedule_at`
`template<class F, class... Args> template<class F, class... Args> EventId schedule_at(Time abs_time, F&&f, Args&&... args)`
## `cancel`
`bool cancel(EventId id);`
## `flush_after`
`void flush_after(Time grace) noexcept;`
## `lock`
`void lock() noexcept;`
## `run_next`
`bool run_next();`
## `run_until`
`void run_until(Time end_time);`

View File

@@ -1,36 +1,61 @@
# core/time.h
## Free functions
### `constexpr Time operator""_ns(unsigned long long v) noexcept { ... }`
### `return Time::from_ns(static_cast<Time::rep>(v));`
### `constexpr Time operator""_us(unsigned long long v) noexcept { ... }`
### `return Time::from_us(static_cast<Time::rep>(v));`
### `constexpr Time operator""_ms(unsigned long long v) noexcept { ... }`
### `return Time::from_ms(static_cast<Time::rep>(v));`
### `constexpr Time operator""_s (unsigned long long v) noexcept { ... }`
### `return Time::from_s (static_cast<Time::rep>(v));`
## class Time — public interface
### `constexpr Time() : _nsec(0) { ... }`
### `explicit constexpr Time(rep ns) : _nsec(ns) { ... }`
### `static constexpr Time from_ns(rep ns) noexcept { ... }`
### `return Time(ns);`
### `static constexpr Time from_us(rep us) noexcept { ... }`
### `return Time(us * 1000ULL);`
### `static constexpr Time from_ms(rep ms) noexcept { ... }`
### `return Time(ms * 1000ULL * 1000ULL);`
### `static constexpr Time from_s (rep s ) noexcept { ... }`
### `return Time(s * 1000ULL * 1000ULL * 1000ULL);`
### `constexpr rep ns() const noexcept { ... }`
### `constexpr rep count() const noexcept { ... }`
### `static constexpr rep us_to_ns(rep us) noexcept { ... }`
### `static constexpr rep ms_to_ns(rep ms) noexcept { ... }`
### `return Time(a._nsec + b._nsec);`
### `return Time(a._nsec * b._nsec);`
### `return safe_sub(a, b);`
### `if (a._nsec < b._nsec) { ... }`
### `return Time(a._nsec - b._nsec);`
### `constexpr Time unsafe_sub(Time t) const noexcept { ... }`
### `return Time(this->_nsec - t._nsec);`
## `Time`
`return Time(a._nsec * b._nsec);`
## `Time`
`return Time(a._nsec + b._nsec);`
## `Time`
`return Time(a._nsec - b._nsec);`
## `Time`
`return Time(ms * 1000ULL * 1000ULL);`
## `Time`
`return Time(ns);`
## `Time`
`return Time(s * 1000ULL * 1000ULL * 1000ULL);`
## `Time`
`return Time(this->_nsec - t._nsec);`
## `Time`
`return Time(us * 1000ULL);`
## `Time::Time`
`constexpr Time() : _nsec(0)`
## `Time::Time`
`explicit constexpr Time(rep ns) : _nsec(ns)`
## `Time::count`
`constexpr rep count() const noexcept`
## `Time::from_ms`
`static constexpr Time from_ms(rep ms) noexcept`
## `Time::from_ns`
`static constexpr Time from_ns(rep ns) noexcept`
## `Time::from_s`
`static constexpr Time from_s (rep s ) noexcept`
## `Time::from_us`
`static constexpr Time from_us(rep us) noexcept`
## `Time::ms_to_ns`
`static constexpr rep ms_to_ns(rep ms) noexcept`
## `Time::ns`
`constexpr rep ns() const noexcept`
## `Time::us_to_ns`
`static constexpr rep us_to_ns(rep us) noexcept`
## `_ms`
`constexpr Time operator _ms(unsigned long long v) noexcept{`
## `_ns`
`constexpr Time operator _ns(unsigned long long v) noexcept{`
## `_s`
`constexpr Time operator _s (unsigned long long v) noexcept{`
## `_us`
`constexpr Time operator _us(unsigned long long v) noexcept{`
## `from_ms`
`static constexpr Time from_ms(rep ms) noexcept{`
## `from_ns`
`static constexpr Time from_ns(rep ns) noexcept{`
## `from_s`
`static constexpr Time from_s (rep s ) noexcept{`
## `from_us`
`static constexpr Time from_us(rep us) noexcept{`
## `ms_to_ns`
`static constexpr rep ms_to_ns(rep ms) noexcept{`
## `safe_sub`
`friend constexpr std::optional<Time> safe_sub(Time a, Time b) noexcept{`
## `safe_sub`
`return safe_sub(a, b);`
## `us_to_ns`
`static constexpr rep us_to_ns(rep us) noexcept{`

View File

@@ -1,13 +1,13 @@
# core/timer.h
## class Timer — public interface
### `Timer() { ... }`
### `init();`
### `void init() noexcept { ... }`
### `_start = clock::now();`
### `Time start() const noexcept { ... }`
### `auto tp = _start.time_since_epoch();`
### `Time now() const noexcept { ... }`
### `auto tp = clock::now().time_since_epoch();`
### `Time elapsed() const noexcept { ... }`
## `Timer::Timer`
`Timer()`
## `Timer::elapsed`
`Time elapsed() const noexcept`
## `Timer::init`
`void init() noexcept`
## `Timer::now`
`Time now() const noexcept`
## `Timer::start`
`Time start() const noexcept`
## `dofs::init`
`void init() noexcept{`

View File

@@ -1,6 +1,3 @@
# core/types.h
## Free functions
### `inline IPv4Addr ipv4(NodeId n, PortId p) noexcept { ... }`
### `return (static_cast<uint32_t>(n) << 16) | static_cast<uint32_t>(p);`
## `dofs::ipv4`
`inline IPv4Addr ipv4(NodeId n, PortId p) noexcept{`