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