00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2005 INRIA 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 00019 */ 00020 00021 #ifndef SCHEDULER_H 00022 #define SCHEDULER_H 00023 00024 #include <stdint.h> 00025 #include "ns3/object.h" 00026 00027 namespace ns3 { 00028 00029 class EventImpl; 00030 00031 /** 00032 * \ingroup simulator 00033 * \defgroup scheduler Scheduler 00034 */ 00035 /** 00036 * \ingroup scheduler 00037 * \brief Maintain the event list 00038 * 00039 * This base class specifies the interface used to maintain the 00040 * event list. If you want to provide a new event list scheduler, 00041 * you need to create a subclass of this base class and implement 00042 * all the pure virtual methods defined here. 00043 * 00044 * The only tricky aspect of this API is the memory management of 00045 * the EventImpl pointer which is a member of the Event data structure. 00046 * The lifetime of this pointer is assumed to always be longer than 00047 * the lifetime of the Scheduler class which means that the caller 00048 * is responsible for ensuring that this invariant holds through 00049 * calling EventImpl::Ref and EventImpl::Unref at the right time. 00050 * Typically, ::Ref is called before Insert and ::Unref is called 00051 * after a call to one of the Remove methods. 00052 */ 00053 class Scheduler : public Object 00054 { 00055 public: 00056 static TypeId GetTypeId (void); 00057 00058 struct EventKey { 00059 uint64_t m_ts; 00060 uint32_t m_uid; 00061 }; 00062 struct Event { 00063 EventImpl *impl; 00064 EventKey key; 00065 }; 00066 00067 virtual ~Scheduler () = 0; 00068 00069 /** 00070 * \param ev event to store in the event list 00071 */ 00072 virtual void Insert (const Event &ev) = 0; 00073 /** 00074 * \returns true if the event list is empty and false otherwise. 00075 */ 00076 virtual bool IsEmpty (void) const = 0; 00077 /** 00078 * \returns a pointer to the next earliest event. The caller 00079 * takes ownership of the returned pointer. 00080 * 00081 * This method cannot be invoked if the list is empty. 00082 */ 00083 virtual Event PeekNext (void) const = 0; 00084 /** 00085 * This method cannot be invoked if the list is empty. 00086 * Remove the next earliest event from the event list. 00087 */ 00088 virtual Event RemoveNext (void) = 0; 00089 /** 00090 * \param ev the event to remove 00091 * 00092 * This methods cannot be invoked if the list is empty. 00093 */ 00094 virtual void Remove (const Event &ev) = 0; 00095 }; 00096 00097 /* Note the invariants which this function must provide: 00098 * - irreflexibility: f (x,x) is false) 00099 * - antisymmetry: f(x,y) = !f(y,x) 00100 * - transitivity: f(x,y) and f(y,z) => f(x,z) 00101 */ 00102 inline bool operator < (const Scheduler::EventKey &a, const Scheduler::EventKey &b) 00103 { 00104 if (a.m_ts < b.m_ts) 00105 { 00106 return true; 00107 } 00108 else if (a.m_ts == b.m_ts && 00109 a.m_uid < b.m_uid) 00110 { 00111 return true; 00112 } 00113 else 00114 { 00115 return false; 00116 } 00117 } 00118 00119 inline bool operator < (const Scheduler::Event &a, const Scheduler::Event &b) 00120 { 00121 return a.key < b.key; 00122 } 00123 00124 00125 } // namespace ns3 00126 00127 00128 #endif /* SCHEDULER_H */