OLD | NEW |
(Empty) | |
| 1 #ifndef NET_QUIC_CORE_CONGESTION_CONTROL_SIMULATION_SIMULATOR_H_ |
| 2 #define NET_QUIC_CORE_CONGESTION_CONTROL_SIMULATION_SIMULATOR_H_ |
| 3 |
| 4 #include <map> |
| 5 #include <unordered_map> |
| 6 #include <unordered_set> |
| 7 |
| 8 #include "net/quic/core/congestion_control/simulation/actor.h" |
| 9 #include "net/quic/core/congestion_control/simulation/alarm_factory.h" |
| 10 #include "net/quic/core/quic_bug_tracker.h" |
| 11 #include "net/quic/core/quic_connection.h" |
| 12 #include "net/quic/core/quic_simple_buffer_allocator.h" |
| 13 |
| 14 namespace net { |
| 15 namespace simulation { |
| 16 |
| 17 // Simulator is responsible for scheduling actors in the simulation and |
| 18 // providing basic utility interfaces (clock, alarms, RNG and others). |
| 19 class Simulator : public QuicConnectionHelperInterface { |
| 20 public: |
| 21 Simulator(); |
| 22 |
| 23 // Register an actor with the simulator. Returns a handle which the actor can |
| 24 // use to schedule and unschedule itself. |
| 25 void AddActor(Actor* actor); |
| 26 |
| 27 // Schedule the specified actor. This method will ensure that |actor| is |
| 28 // called at |new_time| at latest. If Schedule() is called multiple times |
| 29 // before the Actor is called, Act() is called exactly once, at the earliest |
| 30 // time requested, and the Actor has to reschedule itself manually for the |
| 31 // subsequent times if they are still necessary. |
| 32 void Schedule(Actor* actor, QuicTime new_time); |
| 33 |
| 34 // Remove the specified actor from the schedule. |
| 35 void Unschedule(Actor* actor); |
| 36 |
| 37 // Begin QuicConnectionHelperInterface implementation. |
| 38 const QuicClock* GetClock() const override; |
| 39 QuicRandom* GetRandomGenerator() override; |
| 40 QuicBufferAllocator* GetBufferAllocator() override; |
| 41 // End QuicConnectionHelperInterface implementation. |
| 42 |
| 43 QuicAlarmFactory* GetAlarmFactory(); |
| 44 |
| 45 // Run the simulation until either no actors are scheduled or |
| 46 // |termination_predicate| returns true. Returns true if terminated due to |
| 47 // predicate, and false otherwise. |
| 48 template <class TerminationPredicate> |
| 49 bool RunUntil(TerminationPredicate termination_predicate); |
| 50 |
| 51 private: |
| 52 class Clock : public QuicClock { |
| 53 public: |
| 54 // Do not start at zero as certain code can treat zero as an invalid |
| 55 // timestamp. |
| 56 const QuicTime kStartTime = |
| 57 QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1); |
| 58 |
| 59 Clock(); |
| 60 |
| 61 QuicTime ApproximateNow() const override; |
| 62 QuicTime Now() const override; |
| 63 QuicWallTime WallNow() const override; |
| 64 |
| 65 QuicTime now_; |
| 66 }; |
| 67 |
| 68 // Finds the next scheduled actor, advances time to the schedule time and |
| 69 // notifies the actor. |
| 70 void HandleNextScheduledActor(); |
| 71 |
| 72 Clock clock_; |
| 73 QuicRandom* random_generator_; |
| 74 SimpleBufferAllocator buffer_allocator_; |
| 75 AlarmFactory alarm_factory_; |
| 76 |
| 77 // Schedule of when the actors will be executed via an Act() call. The |
| 78 // schedule is subject to the following invariants: |
| 79 // - An actor cannot be scheduled for a later time than it's currently in the |
| 80 // schedule. |
| 81 // - An actor is removed from schedule either immediately before Act() is |
| 82 // called or by explicitly calling Unschedule(). |
| 83 // - Each Actor appears in the map at most once. |
| 84 std::multimap<QuicTime, Actor*> schedule_; |
| 85 // For each actor, maintain the time it is scheduled at. The value for |
| 86 // unscheduled actors is QuicTime::Infinite(). |
| 87 std::unordered_map<Actor*, QuicTime> scheduled_times_; |
| 88 std::unordered_set<std::std::string> actor_names_; |
| 89 |
| 90 DISALLOW_COPY_AND_ASSIGN(Simulator); |
| 91 }; |
| 92 |
| 93 template <class TerminationPredicate> |
| 94 bool Simulator::RunUntil(TerminationPredicate termination_predicate) { |
| 95 bool predicate_value = false; |
| 96 while (!(predicate_value = termination_predicate()) && !schedule_.empty()) { |
| 97 HandleNextScheduledActor(); |
| 98 } |
| 99 return predicate_value; |
| 100 } |
| 101 |
| 102 } // namespace simulation |
| 103 } // namespace net |
| 104 |
| 105 #endif // NET_QUIC_CORE_CONGESTION_CONTROL_SIMULATION_SIMULATOR_H_ |
OLD | NEW |