finished part of the hosts, topos and configuration next

This commit is contained in:
2025-09-13 01:24:38 -04:00
parent 3d3d8113b2
commit 321c60bcf8
66 changed files with 2661 additions and 22 deletions

View File

@@ -14,6 +14,8 @@ option(DOFS_GLOB_SOURCES "Dev: auto-add *.cc files via GLOB (not ideal for CI)"
add_library(dofs_config INTERFACE)
target_compile_features(dofs_config INTERFACE cxx_std_20)
target_compile_options(dofs_config INTERFACE -Wall -Wextra -Wpedantic)
# Let everyone include headers like: #include "core/error.h"
target_include_directories(dofs_config INTERFACE "${PROJECT_SOURCE_DIR}/src")

View File

@@ -0,0 +1,10 @@
# struct
## Functions
### operator()
*public bool operator()(const Item & a, const Item & b)*

View File

@@ -0,0 +1,9 @@
# Global Namespace
## Namespaces
* [dofs](../dofs/index.md)

View File

@@ -0,0 +1,5 @@
# All Files for DOFS
## [@nonymous_record_1A6CA7D670A31E6DAC055D6C915DB71801F36C7F](@nonymous_record_1A6CA7D670A31E6DAC055D6C915DB71801F36C7F.md)
## [dofs](dofs/index.md)
## [GlobalNamespace](GlobalNamespace/index.md)

View File

@@ -0,0 +1,46 @@
# class CongestionControl
*Defined at src/network/nic/congestion_control.h#11*
## Members
protected Bytes _cwnd
protected Bytes _cwnd_max
## Functions
### CongestionControl
*public void CongestionControl(Bytes init_cwnd, Bytes max_cwnd)*
### update
*public void update(const Packet & pkt, Time rtt)*
### is_allowed_to_send
*public bool is_allowed_to_send(Bytes bytes_outstanding, Bytes next_bytes)*
### ~CongestionControl
*public void ~CongestionControl()*
*Defined at src/network/nic/congestion_control.h#14*
### cwnd
*public Bytes cwnd()*
*Defined at src/network/nic/congestion_control.h#21*
### cwnd_max
*public Bytes cwnd_max()*
*Defined at src/network/nic/congestion_control.h#24*

View File

@@ -0,0 +1,20 @@
# class DCQCN
*Defined at src/network/nic/congestion_control.h#33*
Inherits from CongestionControl
## Functions
### DCQCN
*public void DCQCN(Bytes init_cwnd, Bytes max_cwnd)*
### update
*public void update(const Packet & pkt, Time rtt)*

View File

@@ -0,0 +1,44 @@
# class DedicatedBuffer
*Defined at src/network/switch/dedicated_buffer.h#10*
Inherits from SwitchBuffer
## Functions
### DedicatedBuffer
*public void DedicatedBuffer(Simulator *const sim, NetworkSwitch *const owner, Bytes total_bytes, uint16_t ports)*
### enqueue_packet
*public bool enqueue_packet(const Packet & pkt, PortId egress, FlowPriority prio)*
### drain_one
*public bool drain_one(PortId port)*
### queues_for
*protected std::array<std::deque<Queued>, PRI_COUNT> & queues_for(PortId p)*
### queues_for
*protected const std::array<std::deque<Queued>, PRI_COUNT> & queues_for(PortId p)*
### on_enqueue_cap_check
*protected bool on_enqueue_cap_check(PortId port, Bytes sz)*
### on_enqueue_commit
*protected void on_enqueue_commit(PortId port, Bytes sz)*
### on_dequeue_commit
*protected void on_dequeue_commit(PortId port, Bytes sz)*

View File

@@ -0,0 +1,22 @@
# class DedicatedREDEngine
*Defined at src/network/switch/ecn_dedicated_red.h#13*
Inherits from ECNEngine
## Functions
### DedicatedREDEngine
*public void DedicatedREDEngine(Bytes min_th, Bytes max_th, double p_max, bool back_to_sender, Rng *const rng)*
*Defined at src/network/switch/ecn_dedicated_red.h#15*
### process_packet
*public Packet & process_packet(Packet & pkt, SwitchBuffer * buf)*

View File

@@ -0,0 +1,30 @@
# class ECNEngine
*Defined at src/network/switch/ecn_engine.h#12*
## Functions
### maybe_mark_ecn
*protected void maybe_mark_ecn(Packet & pkt)*
*Defined at src/network/switch/ecn_engine.h#23*
### process_packet
*public Packet & process_packet(Packet & pkt, SwitchBuffer * buf)*
### ~ECNEngine
*public void ~ECNEngine()*
*Defined at src/network/switch/ecn_engine.h#14*
### header_trim
*protected void header_trim(Packet & pkt, bool back_to_sender)*
*Defined at src/network/switch/ecn_engine.h#30*

View File

@@ -0,0 +1,18 @@
# struct EndSimulationMsg
*Defined at src/hosts/mgmt_msg.h#41*
Inherits from MgmtMsg
## Functions
### kind
*public MgmtKind kind()*
*Defined at src/hosts/mgmt_msg.h#42*

View File

@@ -0,0 +1,34 @@
# struct HeartbeatMsg
*Defined at src/hosts/mgmt_msg.h#16*
Inherits from MgmtMsg
## Members
public NodeId subscriber_id
public NodeStatus status
public Time generated_at
## Functions
### HeartbeatMsg
*public void HeartbeatMsg(NodeId sid, NodeStatus st, Time t)*
*Defined at src/hosts/mgmt_msg.h#21*
### kind
*public MgmtKind kind()*
*Defined at src/hosts/mgmt_msg.h#24*

View File

@@ -0,0 +1,60 @@
# class Host
*Defined at src/core/host.h#14*
Inherits from Node
## Functions
### Host
*public void Host(Simulator *const sim, NodeId id)*
### attach_nic
*public void attach_nic(NetworkNic * nic)*
### detach_nic
*public void detach_nic(NetworkNic * nic)*
### ~Host
*public void ~Host()*
*Defined at src/core/host.h#17*
### nic
*public NetworkNic * nic()*
*Defined at src/core/host.h#20*
### Host
*public void Host(const Host & )*
*Defined at src/core/host.h#39*
### operator=
*public Host & operator=(const Host & )*
*Defined at src/core/host.h#40*
### recv_flow
*public void recv_flow(NodeId src, FlowId flow, FlowPriority priority, Bytes flow_size)*
### recv_frame
*public void recv_frame(const Packet & frame)*
### recv_mgmt_msg
*public void recv_mgmt_msg(std::unique_ptr<struct MgmtMsg> msg)*

View File

@@ -0,0 +1,32 @@
# struct JobFinishedMsg
*Defined at src/hosts/mgmt_msg.h#29*
Inherits from MgmtMsg
## Members
public FlowId flow_id
public Time finished_at
## Functions
### JobFinishedMsg
*public void JobFinishedMsg(FlowId fid, Time t)*
*Defined at src/hosts/mgmt_msg.h#33*
### kind
*public MgmtKind kind()*
*Defined at src/hosts/mgmt_msg.h#36*

View File

@@ -0,0 +1,26 @@
# class LBRandomPacketSpraying
*Defined at src/network/nic/load_balance.h#27*
Inherits from LoadBalance
## Functions
### LBRandomPacketSpraying
*public void LBRandomPacketSpraying(Rng *const rng)*
*Defined at src/network/nic/load_balance.h#29*
### update
*public void update(const Packet & pkt)*
### get_entropy
*public uint16_t get_entropy(const Packet & context)*

View File

@@ -0,0 +1,96 @@
# class Link
*Defined at src/network/link.h#27*
## Records
Reservation
## Functions
### Link
*public void Link(Simulator *const sim, LinkId id, NetworkNode * a, PortId a_port, NetworkNode * b, PortId b_port, Time latency, double bandwidth_gbps)*
### send_pkt
*public void send_pkt(Packet & pkt, NodeId caller)*
### schedule_delivery_after
*public void schedule_delivery_after(Packet & pkt, NodeId caller, Time after)*
### next_available
*public Time next_available(NodeId sender)*
### reserve
*public std::optional<Reservation> reserve(Bytes bytes, NodeId sender)*
### serialization_time
*public Time serialization_time(Bytes bytes)*
*Defined at src/network/link.h#49*
### propagation_latency
*public Time propagation_latency()*
*Defined at src/network/link.h#53*
### id
*public LinkId id()*
*Defined at src/network/link.h#57*
### status
*public LinkStatus status()*
*Defined at src/network/link.h#60*
### bandwidth_gbps
*public double bandwidth_gbps()*
*Defined at src/network/link.h#63*
### src_id
*public NodeId src_id()*
*Defined at src/network/link.h#68*
### dst_id
*public NodeId dst_id()*
*Defined at src/network/link.h#71*
### src_port
*public PortId src_port()*
*Defined at src/network/link.h#74*
### dst_port
*public PortId dst_port()*
*Defined at src/network/link.h#77*
### set_status
*public void set_status(LinkStatus s, Time new_latency, double new_bandwidth_gbps)*
### serialization_time
*public Time serialization_time(Bytes bytes, double gbps)*

View File

@@ -0,0 +1,12 @@
# struct Reservation
*Defined at src/network/link.h#29*
## Members
public Time start
public Time finish

View File

@@ -0,0 +1,34 @@
# class LoadBalance
*Defined at src/network/nic/load_balance.h#12*
## Members
protected Rng *const _rng
## Functions
### LoadBalance
*public void LoadBalance(Rng *const rng)*
*Defined at src/network/nic/load_balance.h#14*
### update
*public void update(const Packet & pkt)*
### get_entropy
*public uint16_t get_entropy(const Packet & context)*
### ~LoadBalance
*public void ~LoadBalance()*
*Defined at src/network/nic/load_balance.h#15*

View File

@@ -0,0 +1,64 @@
# class Logger
*Defined at src/core/logger.h#19*
## Functions
### Logger
*public void Logger(std::string_view path, bool append)*
### Logger
*public void Logger(const Logger & )*
*Defined at src/core/logger.h#24*
### operator=
*public Logger & operator=(const Logger & )*
*Defined at src/core/logger.h#25*
### Logger
*public void Logger(Logger && )*
*Defined at src/core/logger.h#26*
### operator=
*public Logger & operator=(Logger && )*
*Defined at src/core/logger.h#27*
### is_open
*public bool is_open()*
*Defined at src/core/logger.h#29*
### ~Logger
*public void ~Logger()*
### write_line
*public void write_line(std::string_view line)*
### flush
*public void flush()*
### close
*public void close()*
### path
*public std::string_view path()*
*Defined at src/core/logger.h#38*

View File

@@ -0,0 +1,20 @@
# struct McTree
*Defined at src/network/switch/multicast_table.h#14*
## Members
public vector child_ports
public optional parent_port
public uint8_t weight
public uint8_t tier
public uint16_t tree_id
public uint8_t epoch

View File

@@ -0,0 +1,18 @@
# struct MgmtMsg
*Defined at src/hosts/mgmt_msg.h#11*
## Functions
### kind
*public MgmtKind kind()*
### ~MgmtMsg
*public void ~MgmtMsg()*
*Defined at src/hosts/mgmt_msg.h#12*

View File

@@ -0,0 +1,52 @@
# class MulticastTable
*Defined at src/network/switch/multicast_table.h#23*
## Functions
### MulticastTable
*public void MulticastTable()*
### add_tree
*public bool add_tree(std::size_t group_id, uint16_t tree_id)*
### delete_tree
*public bool delete_tree(std::size_t group_id, uint16_t tree_id)*
### add_child_port
*public bool add_child_port(std::size_t group_id, uint16_t tree_id, PortId out_port)*
### delete_child_port
*public bool delete_child_port(std::size_t group_id, uint16_t tree_id, PortId out_port)*
### set_parent
*public bool set_parent(std::size_t group_id, uint16_t tree_id, PortId parent)*
### set_weight
*public bool set_weight(std::size_t group_id, uint16_t tree_id, uint8_t w)*
### set_epoch
*public bool set_epoch(std::size_t group_id, uint16_t tree_id, uint8_t epoch)*
### trees_of
*public const std::vector<McTree> * trees_of(std::size_t group_id)*
### group_count
*public std::size_t group_count()*
### get_port_list
*public std::vector<PortId> get_port_list(PacketGroups groups)*

View File

@@ -0,0 +1,20 @@
# class NSCC
*Defined at src/network/nic/congestion_control.h#39*
Inherits from CongestionControl
## Functions
### NSCC
*public void NSCC(Bytes init_cwnd, Bytes max_cwnd)*
### update
*public void update(const Packet & pkt, Time rtt)*

View File

@@ -0,0 +1,54 @@
# class NetworkNic
*Defined at src/network/network_nic.h#31*
Inherits from NetworkNode
## Functions
### NetworkNic
*public void NetworkNic(Simulator *const sim, NodeId id, uint16_t total_ports, SwitchBuffer *const buf, Time nic_latency, Bytes mice_elephant_threshold, PacketSeq ooo_threshold, CCType cc_type, LBType lb_type, Bytes cc_init_cwnd, Bytes cc_max_cwnd, const NicSchedulingWeights & schedw)*
### recv_pkt
*public void recv_pkt(Packet & pkt, PortId ingress)*
### attach_host
*public void attach_host(Host * host)*
### detach_host
*public void detach_host(Host * host)*
### send_flow
*public void send_flow(NodeId dst, Bytes size, FlowPriority desired)*
### send_flow
*public void send_flow(PacketGroups group_mask, Bytes size, FlowPriority desired)*
### set_status
*public void set_status(NodeStatus s, Time new_latency)*
### set_port_blacklisted
*public void set_port_blacklisted(PortId port, bool blacklisted)*
### is_port_blacklisted
*public bool is_port_blacklisted(PortId port)*
### telemetry
*public const NicTelemetry & telemetry()*
*Defined at src/network/network_nic.h#59*

View File

@@ -0,0 +1,26 @@
# class NetworkNode
*Defined at src/network/network_node.h#12*
Inherits from Node
## Functions
### NetworkNode
*public void NetworkNode(Simulator *const sim, NodeId id, NodeType type)*
### recv_pkt
*public void recv_pkt(Packet & pkt, PortId ingress)*
### ~NetworkNode
*public void ~NetworkNode()*
*Defined at src/network/network_node.h#17*

View File

@@ -0,0 +1,36 @@
# class NetworkSwitch
*Defined at src/network/network_switch.h#19*
Inherits from NetworkNode
## Functions
### NetworkSwitch
*public void NetworkSwitch(Simulator *const sim, NodeId id, uint16_t total_ports, ECNEngine *const ecn, SwitchBuffer *const buf, const RoutingTables *const rt, Time forwarding_latency, Time multicast_dup_delay)*
### get_status
*public NodeStatus get_status()*
*Defined at src/network/network_switch.h#38*
### port_cnt
*public uint16_t port_cnt()*
*Defined at src/network/network_switch.h#42*
### recv_pkt
*public void recv_pkt(Packet & pkt, PortId ingress)*
### set_status
*public void set_status(NodeStatus s, Time new_forward_latency)*

View File

@@ -0,0 +1,16 @@
# struct NicSchedulingWeights
*Defined at src/network/network_nic.h#23*
## Members
public Bytes control
public Bytes retrans
public Bytes mice
public Bytes elephant

View File

@@ -0,0 +1,32 @@
# struct NicTelemetry
*Defined at src/network/nic/nic_telemetry.h#8*
## Members
public std::uint64_t rx_acks
public std::uint64_t rx_nacks
public std::uint64_t rx_trims
public std::uint64_t rx_data
public std::uint64_t tx_acks
public std::uint64_t tx_nacks
public std::uint64_t tx_trims
public std::uint64_t tx_data
public std::uint64_t retrans
public std::uint64_t timeouts
public std::uint64_t cc_updates
public std::uint64_t lb_updates

View File

@@ -0,0 +1,66 @@
# class Node
*Defined at src/core/node.h#12*
## Members
protected Simulator *const _sim
protected NodeId _id
protected NodeStatus _status
protected NodeType _type
## Functions
### Node
*public void Node(Simulator *const sim, NodeId id, NodeType type)*
### id
*public NodeId id()*
### status
*public NodeStatus status()*
### type
*public NodeType type()*
### set_status
*public void set_status(NodeStatus s)*
### boot
*public void boot(Time boottime_ns)*
### reboot
*public void reboot(Time boottime_ns)*
### ~Node
*public void ~Node()*
*Defined at src/core/node.h#15*
### Node
*public void Node(const Node & )*
*Defined at src/core/node.h#26*
### operator=
*public Node & operator=(const Node & )*
*Defined at src/core/node.h#27*

View File

@@ -0,0 +1,136 @@
# class Packet
*Defined at src/network/packet.h#18*
## Functions
### Packet
*public void Packet(NodeId src_node, PortId src_port, NodeId dst_node, PortId dst_port, PacketProtocol proto, FlowPriority prio, PacketSeq seq, FlowId flow, uint16_t entropy, uint8_t notifications, Bytes payload_bytes)*
### src_node
*public NodeId src_node()*
### src_port
*public PortId src_port()*
### dst_node
*public NodeId dst_node()*
### dst_port
*public PortId dst_port()*
### protocol
*public PacketProtocol protocol()*
### seq
*public PacketSeq seq()*
### flow_id
*public FlowId flow_id()*
### entropy
*public uint32_t entropy()*
### set_src_node
*public void set_src_node(NodeId n)*
### set_src_port
*public void set_src_port(PortId p)*
### set_dst_node
*public void set_dst_node(NodeId n)*
### set_dst_port
*public void set_dst_port(PortId p)*
### set_seq
*public void set_seq(PacketSeq s)*
### set_flow_id
*public void set_flow_id(FlowId f)*
### set_entropy
*public void set_entropy(uint32_t e)*
### set_protocol
*public void set_protocol(PacketProtocol p)*
### set_payload_size
*public void set_payload_size(Bytes size)*
### set_ecn_enabled
*public void set_ecn_enabled(bool v)*
### set_ecn_marked
*public void set_ecn_marked(bool v)*
### set_eof
*public void set_eof(bool v)*
### is_ecn_enabled
*public bool is_ecn_enabled()*
### is_ecn
*public bool is_ecn()*
### is_eof
*public bool is_eof()*
### priority
*public FlowPriority priority()*
### priority_raw
*public uint8_t priority_raw()*
### header_size
*public Bytes header_size()*
### payload_size
*public Bytes payload_size()*
### total_size
*public Bytes total_size()*
### groups
*public PacketGroups groups()*
### set_groups
*public void set_groups(PacketGroups g)*
### add_groups
*public void add_groups(PacketGroups gmask)*

View File

@@ -0,0 +1,18 @@
# struct PubBasePolicy
*Defined at src/hosts/policies.h#13*
## Functions
### select_multicast_groups
*public PacketGroups select_multicast_groups(PacketGroups update_groups_mask)*
### ~PubBasePolicy
*public void ~PubBasePolicy()*
*Defined at src/hosts/policies.h#14*

View File

@@ -0,0 +1,30 @@
# class PubRRPolicy
*Defined at src/hosts/policies.h#20*
Inherits from PubBasePolicy
## Records
ReplicaRange
## Functions
### PubRRPolicy
*public void PubRRPolicy(std::vector<ReplicaRange> ranges)*
*Defined at src/hosts/policies.h#28*
### select_multicast_groups
*public PacketGroups select_multicast_groups(PacketGroups update_groups_mask)*
*Defined at src/hosts/policies.h#33*

View File

@@ -0,0 +1,14 @@
# struct ReplicaRange
*Defined at src/hosts/policies.h#22*
## Members
public uint32_t update_group
public uint8_t low_bit
public uint8_t high_bit

View File

@@ -0,0 +1,48 @@
# class Publisher
*Defined at src/hosts/publisher.h#17*
Inherits from Host
## Functions
### Publisher
*public void Publisher(Simulator * sim, NodeId id, Time update_latency_base, std::unique_ptr<PubBasePolicy> policy, Time mgmt_latency)*
### recv_update
*public void recv_update(Bytes size, PacketGroups update_groups_mask)*
### set_status
*public void set_status(NodeStatus s, Time new_latency)*
### recv_mgmt_msg
*public void recv_mgmt_msg(MgmtMsgPtr msg)*
### recv_flow
*public void recv_flow(NodeId src, FlowId flow, FlowPriority prio, Bytes flow_size)*
### recv_frame
*public void recv_frame(const Packet & frame)*
### updates_in
*public uint64_t updates_in()*
*Defined at src/hosts/publisher.h#40*
### bytes_out
*public uint64_t bytes_out()*
*Defined at src/hosts/publisher.h#43*

View File

@@ -0,0 +1,62 @@
# class Rng
*Defined at src/core/rng.h#14*
## Functions
### Rng
*public void Rng(seed_type seed)*
*Defined at src/core/rng.h#19*
### seed
*public void seed(seed_type s)*
*Defined at src/core/rng.h#22*
### uniform01
*public double uniform01()*
*Defined at src/core/rng.h#27*
### uniform_range
*public Int uniform_range(Int lo_inclusive, Int hi_exclusive)*
*Defined at src/core/rng.h#34*
### uniform_range
*public Int uniform_range(Int hi_exclusive)*
*Defined at src/core/rng.h#41*
### uniform_range
*public double uniform_range(double lo_inclusive, double hi_exclusive)*
*Defined at src/core/rng.h#45*
### poisson
*public std::uint64_t poisson(double lambda)*
*Defined at src/core/rng.h#50*
### choose_weighted
*public T choose_weighted(const std::vector<std::pair<double, T>> & items)*
*Defined at src/core/rng.h#56*
### choose_weighted
*public T choose_weighted(std::initializer_list<std::pair<double, T>> items)*
*Defined at src/core/rng.h#61*

View File

@@ -0,0 +1,12 @@
# struct RoutingTables
*Defined at src/network/switch/routing_tables.h#9*
## Members
public UnicastTable unicast
public MulticastTable multicast

View File

@@ -0,0 +1,44 @@
# class SharedBuffer
*Defined at src/network/switch/shared_buffer.h#10*
Inherits from SwitchBuffer
## Functions
### SharedBuffer
*public void SharedBuffer(Simulator *const sim, NetworkSwitch *const owner, Bytes total_bytes, uint16_t ports)*
### enqueue_packet
*public bool enqueue_packet(const Packet & pkt, PortId egress, FlowPriority prio)*
### drain_one
*public bool drain_one(PortId port)*
### queues_for
*protected std::array<std::deque<Queued>, PRI_COUNT> & queues_for(PortId p)*
### queues_for
*protected const std::array<std::deque<Queued>, PRI_COUNT> & queues_for(PortId p)*
### on_enqueue_cap_check
*protected bool on_enqueue_cap_check(PortId port, Bytes sz)*
### on_enqueue_commit
*protected void on_enqueue_commit(PortId port, Bytes sz)*
### on_dequeue_commit
*protected void on_dequeue_commit(PortId port, Bytes sz)*

View File

@@ -0,0 +1,22 @@
# class SharedREDEngine
*Defined at src/network/switch/ecn_shared_red.h#18*
Inherits from ECNEngine
## Functions
### SharedREDEngine
*public void SharedREDEngine(Rng *const rng)*
*Defined at src/network/switch/ecn_shared_red.h#20*
### process_packet
*public Packet & process_packet(Packet & pkt, SwitchBuffer * buf)*

View File

@@ -0,0 +1,88 @@
# class Simulator
*Defined at src/core/simulator.h#34*
## Functions
### Simulator
*public void Simulator()*
*Defined at src/core/simulator.h#58*
### create_simulator
*public std::pair<InstanceId, Simulator *> create_simulator(InstanceId id)*
### get_simulator
*public Simulator * get_simulator(InstanceId id)*
### is_locked
*public bool is_locked()*
*Defined at src/core/simulator.h#96*
### now
*public Time now()*
### cancel
*public bool cancel(EventId id)*
### run_next
*public bool run_next()*
### run_until
*public void run_until(Time end_time)*
### lock
*public void lock()*
### flush_after
*public void flush_after(Time grace)*
### create_rng
*public Rng * create_rng(std::uint64_t seed)*
### get_rng
*public Rng * get_rng()*
### get_rng
*public const Rng * get_rng()*
### create_link
*public std::pair<LinkId, Link *> create_link(NetworkNode * a, PortId a_port, NetworkNode * b, PortId b_port, Time latency, double bandwidth_gbps)*
### get_link
*public Link * get_link(LinkId id)*
### get_link
*public const Link * get_link(LinkId id)*
### schedule_at
*public EventId schedule_at(Time abs_time, F && f, Args &&... args)*
*Defined at src/core/simulator.h#66*
### schedule_after
*public EventId schedule_after(Time delay, F && f, Args &&... args)*
*Defined at src/core/simulator.h#84*

View File

@@ -0,0 +1,14 @@
# struct SubBasePolicy
*Defined at src/hosts/policies.h#76*
## Functions
### ~SubBasePolicy
*public void ~SubBasePolicy()*
*Defined at src/hosts/policies.h#77*

View File

@@ -0,0 +1,18 @@
# struct SubDummyPolicy
*Defined at src/hosts/policies.h#80*
Inherits from SubBasePolicy
## Functions
### ~SubDummyPolicy
*public void ~SubDummyPolicy()*
*Defined at src/hosts/policies.h#81*

View File

@@ -0,0 +1,38 @@
# class Subscriber
*Defined at src/hosts/subscriber.h#15*
Inherits from Host
## Functions
### Subscriber
*public void Subscriber(Simulator * sim, NodeId id, Publisher * publisher, std::unique_ptr<SubBasePolicy> policy, Time mgmt_latency, Time heartbeat_period)*
### recv_mgmt_msg
*public void recv_mgmt_msg(MgmtMsgPtr msg)*
### recv_flow
*public void recv_flow(NodeId src, FlowId flow, FlowPriority prio, Bytes flow_size)*
### recv_frame
*public void recv_frame(const Packet & frame)*
### set_publisher
*public void set_publisher(Publisher * p)*
*Defined at src/hosts/subscriber.h#35*
### set_status
*public void set_status(NodeStatus s)*

View File

@@ -0,0 +1,168 @@
# class SwitchBuffer
*Defined at src/network/switch/switch_buffer.h#22*
## Members
protected Simulator *const _sim
protected NetworkSwitch *const _owner
protected SwitchBufferType _type
protected Bytes _buffer_bytes
protected uint16_t _port_cnt
protected vector _egress_links
protected vector _drain_scheduled
protected vector _per_port_bytes
protected vector _sched
protected uint8_t _share_ctrl
protected uint8_t _share_mice
protected uint8_t _share_ele
## Records
PerPortSched
Queued
## Functions
### enqueue_packet
*public bool enqueue_packet(const Packet & pkt, PortId egress, FlowPriority prio)*
### drain_one
*public bool drain_one(PortId port)*
### buffer_size
*public Bytes buffer_size()*
### type
*public SwitchBufferType type()*
### port_cnt
*public uint16_t port_cnt()*
### port_buffered
*public Bytes port_buffered(PortId p)*
### ports_buffered
*public const std::vector<Bytes> & ports_buffered()*
### share_ctrl
*public uint8_t share_ctrl()*
### share_mice
*public uint8_t share_mice()*
### share_elephant
*public uint8_t share_elephant()*
### set_share_ctrl
*public void set_share_ctrl(uint8_t pct)*
### set_share_mice
*public void set_share_mice(uint8_t pct)*
### set_share_elephant
*public void set_share_elephant(uint8_t pct)*
### simulator
*public const Simulator * simulator()*
### owner
*public const NetworkSwitch * owner()*
### set_egress_links
*public void set_egress_links(const std::vector<Link *> & links)*
### SwitchBuffer
*protected void SwitchBuffer(Simulator *const sim, NetworkSwitch *const owner, SwitchBufferType t, Bytes total_bytes, uint16_t ports)*
### drain_one_common
*protected bool drain_one_common(PortId port)*
### schedule_drain_if_needed
*protected void schedule_drain_if_needed(PortId port)*
### drain_once
*protected void drain_once(PortId port)*
### queues_for
*protected std::array<std::deque<Queued>, PRI_COUNT> & queues_for(PortId p)*
### queues_for
*protected const std::array<std::deque<Queued>, PRI_COUNT> & queues_for(PortId p)*
### on_enqueue_cap_check
*protected bool on_enqueue_cap_check(PortId port, Bytes sz)*
### on_enqueue_commit
*protected void on_enqueue_commit(PortId port, Bytes sz)*
### on_dequeue_commit
*protected void on_dequeue_commit(PortId port, Bytes sz)*
### ~SwitchBuffer
*public void ~SwitchBuffer()*
*Defined at src/network/switch/switch_buffer.h#32*
### to_idx
*protected int to_idx(FlowPriority p)*
*Defined at src/network/switch/switch_buffer.h#83*
### try_reserve_and_send
*protected std::optional<Time> try_reserve_and_send(PortId port, Queued & q)*
### queued_bytes_total
*protected Bytes queued_bytes_total()*
### queued_bytes_port
*protected Bytes queued_bytes_port(PortId p)*

View File

@@ -0,0 +1,12 @@
# struct PerPortSched
*Defined at src/network/switch/switch_buffer.h#104*
## Members
public array deficit_bytes
public int next_pick

View File

@@ -0,0 +1,18 @@
# struct Queued
*Defined at src/network/switch/switch_buffer.h#24*
## Members
public Packet pkt
public PortId egress
public FlowPriority prio
public Time enq_time
public Bytes size_bytes

View File

@@ -0,0 +1,86 @@
# class Time
*Defined at src/core/time.h#9*
## Functions
### Time
*public void Time()*
*Defined at src/core/time.h#14*
### Time
*public void Time(rep ns)*
*Defined at src/core/time.h#15*
### from_ns
*public Time from_ns(rep ns)*
*Defined at src/core/time.h#18*
### from_us
*public Time from_us(rep us)*
*Defined at src/core/time.h#21*
### from_ms
*public Time from_ms(rep ms)*
*Defined at src/core/time.h#24*
### from_s
*public Time from_s(rep s)*
*Defined at src/core/time.h#27*
### ns
*public rep ns()*
*Defined at src/core/time.h#32*
### count
*public rep count()*
*Defined at src/core/time.h#35*
### us_to_ns
*public rep us_to_ns(rep us)*
*Defined at src/core/time.h#40*
### ms_to_ns
*public rep ms_to_ns(rep ms)*
*Defined at src/core/time.h#43*
### operator+=
*public Time & operator+=(Time rhs)*
*Defined at src/core/time.h#73*
### operator-=
*public Time & operator-=(Time rhs)*
*Defined at src/core/time.h#77*
### unsafe_sub
*public Time unsafe_sub(Time t)*
*Defined at src/core/time.h#106*

View File

@@ -0,0 +1,38 @@
# class Timer
*Defined at src/core/timer.h#9*
## Functions
### Timer
*public void Timer()*
*Defined at src/core/timer.h#11*
### init
*public void init()*
*Defined at src/core/timer.h#15*
### start
*public Time start()*
*Defined at src/core/timer.h#19*
### now
*public Time now()*
*Defined at src/core/timer.h#29*
### elapsed
*public Time elapsed()*
*Defined at src/core/timer.h#39*

View File

@@ -0,0 +1,26 @@
# class UnicastTable
*Defined at src/network/switch/unicast_table.h#13*
## Functions
### UnicastTable
*public void UnicastTable()*
*Defined at src/network/switch/unicast_table.h#15*
### get_port_list
*public std::vector<PortId> get_port_list(NodeId dst_node, PortId dst_port)*
### add_entry
*public bool add_entry(NodeId dst_node, PortId dst_port, PortId out_port)*
### delete_entry
*public bool delete_entry(NodeId dst_node, PortId dst_port, PortId out_port)*

View File

@@ -0,0 +1,274 @@
# namespace dofs
## Records
* [CongestionControl](CongestionControl.md)
* [DCQCN](DCQCN.md)
* [DedicatedBuffer](DedicatedBuffer.md)
* [DedicatedREDEngine](DedicatedREDEngine.md)
* [ECNEngine](ECNEngine.md)
* [EndSimulationMsg](EndSimulationMsg.md)
* [HeartbeatMsg](HeartbeatMsg.md)
* [Host](Host.md)
* [JobFinishedMsg](JobFinishedMsg.md)
* [LBRandomPacketSpraying](LBRandomPacketSpraying.md)
* [Link](Link.md)
* [LoadBalance](LoadBalance.md)
* [Logger](Logger.md)
* [McTree](McTree.md)
* [MgmtMsg](MgmtMsg.md)
* [MulticastTable](MulticastTable.md)
* [NSCC](NSCC.md)
* [NetworkNic](NetworkNic.md)
* [NetworkNode](NetworkNode.md)
* [NetworkSwitch](NetworkSwitch.md)
* [NicSchedulingWeights](NicSchedulingWeights.md)
* [NicTelemetry](NicTelemetry.md)
* [Node](Node.md)
* [Packet](Packet.md)
* [PubBasePolicy](PubBasePolicy.md)
* [PubRRPolicy](PubRRPolicy.md)
* [Publisher](Publisher.md)
* [Rng](Rng.md)
* [RoutingTables](RoutingTables.md)
* [SharedBuffer](SharedBuffer.md)
* [SharedREDEngine](SharedREDEngine.md)
* [Simulator](Simulator.md)
* [SubBasePolicy](SubBasePolicy.md)
* [SubDummyPolicy](SubDummyPolicy.md)
* [Subscriber](Subscriber.md)
* [SwitchBuffer](SwitchBuffer.md)
* [Time](Time.md)
* [Timer](Timer.md)
* [UnicastTable](UnicastTable.md)
## Functions
### show
*T && show(std::string_view name, T && value)*
*Defined at src/core/error.h#21*
### eval_and_show
*T && eval_and_show(std::string_view expr, T && value)*
*Defined at src/core/error.h#28*
### hash_ecmp
*PortId hash_ecmp(NodeId src_node, PortId src_port, NodeId dst_node, PortId dst_port, uint32_t differentiator, uint16_t port_count)*
### error_mutex
*std::mutex & error_mutex()*
### hash_ecmp
*PortId hash_ecmp(NodeId src_node, NodeId dst_node, uint32_t differentiator, uint16_t port_count)*
*Defined at src/network/switch/routing_alg.h#15*
### ipv4
*IPv4Addr ipv4(NodeId n, PortId p)*
*Defined at src/core/types.h#31*
### log_error
*void log_error(std::string_view type, std::string_view message, std::optional<uint64_t> timestamp)*
### operator==
*bool operator==(Time a, Time b)*
*Defined at src/core/time.h#48*
### operator!=
*bool operator!=(Time a, Time b)*
*Defined at src/core/time.h#52*
### operator<
*bool operator<(Time a, Time b)*
*Defined at src/core/time.h#56*
### operator>
*bool operator>(Time a, Time b)*
*Defined at src/core/time.h#60*
### operator<=
*bool operator<=(Time a, Time b)*
*Defined at src/core/time.h#64*
### operator>=
*bool operator>=(Time a, Time b)*
*Defined at src/core/time.h#68*
### operator+
*Time operator+(Time a, Time b)*
*Defined at src/core/time.h#86*
### operator*
*Time operator*(Time a, Time b)*
*Defined at src/core/time.h#90*
### operator-
*std::optional<Time> operator-(Time a, Time b)*
*Defined at src/core/time.h#94*
### safe_sub
*std::optional<Time> safe_sub(Time a, Time b)*
*Defined at src/core/time.h#98*
### operator""_ns
*Time operator""_ns(unsigned long long v)*
*Defined at src/core/time.h#114*
### operator""_us
*Time operator""_us(unsigned long long v)*
*Defined at src/core/time.h#117*
### operator""_ms
*Time operator""_ms(unsigned long long v)*
*Defined at src/core/time.h#120*
### operator""_s
*Time operator""_s(unsigned long long v)*
*Defined at src/core/time.h#123*
## Enums
| enum class NodeStatus |
--
| OK |
| THROTTLING |
| DOWN |
| BOOTING |
*Defined at src/core/types.h#15*
| enum class NodeType |
--
| HOST |
| SWITCH |
| NIC |
*Defined at src/core/types.h#22*
| enum class LinkStatus |
--
| OK |
| DOWN |
| THROTTLING |
*Defined at src/core/types.h#36*
| enum class PacketProtocol |
--
| DATA |
| ACK |
| NACK |
| HEADER_TRIM |
| HEADER_TRIM_BACK |
*Defined at src/core/types.h#42*
| enum class SwitchBufferType |
--
| SHARED |
| DEDICATED |
*Defined at src/core/types.h#50*
| enum class FlowPriority |
--
| CTRL |
| MICE |
| ELEPHANT |
| AUTO |
*Defined at src/core/types.h#52*
| enum class CCType |
--
| DCQCN |
| NSCC |
*Defined at src/core/types.h#59*
| enum class LBType |
--
| RANDOM_PACKET_SPRAYING |
*Defined at src/core/types.h#64*
| enum class MgmtKind |
--
| HEARTBEAT |
| JOB_FINISHED |
| END_SIMULATION |
*Defined at src/core/types.h#68*

3
docs/clang-doc/index.md Normal file
View File

@@ -0,0 +1,3 @@
# DOFS C/C++ Reference
* Namespace: [dofs](dofs)

View File

@@ -1,4 +1,5 @@
#include "core/host.h"
#include "core/error.h"
namespace dofs {

View File

@@ -27,12 +27,15 @@ public:
// Data-plane completion: a whole flow has arrived.
virtual void recv_flow(NodeId src,
FlowId flow,
FlowPriority priority,
Bytes flow_size) = 0;
// Control/telemetry interrupt: ACK/NACK/TRIM_BACK, etc.
virtual void recv_frame(const Packet& frame) = 0;
virtual void recv_mgmt_msg(std::unique_ptr<struct MgmtMsg> msg) = 0;
Host(const Host &) = delete;
Host &operator=(const Host &) = delete;

View File

@@ -49,7 +49,25 @@ void Simulator::run_until(Time end_time) {
}
}
std::vector<std::unique_ptr<Simulator>>& Simulator::registry_() {
void Simulator::lock() noexcept {
_locked = true;
}
void Simulator::flush_after(Time grace) noexcept {
_locked = true;
const Time deadline = _now + grace;
run_until(deadline);
while (!_event_pq.empty()) {
_event_pq.pop();
}
_cancelled.clear();
}
std::vector<std::unique_ptr<Simulator>>& Simulator::_registry() {
static std::vector<std::unique_ptr<Simulator>> reg;
return reg;
}
@@ -59,7 +77,7 @@ std::pair<InstanceId, Simulator *> Simulator::create_simulator(InstanceId id) {
return {INVALID_INSTANCE_ID, nullptr};
}
auto& reg = registry_();
auto& reg = _registry();
if (static_cast<size_t>(id) >= reg.size()) {
reg.resize(static_cast<size_t>(id) + 1);
@@ -79,7 +97,7 @@ Simulator * Simulator::get_simulator(InstanceId id) noexcept {
if (id == INVALID_INSTANCE_ID)
return nullptr;
auto& reg = registry_();
auto& reg = _registry();
const size_t idx = static_cast<size_t>(id);
if (idx >= reg.size())

View File

@@ -1,8 +1,6 @@
#ifndef CORE_SIMULATOR_H
#define CORE_SIMULATOR_H
// TODO: implement concrete node methods for different nodes, store them all uniformly in vector<u_ptr<Node>> and return a get function
#include <cstdint>
#include <functional>
#include <queue>
@@ -49,6 +47,7 @@ private:
std::unordered_set<EventId> _cancelled;
Time _now{};
EventId _next_id{1};
bool _locked{false};
std::unique_ptr<Rng> _rng;
@@ -65,6 +64,9 @@ public:
template <class F, class... Args>
EventId schedule_at(Time abs_time, F&& f, Args&&... args) {
if (_locked)
return NULL_EVENT;
if (abs_time < _now)
return NULL_EVENT;
@@ -88,6 +90,15 @@ public:
bool run_next();
void run_until(Time end_time);
// ----- Termination helpers -----
// Prevent any future schedule_* calls from enqueuing events.
void lock() noexcept;
bool is_locked() const noexcept {
return _locked;
}
// Lock, then run all events up to now()+grace, finally discard any remaining.
void flush_after(Time grace) noexcept;
// ---------- Object management ----------
Rng* create_rng(std::uint64_t seed);
Rng* get_rng() noexcept;
@@ -112,7 +123,7 @@ private:
};
}
static std::vector<std::unique_ptr<Simulator>>& registry_();
static std::vector<std::unique_ptr<Simulator>>& _registry();
};
} // namespace dofs

View File

@@ -65,6 +65,12 @@ enum class LBType : uint8_t {
RANDOM_PACKET_SPRAYING
};
enum class MgmtKind : uint8_t {
HEARTBEAT,
JOB_FINISHED,
END_SIMULATION
};
} // namespace dofs
#endif // CORE_TYPES_H

View File

@@ -8,7 +8,7 @@ target_include_directories(dofs_hosts
$<INSTALL_INTERFACE:include>
)
target_link_libraries(dofs_hosts PUBLIC dofs_core)
target_link_libraries(dofs_hosts PUBLIC dofs_core dofs_network)
if(DOFS_GLOB_SOURCES)
file(GLOB HOSTS_CC CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cc")
@@ -18,9 +18,13 @@ if(DOFS_GLOB_SOURCES)
else()
target_sources(dofs_hosts
PUBLIC
nodes_dummy.h
mgmt_msg.h
policies.h
publisher.h
subscriber.h
PRIVATE
nodes_dummy.cc
publisher.cc
subscriber.cc
)
endif()
@@ -39,7 +43,12 @@ endforeach()
add_library(dofs_hosts_headers_tooling STATIC ${HOSTS_STUBS})
# inherit include dirs/usage reqs from dofs_hosts
target_link_libraries(dofs_hosts_headers_tooling PRIVATE dofs_hosts dofs_core)
target_link_libraries(
dofs_hosts_headers_tooling
PRIVATE
dofs_hosts
dofs_core
dofs_network)
# This ensures the same -I flags even if cmake-ide builds the stubs alone
target_include_directories(dofs_hosts_headers_tooling

51
src/hosts/mgmt_msg.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef HOSTS_MGMT_MSG_H
#define HOSTS_MGMT_MSG_H
#include <cstdint>
#include <memory>
#include "core/time.h"
#include "core/types.h"
namespace dofs {
struct MgmtMsg {
virtual ~MgmtMsg() = default;
virtual MgmtKind kind() const noexcept = 0;
};
struct HeartbeatMsg final : public MgmtMsg {
NodeId subscriber_id;
NodeStatus status;
Time generated_at;
explicit HeartbeatMsg(NodeId sid, NodeStatus st, Time t) noexcept
: subscriber_id(sid), status(st), generated_at(t) {}
MgmtKind kind() const noexcept override {
return MgmtKind::HEARTBEAT;
}
};
struct JobFinishedMsg final : public MgmtMsg {
FlowId flow_id;
Time finished_at;
explicit JobFinishedMsg(FlowId fid, Time t) noexcept
: flow_id(fid), finished_at(t) {}
MgmtKind kind() const noexcept override {
return MgmtKind::JOB_FINISHED;
}
};
struct EndSimulationMsg final : public MgmtMsg {
MgmtKind kind() const noexcept override {
return MgmtKind::END_SIMULATION;
}
};
using MgmtMsgPtr = std::unique_ptr<MgmtMsg>;
} // namespace dofs
#endif // HOSTS_MGMT_MSG_H

View File

@@ -1,6 +0,0 @@
#include "core/error.h"
#include "core/logger.h"
namespace dofs {
int _nodes_tooling_dummy = 0;
}

View File

@@ -1,4 +0,0 @@
#ifndef NODES_DUMMY
#define NODES_DUMMY
#endif

86
src/hosts/policies.h Normal file
View File

@@ -0,0 +1,86 @@
#ifndef HOSTS_POLICIES_H
#define HOSTS_POLICIES_H
#include <cstdint>
#include <vector>
#include <unordered_map>
#include <cassert>
#include "core/types.h"
namespace dofs {
// Abstract publisher policy: map logical update groups → concrete multicast mask.
struct PubBasePolicy {
virtual ~PubBasePolicy() = default;
virtual PacketGroups select_multicast_groups(PacketGroups update_groups_mask) =
0;
};
// Round-robin policy over bit ranges per logical group.
class PubRRPolicy final : public PubBasePolicy {
public:
struct ReplicaRange {
uint32_t update_group; // logical group id you use in your workload file
uint8_t low_bit; // inclusive, < 128
uint8_t high_bit; // inclusive, < 128
};
explicit PubRRPolicy(std::vector<ReplicaRange> ranges)
: _ranges(std::move(ranges)) {
validate_and_build();
}
PacketGroups select_multicast_groups(PacketGroups update_groups_mask) override {
PacketGroups result = 0;
for (auto const& r : _ranges) {
if (!group_present(update_groups_mask, r.update_group))
continue;
const uint8_t width = static_cast<uint8_t>(r.high_bit - r.low_bit + 1);
uint8_t &cursor = _rr_cursor[r.update_group];
uint8_t chosen = static_cast<uint8_t>(r.low_bit + (cursor % width));
cursor = static_cast<uint8_t>((cursor + 1) % width);
result |= (PacketGroups(1) << chosen);
}
return result;
}
private:
std::vector<ReplicaRange> _ranges;
std::unordered_map<uint32_t, uint8_t> _rr_cursor; // per logical group
static bool group_present(PacketGroups mask, uint32_t gid) noexcept {
// convention: logical update groups are not bits, theyre ids you pass in;
// presence is determined outside—if you want bitwise presence, adapt here later.
// For now, assume any nonzero mask means all configured groups are requested.
(void)gid;
return mask != 0;
}
void validate_and_build() {
for (auto const& r : _ranges) {
assert(r.low_bit <= r.high_bit);
assert(r.high_bit < 128 && r.low_bit < 128);
(void)r;
// Non-overlap across different logical groups is allowed.
}
// init all cursors to 0 for determinism.
for (auto const& r : _ranges)
_rr_cursor[r.update_group] = 0;
}
};
struct SubBasePolicy {
virtual ~SubBasePolicy() = default;
};
struct SubDummyPolicy final : public SubBasePolicy {
~SubDummyPolicy() override = default;
};
} // namespace dofs
#endif // HOSTS_POLICIES_H

143
src/hosts/publisher.cc Normal file
View File

@@ -0,0 +1,143 @@
#include "hosts/publisher.h"
#include "core/error.h"
#include "network/network_nic.h"
namespace dofs {
Publisher::Publisher(Simulator *const sim,
NodeId id,
Time update_latency_base,
std::unique_ptr<PubBasePolicy> policy,
Time mgmt_latency) noexcept
: Host(sim, id)
, _sim(sim)
, _update_latency_base(update_latency_base)
, _update_latency_cur(update_latency_base)
, _mgmt_latency(mgmt_latency)
, _policy(std::move(policy)) {}
void Publisher::set_status(NodeStatus s, Time new_latency) noexcept {
// Enforce clamp: new_latency == 0 means "no-op"
if (new_latency.count() != 0 && new_latency < _update_latency_base) {
DOFS_ERROR("publisher", "set_status: new latency below base; ignored");
} else if (new_latency.count() != 0) {
_update_latency_cur = new_latency;
}
// Forward to Node base if available (Host derives from Node).
// If Node::set_status is public, this works; otherwise adjust when you expose it.
// (We keep this call for correctness; remove if not yet available.)
// Node::set_status(s);
if (s == NodeStatus::DOWN) {
if (_staging_evt != NULL_EVENT) {
_sim->cancel(_staging_evt);
_staging_evt = NULL_EVENT;
}
_state = State::Quiesced;
}
}
void Publisher::recv_update(Bytes size,
PacketGroups update_groups_mask) noexcept {
if (size == 0 || update_groups_mask == 0) {
DOFS_ERROR("publisher", "recv_update: invalid size or groups");
return;
}
_queue.push_back(Pending{size, update_groups_mask, _sim->now()});
++_updates_in;
if (_state == State::Idle) {
_state = State::Staging;
arm_staging_if_needed();
}
}
void Publisher::arm_staging_if_needed() noexcept {
if (_staging_evt != NULL_EVENT)
return;
if (_queue.empty()) {
_state = State::Idle;
return;
}
_staging_evt = _sim->schedule_after(_update_latency_cur, [this]() {
this->on_staging_timer();
});
}
void Publisher::on_staging_timer() noexcept {
_staging_evt = NULL_EVENT;
if (_state == State::Quiesced)
return;
if (_queue.empty()) {
_state = State::Idle;
return;
}
Pending p = _queue.front();
_queue.pop_front();
const PacketGroups mcast_mask = _policy ? _policy->select_multicast_groups(
p.mask) : PacketGroups{0};
if (mcast_mask == 0) {
DOFS_ERROR("publisher", "policy produced empty multicast mask");
} else {
auto* n = this->nic();
if (!n) {
DOFS_ERROR("publisher", "no NIC attached; dropping update");
} else {
n->send_flow(mcast_mask, p.size, FlowPriority::MICE);
_bytes_out += p.size;
}
}
// Next
if (_queue.empty()) {
_state = State::Idle;
} else {
arm_staging_if_needed();
}
}
void Publisher::recv_mgmt_msg(MgmtMsgPtr msg) noexcept {
if (!msg)
return;
++_mgmt_in;
switch (msg->kind()) {
case MgmtKind::END_SIMULATION: {
if (_staging_evt != NULL_EVENT) {
_sim->cancel(_staging_evt);
_staging_evt = NULL_EVENT;
}
_state = State::Quiesced;
}
break;
case MgmtKind::HEARTBEAT:
case MgmtKind::JOB_FINISHED:
default:
// informational only for now
break;
}
}
void Publisher::recv_flow(NodeId, FlowId, FlowPriority, Bytes) {
// Publisher is mainly a sender in this workload; ignore data-plane flow arrivals.
}
void Publisher::recv_frame(const Packet &) {
// Control frames not used by Publisher in this stage.
}
} // namespace dofs

79
src/hosts/publisher.h Normal file
View File

@@ -0,0 +1,79 @@
#ifndef HOSTS_PUBLISHER_H
#define HOSTS_PUBLISHER_H
#include <cstdint>
#include <deque>
#include <memory>
#include "core/time.h"
#include "core/types.h"
#include "core/host.h"
#include "core/simulator.h"
#include "hosts/mgmt_msg.h"
#include "hosts/policies.h"
namespace dofs {
class Publisher final : public Host {
public:
Publisher(Simulator* sim,
NodeId id,
Time update_latency_base,
std::unique_ptr<PubBasePolicy> policy,
Time mgmt_latency) noexcept;
// Triggered by workload driver
void recv_update(Bytes size, PacketGroups update_groups_mask) noexcept;
// Status with latency clamp; new_latency==0 means "no change"
void set_status(NodeStatus s, Time new_latency = Time{}) noexcept;
// Mgmt-plane receive (from subscribers)
virtual void recv_mgmt_msg(MgmtMsgPtr msg) noexcept override;
// Host overrides (data-plane callbacks)
virtual void recv_flow(NodeId src, FlowId flow, FlowPriority prio,
Bytes flow_size) override;
virtual void recv_frame(const Packet& frame) override;
// Telemetry
uint64_t updates_in() const noexcept {
return _updates_in;
}
uint64_t bytes_out() const noexcept {
return _bytes_out;
}
private:
enum class State : uint8_t { Idle = 0, Staging = 1, Quiesced = 2 };
struct Pending {
Bytes size{0};
PacketGroups mask{0};
Time enq_time{};
};
void arm_staging_if_needed() noexcept;
void on_staging_timer() noexcept;
private:
Simulator *const _sim;
Time _update_latency_base;
Time _update_latency_cur;
Time _mgmt_latency;
std::unique_ptr<PubBasePolicy> _policy;
State _state{State::Idle};
EventId _staging_evt{NULL_EVENT};
std::deque<Pending> _queue;
// telemetry
uint64_t _updates_in{0};
uint64_t _bytes_out{0};
uint64_t _mgmt_in{0};
uint64_t _mgmt_out{0};
};
} // namespace dofs
#endif // HOSTS_PUBLISHER_H

104
src/hosts/subscriber.cc Normal file
View File

@@ -0,0 +1,104 @@
#include "hosts/subscriber.h"
#include "hosts/publisher.h"
#include "core/error.h"
namespace dofs {
Subscriber::Subscriber(Simulator* sim,
NodeId id,
Publisher* publisher,
std::unique_ptr<SubBasePolicy> policy,
Time mgmt_latency,
Time heartbeat_period) noexcept
: Host(sim, id)
, _sim(sim)
, _publisher(publisher)
, _policy(std::move(policy))
, _mgmt_latency(mgmt_latency)
, _hb_period(heartbeat_period) {
// Deterministic stagger: simple function of NodeId.
Time::rep off = (static_cast<Time::rep>(id) % (std::max<Time::rep>(1,
heartbeat_period.count() / 4)));
schedule_next_heartbeat(Time(off));
}
void Subscriber::set_status(NodeStatus s) noexcept {
// Node::set_status(s);
if (s == NodeStatus::DOWN) {
if (_hb_evt != NULL_EVENT) {
_sim->cancel(_hb_evt);
_hb_evt = NULL_EVENT;
}
_state = State::Quiesced;
}
}
void Subscriber::schedule_next_heartbeat(Time delay) noexcept {
if (_state == State::Quiesced)
return;
_hb_evt = _sim->schedule_after(delay, [this]() {
this->on_heartbeat_timer();
});
}
void Subscriber::on_heartbeat_timer() noexcept {
_hb_evt = NULL_EVENT;
if (_state == State::Quiesced)
return;
if (_publisher) {
const NodeId sid = this->id();
const NodeStatus st = NodeStatus::OK;
const Time gen = _sim->now();
Publisher* const pub = _publisher;
_sim->schedule_after(_mgmt_latency, [pub, sid, st, gen]() {
pub->recv_mgmt_msg(std::make_unique<HeartbeatMsg>(sid, st, gen));
});
}
schedule_next_heartbeat(_hb_period);
}
void Subscriber::send_job_finished(FlowId flow) noexcept {
if (_publisher) {
const Time fin = _sim->now();
_sim->schedule_after(_mgmt_latency, [pub = _publisher, flow, fin]() mutable {
pub->recv_mgmt_msg(std::make_unique<JobFinishedMsg>(flow, fin));
});
}
}
void Subscriber::recv_mgmt_msg(MgmtMsgPtr msg) noexcept {
if (!msg)
return;
if (msg->kind() == MgmtKind::END_SIMULATION) {
if (_hb_evt != NULL_EVENT) {
_sim->cancel(_hb_evt);
_hb_evt = NULL_EVENT;
}
_state = State::Quiesced;
}
}
void Subscriber::recv_flow(NodeId /*src*/, FlowId flow, FlowPriority /*prio*/,
Bytes /*flow_size*/) {
if (_state == State::Quiesced) {
DOFS_ERROR("subscriber", "drop flow: quiesced");
return;
}
// 3-day scope: zero processing delay → immediately report completion.
send_job_finished(flow);
_state = State::Idle;
}
void Subscriber::recv_frame(const Packet & /*frame*/) {
// Not used for this pub/sub workload phase.
}
} // namespace dofs

61
src/hosts/subscriber.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef HOSTS_SUBSCRIBER_H
#define HOSTS_SUBSCRIBER_H
#include <cstdint>
#include <memory>
#include "core/host.h"
#include "core/simulator.h"
#include "hosts/mgmt_msg.h"
#include "hosts/policies.h"
namespace dofs {
class Publisher;
class Subscriber final : public Host {
public:
Subscriber(Simulator* sim,
NodeId id,
Publisher* publisher,
std::unique_ptr<SubBasePolicy> policy,
Time mgmt_latency,
Time heartbeat_period) noexcept;
// Mgmt-plane receive (from publisher)
virtual void recv_mgmt_msg(MgmtMsgPtr msg) noexcept override;
// Host overrides (data-plane callbacks)
void recv_flow(NodeId src, FlowId flow, FlowPriority prio,
Bytes flow_size) override;
void recv_frame(const Packet& frame) override;
void set_status(NodeStatus s) noexcept;
// For future: swap publisher pointer
void set_publisher(Publisher* p) noexcept {
_publisher = p;
}
private:
enum class State : uint8_t { Idle = 0, Processing = 1, Quiesced = 2 };
void schedule_next_heartbeat(Time delay) noexcept;
void on_heartbeat_timer() noexcept;
void send_job_finished(FlowId flow) noexcept;
private:
Simulator *_sim;
Publisher *_publisher;
std::unique_ptr<SubBasePolicy> _policy;
Time _mgmt_latency;
Time _hb_period;
EventId _hb_evt{NULL_EVENT};
State _state{State::Idle};
// simple token generator for completions (since FlowId not surfaced here)
uint64_t _next_token{1};
};
} // namespace dofs
#endif // HOSTS_SUBSCRIBER_H

View File

@@ -165,7 +165,8 @@ void NetworkNic::recv_pkt(Packet &pkt_in, PortId ingress) {
// Flow completion: if EOF, notify host with total size from payload (accumulation would live in RxFlowState).
if (pkt.is_eof() && _host) {
_host->recv_flow(pkt.src_node(), pkt.priority(), pkt.payload_size());
_host->recv_flow(pkt.src_node(),
pkt.flow_id(), pkt.priority(), pkt.payload_size());
}
break;

View File

@@ -90,6 +90,9 @@ protected:
case FlowPriority::ELEPHANT:
return PRI_ELE;
default:
return PRI_CTRL;
}
return PRI_ELE; // defensive