// The entities on the ethernet are called "hosts". // Each host has one application behaviour. There are any number of hosts. // Each host, thus, is an object to be queued in the event queue. // The events and hosts turn out to be sufficiently inter-related that it // didn't seem to be useful to split it into two classes. So the base class // is "event", and the subclasses are host_*... class event { private: static class event *top; class event *next; protected: static class strategy *sched_strategy; // how to reschedule long x; // private data for strategy if it wants it static long last_busy; long nexttime; // when the next activity occurs (i.e. my queue position) long nextsize; // size in bytes of packet to be transmitted at that time int isconflict, iscollision; // interference from other events event(long firsttime, long firstsize); // link into list void shuffle(); // already in list; re-insert later on to put things back in order virtual void process(); // calls the following functions, except for quit void checkconflict(); // set was* variables for me _and_ others void resched_conflict(); // reschedule after a collision or other conflict virtual void resched_successful(long) = 0; // reschedule after a successful transmission // -> note: the resched_*() functions just tweak nexttime and nextsize; // they do not call shuffle(). So call shuffle() after that. virtual void record_stats() = 0; // register successful transmission // Other data about multipacket transmissions in progress, etc, is kept in // the subclass representing that type of application behaviour. public: static void set_strategy(class strategy *str); static void process_one(); }; class event_quit : public event { void process(); // quits void resched_successful(long), record_stats();// to make class non-abstract public: event_quit(long when); }; // Simple communication behaviour called a "spewer" class host_spewer : public event { virtual void resched_successful(long completion_time); virtual void record_stats(); public: host_spewer(); }; // Fairly simple communication between peers. Each object represents _two_ // hosts communicating as peers. class host_peer_pair : public event { virtual void resched_successful(long completion_time); virtual void record_stats(); public: host_peer_pair(); }; // Slightly more exciting communication pattern between client-server pairs. // Each object represents _two_ hosts: one client and one server. class host_client_server : public event { int whos_on; // is it client or server transmitting? long message_remaining; // number of bytes remaining in this server // transmission, or zero if it's the client next virtual void resched_successful(long completion_time); void take_one_packet(); virtual void record_stats(); public: host_client_server(); };