first cut at george's ideas on api
This commit is contained in:
@@ -69,7 +69,7 @@ void
|
||||
PcapWriter::write_packet (Packet const packet)
|
||||
{
|
||||
if (m_writer != 0) {
|
||||
uint64_t current = Simulator::now_us ();
|
||||
uint64_t current = Simulator::now ().us ();
|
||||
uint64_t s = current / 1000000;
|
||||
uint64_t us = current % 1000000;
|
||||
write_32 (s & 0xffffffff);
|
||||
|
||||
@@ -54,7 +54,7 @@ StaticSpeedPosition::set_delta (double dx, double dy, double dz)
|
||||
void
|
||||
StaticSpeedPosition::real_get (double &x, double &y, double &z) const
|
||||
{
|
||||
uint64_t now_us = Simulator::now_us ();
|
||||
uint64_t now_us = Simulator::now ().us ();
|
||||
uint64_t delta_us = now_us - m_prev_us;
|
||||
m_x += m_dx * delta_us;
|
||||
m_y += m_dy * delta_us;
|
||||
|
||||
64
src/simulator/event-id.cc
Normal file
64
src/simulator/event-id.cc
Normal file
@@ -0,0 +1,64 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "event-id.h"
|
||||
#include "simulator.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
EventId::EventId ()
|
||||
: m_event_impl (0),
|
||||
m_time (0),
|
||||
m_uid (0)
|
||||
{}
|
||||
|
||||
EventId::EventId (EventImpl *impl, uint64_t time, uint32_t uid)
|
||||
: m_event_impl (impl),
|
||||
m_time (time),
|
||||
m_uid (uid)
|
||||
{}
|
||||
void
|
||||
EventId::cancel (void)
|
||||
{
|
||||
Simulator::cancel (*this);
|
||||
}
|
||||
bool
|
||||
EventId::is_expired (void)
|
||||
{
|
||||
return Simulator::is_expired (*this);
|
||||
}
|
||||
EventImpl *
|
||||
EventId::get_event_impl (void) const
|
||||
{
|
||||
return m_event_impl;
|
||||
}
|
||||
uint64_t
|
||||
EventId::get_time (void) const
|
||||
{
|
||||
return m_time;
|
||||
}
|
||||
uint32_t
|
||||
EventId::get_uid (void) const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
@@ -18,30 +18,35 @@
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "event-impl.h"
|
||||
#include "event.h"
|
||||
#ifndef EVENT_ID_H
|
||||
#define EVENT_ID_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class EventFunctionImpl0 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(void);
|
||||
class EventImpl;
|
||||
|
||||
EventFunctionImpl0 (F function)
|
||||
: m_function (function)
|
||||
{}
|
||||
virtual ~EventFunctionImpl0 () {}
|
||||
class EventId {
|
||||
public:
|
||||
EventId ();
|
||||
EventId (EventImpl *impl, uint64_t time, uint32_t uid);
|
||||
void cancel (void);
|
||||
bool is_expired (void);
|
||||
public:
|
||||
/* The following methods are semi-private
|
||||
* they are supposed to be invoked only by
|
||||
* subclasses of the Scheduler base class.
|
||||
*/
|
||||
EventImpl *get_event_impl (void) const;
|
||||
uint64_t get_time (void) const;
|
||||
uint32_t get_uid (void) const;
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) ();
|
||||
}
|
||||
private:
|
||||
F m_function;
|
||||
EventImpl *m_event_impl;
|
||||
uint64_t m_time;
|
||||
uint32_t m_uid;
|
||||
};
|
||||
|
||||
Event make_event(void (*f) (void))
|
||||
{
|
||||
return Event (new EventFunctionImpl0 (f));
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* EVENT_ID_H */
|
||||
@@ -29,39 +29,30 @@ EventImpl::~EventImpl ()
|
||||
{}
|
||||
|
||||
EventImpl::EventImpl ()
|
||||
: m_id (0),
|
||||
m_count (1),
|
||||
m_cancel (0),
|
||||
m_running (1)
|
||||
: m_internal_iterator (0),
|
||||
m_cancel (false)
|
||||
{}
|
||||
void
|
||||
EventImpl::invoke (void)
|
||||
{
|
||||
if (m_cancel == 0) {
|
||||
if (!m_cancel) {
|
||||
notify ();
|
||||
}
|
||||
m_running = 0;
|
||||
}
|
||||
void
|
||||
EventImpl::set_tag (void *tag)
|
||||
EventImpl::set_internal_iterator (void *tag)
|
||||
{
|
||||
m_id = tag;
|
||||
m_internal_iterator = tag;
|
||||
}
|
||||
void *
|
||||
EventImpl::get_tag (void) const
|
||||
EventImpl::get_internal_iterator (void) const
|
||||
{
|
||||
return m_id;
|
||||
return m_internal_iterator;
|
||||
}
|
||||
void
|
||||
EventImpl::cancel (void)
|
||||
{
|
||||
m_cancel = 1;
|
||||
m_running = 0;
|
||||
}
|
||||
bool
|
||||
EventImpl::is_running (void)
|
||||
{
|
||||
return (m_running == 1);
|
||||
m_cancel = true;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -30,18 +30,15 @@ public:
|
||||
EventImpl ();
|
||||
virtual ~EventImpl () = 0;
|
||||
void invoke (void);
|
||||
void set_tag (void *tag);
|
||||
void *get_tag (void) const;
|
||||
void cancel (void);
|
||||
bool is_running (void);
|
||||
void set_internal_iterator (void *iterator);
|
||||
void *get_internal_iterator (void) const;
|
||||
protected:
|
||||
virtual void notify (void) = 0;
|
||||
private:
|
||||
friend class Event;
|
||||
void *m_id;
|
||||
uint32_t m_count;
|
||||
uint32_t m_cancel : 1;
|
||||
uint32_t m_running : 1;
|
||||
void *m_internal_iterator;
|
||||
bool m_cancel;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "event.tcc"
|
||||
#include "ns3/test.h"
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
#define ENSURE(got,expected) \
|
||||
if (got != expected) { \
|
||||
g_error = true; \
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool g_error = false;
|
||||
|
||||
void null_cb (void)
|
||||
{}
|
||||
void one_cb (int a)
|
||||
{
|
||||
ENSURE (a, 1);
|
||||
}
|
||||
void two_cb (int a,int b)
|
||||
{
|
||||
ENSURE (a, 1);
|
||||
ENSURE (b, 2);
|
||||
}
|
||||
void three_cb (int a,int b,int c)
|
||||
{
|
||||
ENSURE (a, 1);
|
||||
ENSURE (b, 2);
|
||||
ENSURE (c, 3);
|
||||
}
|
||||
void four_cb (int a,int b,int c,int d)
|
||||
{
|
||||
ENSURE (a, 1);
|
||||
ENSURE (b, 2);
|
||||
ENSURE (c, 3);
|
||||
ENSURE (d, 4);
|
||||
}
|
||||
void five_cb (int a,int b,int c,int d,int e)
|
||||
{
|
||||
ENSURE (a, 1);
|
||||
ENSURE (b, 2);
|
||||
ENSURE (c, 3);
|
||||
ENSURE (d, 4);
|
||||
ENSURE (e, 5);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
namespace ns3 {
|
||||
class EventTest : public Test {
|
||||
public:
|
||||
EventTest ();
|
||||
virtual bool run_tests (void);
|
||||
};
|
||||
|
||||
EventTest::EventTest ()
|
||||
: Test ("Event")
|
||||
{}
|
||||
|
||||
bool
|
||||
EventTest::run_tests (void)
|
||||
{
|
||||
Event ev;
|
||||
|
||||
ev = ns3::make_event (&null_cb);
|
||||
ev ();
|
||||
ev = ns3::make_event (&one_cb, 1);
|
||||
ev ();
|
||||
ev = ns3::make_event (&two_cb, 1, 2);
|
||||
ev ();
|
||||
ev = ns3::make_event (&three_cb, 1, 2, 3);
|
||||
ev ();
|
||||
ev = ns3::make_event (&four_cb, 1, 2, 3, 4);
|
||||
ev ();
|
||||
ev = ns3::make_event (&five_cb, 1, 2, 3, 4, 5);
|
||||
ev ();
|
||||
|
||||
if (g_error) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static EventTest g_test;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
@@ -1,140 +0,0 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
|
||||
#include <algorithm>
|
||||
#include "event-impl.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
class EventImpl;
|
||||
/**
|
||||
* \brief Simulation events.
|
||||
*
|
||||
* The Event class has POD semantics: it can and should
|
||||
* be passed around by value. The Event class is a mere
|
||||
* wrapper around the EventImpl class and performs
|
||||
* memory management of EventImpl object instances.
|
||||
*
|
||||
* While users could create Events by instanciating
|
||||
* subclasses of the EventImpl class and storing them
|
||||
* in an Event instance, they are advised to use the
|
||||
* template functions \ref make_event instead.
|
||||
*/
|
||||
class Event {
|
||||
public:
|
||||
Event ()
|
||||
: m_impl (0)
|
||||
{}
|
||||
Event (EventImpl *impl)
|
||||
: m_impl (impl)
|
||||
{}
|
||||
Event (Event const &o)
|
||||
: m_impl (o.m_impl)
|
||||
{
|
||||
if (m_impl != 0) {
|
||||
m_impl->m_count++;
|
||||
}
|
||||
}
|
||||
~Event ()
|
||||
{
|
||||
if (m_impl != 0) {
|
||||
m_impl->m_count--;
|
||||
if (m_impl->m_count == 0) {
|
||||
delete m_impl;
|
||||
}
|
||||
}
|
||||
m_impl = 0;
|
||||
}
|
||||
Event &operator = (Event const&o)
|
||||
{
|
||||
if (m_impl != 0) {
|
||||
m_impl->m_count--;
|
||||
if (m_impl->m_count == 0) {
|
||||
delete m_impl;
|
||||
}
|
||||
}
|
||||
m_impl = o.m_impl;
|
||||
if (m_impl != 0) {
|
||||
m_impl->m_count++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
void operator () (void)
|
||||
{
|
||||
m_impl->invoke ();
|
||||
}
|
||||
/**
|
||||
* Cancel an event. This operation has O(1)
|
||||
* complexity since it merely sets a "cancel" bit
|
||||
* to on and does not remove the Event from the
|
||||
* scheduler's event list. When the event expires,
|
||||
* the scheduler checks this cancel bit and, if set,
|
||||
* does not execute the event.
|
||||
*/
|
||||
void cancel (void)
|
||||
{
|
||||
if (m_impl != 0) {
|
||||
m_impl->cancel ();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return true if the event is in RUNNING state.
|
||||
* Return false otherwise.
|
||||
*
|
||||
* An Event is created in RUNNING state and switches
|
||||
* to NON_RUNNING state upon one of:
|
||||
* - cancel bit is set to on
|
||||
* - Event execution is completed.
|
||||
* It is important to note that an event is in RUNNING
|
||||
* state while being executed.
|
||||
*/
|
||||
bool is_running (void)
|
||||
{
|
||||
if (m_impl != 0 && m_impl->is_running ()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SchedulerHeap;
|
||||
friend class SchedulerList;
|
||||
friend class SchedulerMap;
|
||||
void set_tag (void *tag)
|
||||
{
|
||||
return m_impl->set_tag (tag);
|
||||
}
|
||||
void *get_tag (void) const
|
||||
{
|
||||
return m_impl->get_tag ();
|
||||
}
|
||||
|
||||
EventImpl *m_impl;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* EVENT_H */
|
||||
@@ -1,454 +0,0 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef EVENT_TCC
|
||||
#define EVENT_TCC
|
||||
|
||||
#include "event.h"
|
||||
#include "event-impl.h"
|
||||
|
||||
/**
|
||||
* ns3 namespace
|
||||
*/
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \defgroup make_event make_event
|
||||
*
|
||||
* Every make_event template function returns a newly-created Event
|
||||
* which holds a pointer to a special subclass of the EventImpl
|
||||
* base class. Each of these subclasses holds information about which
|
||||
* function or method to call and which parameters must be forwarded
|
||||
* to this function or method.
|
||||
*
|
||||
* Sample code is shown below:
|
||||
* \include samples/main-event.cc
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
class EventMemberImpl0 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(void);
|
||||
|
||||
EventMemberImpl0 (T *obj, F function)
|
||||
: m_obj (obj),
|
||||
m_function (function)
|
||||
{}
|
||||
virtual ~EventMemberImpl0 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) ();
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
};
|
||||
|
||||
template<typename T, typename T1>
|
||||
class EventMemberImpl1 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(T1);
|
||||
|
||||
EventMemberImpl1 (T *obj, F function, T1 a1)
|
||||
: m_obj (obj),
|
||||
m_function (function),
|
||||
m_a1 (a1)
|
||||
{ }
|
||||
virtual ~EventMemberImpl1 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) (m_a1);
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
};
|
||||
|
||||
template<typename T, typename T1, typename T2>
|
||||
class EventMemberImpl2 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(T1, T2);
|
||||
|
||||
EventMemberImpl2 (T *obj, F function, T1 a1, T2 a2)
|
||||
: m_obj (obj),
|
||||
m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2)
|
||||
{ }
|
||||
virtual ~EventMemberImpl2 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) (m_a1, m_a2);
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
};
|
||||
|
||||
template<typename T, typename T1, typename T2, typename T3>
|
||||
class EventMemberImpl3 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(T1, T2, T3);
|
||||
|
||||
EventMemberImpl3 (T *obj, F function, T1 a1, T2 a2, T3 a3)
|
||||
: m_obj (obj),
|
||||
m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2),
|
||||
m_a3 (a3)
|
||||
{ }
|
||||
virtual ~EventMemberImpl3 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) (m_a1, m_a2, m_a3);
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
T3 m_a3;
|
||||
};
|
||||
|
||||
template<typename T, typename T1, typename T2, typename T3, typename T4>
|
||||
class EventMemberImpl4 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(T1, T2, T3, T4);
|
||||
|
||||
EventMemberImpl4 (T *obj, F function, T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
: m_obj (obj),
|
||||
m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2),
|
||||
m_a3 (a3),
|
||||
m_a4 (a4)
|
||||
{ }
|
||||
virtual ~EventMemberImpl4 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4);
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
T3 m_a3;
|
||||
T4 m_a4;
|
||||
};
|
||||
|
||||
template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class EventMemberImpl5 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(T1, T2, T3, T4, T5);
|
||||
|
||||
EventMemberImpl5 (T *obj, F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
: m_obj (obj),
|
||||
m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2),
|
||||
m_a3 (a3),
|
||||
m_a4 (a4),
|
||||
m_a5 (a5)
|
||||
{ }
|
||||
virtual ~EventMemberImpl5 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
T3 m_a3;
|
||||
T4 m_a4;
|
||||
T5 m_a5;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f class method member pointer
|
||||
* \param t class instance
|
||||
* \return a wrapper Event
|
||||
* Build Events for class method members which take no arguments.
|
||||
*/
|
||||
template<typename T>
|
||||
Event make_event(void (T::*f) (void), T* t) {
|
||||
return Event (new EventMemberImpl0<T>(t, f));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f class method member pointer
|
||||
* \param t class instance
|
||||
* \param a1 first argument to pass to the target method when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for class method members which take only one argument
|
||||
*/
|
||||
template<typename T, typename T1>
|
||||
Event make_event(void (T::*f) (T1), T* t, T1 a1) {
|
||||
return Event (new EventMemberImpl1<T, T1>(t, f, a1));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f class method member pointer
|
||||
* \param t class instance
|
||||
* \param a1 first argument to pass to the target method when the event expires
|
||||
* \param a2 second argument to pass to the target method when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for class method members which take two arguments
|
||||
*/
|
||||
template<typename T, typename T1, typename T2>
|
||||
Event make_event(void (T::*f) (T1, T2), T* t, T1 a1, T2 a2) {
|
||||
return Event (new EventMemberImpl2<T, T1, T2>(t, f, a1, a2));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f class method member pointer
|
||||
* \param t class instance
|
||||
* \param a1 first argument to pass to the target method when the event expires
|
||||
* \param a2 second argument to pass to the target method when the event expires
|
||||
* \param a3 third argument to pass to the target method when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for class method members which take three arguments
|
||||
*/
|
||||
template<typename T, typename T1, typename T2, typename T3>
|
||||
Event make_event(void (T::*f) (T1, T2, T3), T* t, T1 a1, T2 a2, T3 a3) {
|
||||
return Event (new EventMemberImpl3<T, T1, T2, T3>(t, f, a1, a2, a3));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f class method member pointer
|
||||
* \param t class instance
|
||||
* \param a1 first argument to pass to the target method when the event expires
|
||||
* \param a2 second argument to pass to the target method when the event expires
|
||||
* \param a3 third argument to pass to the target method when the event expires
|
||||
* \param a4 fourth argument to pass to the target method when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for class method members which take four arguments
|
||||
*/
|
||||
template<typename T, typename T1, typename T2, typename T3, typename T4>
|
||||
Event make_event(void (T::*f) (T1, T2, T3, T4), T* t, T1 a1, T2 a2, T3 a3, T4 a4) {
|
||||
return Event (new EventMemberImpl4<T, T1, T2, T3, T4>(t, f, a1, a2, a3, a4));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f class method member pointer
|
||||
* \param t class instance
|
||||
* \param a1 first argument to pass to the target method when the event expires
|
||||
* \param a2 second argument to pass to the target method when the event expires
|
||||
* \param a3 third argument to pass to the target method when the event expires
|
||||
* \param a4 fourth argument to pass to the target method when the event expires
|
||||
* \param a5 fifth argument to pass to the target method when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for class method members which take five arguments.
|
||||
*/
|
||||
template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
Event make_event(void (T::*f) (T1, T2, T3, T4, T5), T* t, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
|
||||
return Event (new EventMemberImpl5<T, T1, T2, T3, T4, T5>(t, f, a1, a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
class EventFunctionImpl1 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(T1);
|
||||
|
||||
EventFunctionImpl1 (F function, T1 a1)
|
||||
: m_function (function),
|
||||
m_a1 (a1)
|
||||
{ }
|
||||
virtual ~EventFunctionImpl1 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) (m_a1);
|
||||
}
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
class EventFunctionImpl2 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(T1, T2);
|
||||
|
||||
EventFunctionImpl2 (F function, T1 a1, T2 a2)
|
||||
: m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2)
|
||||
{ }
|
||||
virtual ~EventFunctionImpl2 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) (m_a1, m_a2);
|
||||
}
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
class EventFunctionImpl3 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(T1, T2, T3);
|
||||
|
||||
EventFunctionImpl3 (F function, T1 a1, T2 a2, T3 a3)
|
||||
: m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2),
|
||||
m_a3 (a3)
|
||||
{ }
|
||||
virtual ~EventFunctionImpl3 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) (m_a1, m_a2, m_a3);
|
||||
}
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
T3 m_a3;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
class EventFunctionImpl4 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(T1, T2, T3, T4);
|
||||
|
||||
EventFunctionImpl4 (F function, T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
: m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2),
|
||||
m_a3 (a3),
|
||||
m_a4 (a4)
|
||||
{ }
|
||||
virtual ~EventFunctionImpl4 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) (m_a1, m_a2, m_a3, m_a4);
|
||||
}
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
T3 m_a3;
|
||||
T4 m_a4;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class EventFunctionImpl5 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(T1, T2, T3, T4, T5);
|
||||
|
||||
EventFunctionImpl5 (F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
: m_function (function),
|
||||
m_a1 (a1),
|
||||
m_a2 (a2),
|
||||
m_a3 (a3),
|
||||
m_a4 (a4),
|
||||
m_a5 (a5)
|
||||
{ }
|
||||
virtual ~EventFunctionImpl5 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
|
||||
}
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
T2 m_a2;
|
||||
T3 m_a3;
|
||||
T4 m_a4;
|
||||
T5 m_a5;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f function pointer
|
||||
* \return a wrapper Event
|
||||
* Build Events for function pointers which take no arguments
|
||||
*/
|
||||
Event make_event(void (*f) (void));
|
||||
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f function pointer
|
||||
* \param a1 first argument to pass to the target function when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for function pointers which take one argument
|
||||
*/
|
||||
template<typename T1>
|
||||
Event make_event(void (*f) (T1), T1 a1) {
|
||||
return Event (new EventFunctionImpl1<T1>(f, a1));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f function pointer
|
||||
* \param a1 first argument to pass to the target function when the event expires
|
||||
* \param a2 second argument to pass to the target function when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for function pointers which take two argument
|
||||
*/
|
||||
template<typename T1, typename T2>
|
||||
Event make_event(void (*f) (T1, T2), T1 a1, T2 a2) {
|
||||
return Event (new EventFunctionImpl2<T1, T2>(f, a1, a2));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f function pointer
|
||||
* \param a1 first argument to pass to the target function when the event expires
|
||||
* \param a2 second argument to pass to the target function when the event expires
|
||||
* \param a3 third argument to pass to the target function when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for function pointers which take three argument
|
||||
*/
|
||||
template<typename T1, typename T2, typename T3>
|
||||
Event make_event(void (*f) (T1, T2, T3), T1 a1, T2 a2, T3 a3) {
|
||||
return Event (new EventFunctionImpl3<T1, T2, T3>(f, a1, a2, a3));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f function pointer
|
||||
* \param a1 first argument to pass to the target function when the event expires
|
||||
* \param a2 second argument to pass to the target function when the event expires
|
||||
* \param a3 third argument to pass to the target function when the event expires
|
||||
* \param a4 fourth argument to pass to the target function when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for function pointers which take four argument
|
||||
*/
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
Event make_event(void (*f) (T1, T2, T3, T4), T1 a1, T2 a2, T3 a3, T4 a4) {
|
||||
return Event (new EventFunctionImpl4<T1, T2, T3, T4>(f, a1, a2, a3, a4));
|
||||
}
|
||||
/**
|
||||
* \ingroup make_event
|
||||
* \param f function pointer
|
||||
* \param a1 first argument to pass to the target function when the event expires
|
||||
* \param a2 second argument to pass to the target function when the event expires
|
||||
* \param a3 third argument to pass to the target function when the event expires
|
||||
* \param a4 fourth argument to pass to the target function when the event expires
|
||||
* \param a5 fifth argument to pass to the target function when the event expires
|
||||
* \return a wrapper Event
|
||||
* Build Events for function pointers which take five argument
|
||||
*/
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
Event make_event(void (*f) (T1, T2, T3, T4, T5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
|
||||
return Event (new EventFunctionImpl5<T1, T2, T3, T4, T5>(f, a1, a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* EVENT_TCC */
|
||||
@@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include "scheduler-heap.h"
|
||||
#include "event.h"
|
||||
#include "event-impl.h"
|
||||
#include <cassert>
|
||||
|
||||
#define noTRACE_HEAP 1
|
||||
@@ -57,25 +57,22 @@ SchedulerHeap::SchedulerHeap ()
|
||||
// the array to make sure the indexes in the
|
||||
// array start at one.
|
||||
Scheduler::EventKey empty_key = {0,0};
|
||||
m_heap.push_back (std::make_pair ((Event )0, empty_key));
|
||||
m_heap.push_back (std::make_pair (static_cast<EventImpl *>(0), empty_key));
|
||||
}
|
||||
|
||||
SchedulerHeap::~SchedulerHeap ()
|
||||
{}
|
||||
|
||||
|
||||
void
|
||||
SchedulerHeap::store_in_event (Event ev, uint32_t index) const
|
||||
void
|
||||
SchedulerHeap::store_in_event (EventImpl *ev, uint32_t index) const
|
||||
{
|
||||
ev.set_tag ((void *)index);
|
||||
ev->set_internal_iterator ((void *)index);
|
||||
}
|
||||
uint32_t
|
||||
SchedulerHeap::get_from_event (Event const ev) const
|
||||
uint32_t
|
||||
SchedulerHeap::get_from_event (EventImpl *ev) const
|
||||
{
|
||||
return (uint32_t)ev.get_tag ();
|
||||
return (uint32_t)ev->get_internal_iterator ();
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
SchedulerHeap::parent (uint32_t id) const
|
||||
{
|
||||
@@ -127,14 +124,9 @@ SchedulerHeap::exch (uint32_t a, uint32_t b)
|
||||
{
|
||||
assert (b < m_heap.size () && a < m_heap.size ());
|
||||
TRACE ("exch " << a << ", " << b);
|
||||
#if 1
|
||||
std::swap (m_heap[a].second, m_heap[b].second);
|
||||
std::swap (m_heap[a].first.m_impl, m_heap[b].first.m_impl);
|
||||
#else
|
||||
std::pair<Event , Scheduler::EventKey> tmp (m_heap[a]);
|
||||
std::pair<EventImpl*, Scheduler::EventKey> tmp (m_heap[a]);
|
||||
m_heap[a] = m_heap[b];
|
||||
m_heap[b] = tmp;
|
||||
#endif
|
||||
store_in_event (m_heap[a].first, a);
|
||||
store_in_event (m_heap[b].first, b);
|
||||
}
|
||||
@@ -199,16 +191,16 @@ SchedulerHeap::top_down (void)
|
||||
}
|
||||
|
||||
|
||||
Event
|
||||
SchedulerHeap::insert (Event event, Scheduler::EventKey key)
|
||||
EventId
|
||||
SchedulerHeap::insert (EventImpl *event, Scheduler::EventKey key)
|
||||
{
|
||||
m_heap.push_back (std::make_pair (event, key));
|
||||
store_in_event (event, last ());
|
||||
bottom_up ();
|
||||
return event;
|
||||
store_in_event (event, last ());
|
||||
return EventId (event, key.m_time, key.m_uid);
|
||||
}
|
||||
|
||||
Event
|
||||
EventImpl *
|
||||
SchedulerHeap::peek_next (void) const
|
||||
{
|
||||
assert (!is_empty ());
|
||||
@@ -229,15 +221,26 @@ SchedulerHeap::remove_next (void)
|
||||
top_down ();
|
||||
}
|
||||
|
||||
Scheduler::EventKey
|
||||
SchedulerHeap::remove (Event const ev)
|
||||
|
||||
EventImpl *
|
||||
SchedulerHeap::remove (EventId id, Scheduler::EventKey *key)
|
||||
{
|
||||
EventImpl *ev = id.get_event_impl ();
|
||||
uint32_t i = get_from_event (ev);
|
||||
EventKey key = m_heap[i].second;
|
||||
*key = m_heap[i].second;
|
||||
exch (i, last ());
|
||||
m_heap.pop_back ();
|
||||
top_down ();
|
||||
return key;
|
||||
return ev;
|
||||
}
|
||||
|
||||
bool
|
||||
SchedulerHeap::is_valid (EventId id)
|
||||
{
|
||||
EventImpl *ev = id.get_event_impl ();
|
||||
uint32_t i = get_from_event (ev);
|
||||
Scheduler::EventKey key = m_heap[i].second;
|
||||
return (key.m_time == id.get_time () &&
|
||||
key.m_uid == id.get_uid ());
|
||||
}
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Event;
|
||||
class EventHolder;
|
||||
|
||||
class SchedulerHeap : public Scheduler {
|
||||
@@ -36,16 +35,17 @@ public:
|
||||
SchedulerHeap ();
|
||||
virtual ~SchedulerHeap ();
|
||||
|
||||
virtual Event insert (Event event, Scheduler::EventKey key);
|
||||
virtual EventId insert (EventImpl *event, Scheduler::EventKey key);
|
||||
virtual bool is_empty (void) const;
|
||||
virtual Event peek_next (void) const;
|
||||
virtual EventImpl *peek_next (void) const;
|
||||
virtual Scheduler::EventKey peek_next_key (void) const;
|
||||
virtual void remove_next (void);
|
||||
virtual Scheduler::EventKey remove (Event const ev);
|
||||
virtual EventImpl *remove (EventId ev, Scheduler::EventKey *key);
|
||||
virtual bool is_valid (EventId id);
|
||||
private:
|
||||
typedef std::vector<std::pair<Event, Scheduler::EventKey> > BinaryHeap;
|
||||
inline void store_in_event (Event ev, uint32_t index) const;
|
||||
uint32_t get_from_event (Event const ev) const;
|
||||
typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
|
||||
inline void store_in_event (EventImpl *ev, uint32_t index) const;
|
||||
uint32_t get_from_event (EventImpl *ev) const;
|
||||
|
||||
inline uint32_t parent (uint32_t id) const;
|
||||
uint32_t sibling (uint32_t id) const;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "scheduler-list.h"
|
||||
#include "event.h"
|
||||
#include "event-impl.h"
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
@@ -37,46 +37,47 @@ SchedulerList::~SchedulerList ()
|
||||
* it relies on the fact that a std::list<>::iterator has a single
|
||||
* member variable, a pointer.
|
||||
*/
|
||||
void
|
||||
SchedulerList::store_in_event (Event ev, EventsI i)
|
||||
EventId
|
||||
SchedulerList::get_event_id (Scheduler::EventKey key, EventsI i)
|
||||
{
|
||||
assert (sizeof (i) <= sizeof (Event));
|
||||
void *tag;
|
||||
strncpy ((char *)&(tag), (char *)&i, sizeof (void *));
|
||||
ev.set_tag (tag);
|
||||
assert (sizeof (i) <= sizeof (void *));
|
||||
void *internal_iterator;
|
||||
memcpy ((char *)&(internal_iterator), (char *)&i, sizeof (void *));
|
||||
EventImpl *ev = i->first;
|
||||
ev->set_internal_iterator (internal_iterator);
|
||||
return EventId (ev, key.m_time, key.m_uid);
|
||||
}
|
||||
SchedulerList::EventsI
|
||||
SchedulerList::get_from_event (Event const ev)
|
||||
SchedulerList::get_iterator (EventId id)
|
||||
{
|
||||
SchedulerList::EventsI i;
|
||||
assert (sizeof (i) <= sizeof (Event));
|
||||
void *tag = ev.get_tag ();
|
||||
strncpy ((char *)&i, (char *)&(tag), sizeof (void *));
|
||||
assert (sizeof (i) <= sizeof (void *));
|
||||
EventImpl *ev = id.get_event_impl ();
|
||||
void *internal_iterator = ev->get_internal_iterator ();
|
||||
memcpy ((char *)&i, (char *)&(internal_iterator), sizeof (void *));
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
Event
|
||||
SchedulerList::insert (Event event, Scheduler::EventKey key)
|
||||
EventId
|
||||
SchedulerList::insert (EventImpl *event, Scheduler::EventKey key)
|
||||
{
|
||||
Scheduler::EventKeyCompare compare;
|
||||
for (EventsI i = m_events.begin (); i != m_events.end (); i++) {
|
||||
if (compare (key, i->second)) {
|
||||
m_events.insert (i, std::make_pair (event, key));
|
||||
store_in_event (event, i);
|
||||
return event;
|
||||
return get_event_id (key, i);
|
||||
}
|
||||
}
|
||||
m_events.push_back (std::make_pair (event, key));
|
||||
store_in_event (event, --(m_events.end ()));
|
||||
return event;
|
||||
return get_event_id (key, --(m_events.end ()));
|
||||
}
|
||||
bool
|
||||
SchedulerList::is_empty (void) const
|
||||
{
|
||||
return m_events.empty ();
|
||||
}
|
||||
Event
|
||||
EventImpl *
|
||||
SchedulerList::peek_next (void) const
|
||||
{
|
||||
assert (!is_empty ());
|
||||
@@ -95,13 +96,26 @@ SchedulerList::remove_next (void)
|
||||
m_events.pop_front ();
|
||||
}
|
||||
|
||||
Scheduler::EventKey
|
||||
SchedulerList::remove (Event const ev)
|
||||
EventImpl *
|
||||
SchedulerList::remove (EventId id, Scheduler::EventKey *key)
|
||||
{
|
||||
EventsI i = get_from_event (ev);
|
||||
EventKey key = (*i).second;
|
||||
m_events.erase (get_from_event (ev));
|
||||
return key;
|
||||
EventsI i = get_iterator (id);
|
||||
*key = i->second;
|
||||
assert (key->m_time == id.get_time () &&
|
||||
key->m_uid == id.get_uid ());
|
||||
EventImpl *ev = i->first;
|
||||
m_events.erase (i);
|
||||
return ev;
|
||||
}
|
||||
|
||||
bool
|
||||
SchedulerList::is_valid (EventId id)
|
||||
{
|
||||
EventsI i = get_iterator (id);
|
||||
Scheduler::EventKey key = i->second;
|
||||
return (key.m_time == id.get_time () &&
|
||||
key.m_uid == id.get_uid ());
|
||||
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -23,31 +23,32 @@
|
||||
#define SCHEDULER_LIST_H
|
||||
|
||||
#include "scheduler.h"
|
||||
#include "event-id.h"
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Event;
|
||||
class EventImpl;
|
||||
|
||||
class SchedulerList : public Scheduler {
|
||||
public:
|
||||
SchedulerList ();
|
||||
virtual ~SchedulerList ();
|
||||
|
||||
virtual Event insert (Event event, EventKey key);
|
||||
virtual EventId insert (EventImpl *event, EventKey key);
|
||||
virtual bool is_empty (void) const;
|
||||
virtual Event peek_next (void) const;
|
||||
virtual EventImpl *peek_next (void) const;
|
||||
virtual Scheduler::EventKey peek_next_key (void) const;
|
||||
virtual void remove_next (void);
|
||||
virtual Scheduler::EventKey remove (Event const ev);
|
||||
|
||||
virtual EventImpl *remove (EventId ev, Scheduler::EventKey *key);
|
||||
virtual bool is_valid (EventId id);
|
||||
private:
|
||||
typedef std::list<std::pair<Event, EventKey> > Events;
|
||||
typedef std::list<std::pair<Event, EventKey> >::iterator EventsI;
|
||||
void store_in_event (Event ev, EventsI i);
|
||||
EventsI get_from_event (Event const ev);
|
||||
typedef std::list<std::pair<EventImpl*, EventKey> > Events;
|
||||
typedef std::list<std::pair<EventImpl*, EventKey> >::iterator EventsI;
|
||||
EventId get_event_id (Scheduler::EventKey key, EventsI i);
|
||||
EventsI get_iterator (EventId id);
|
||||
Events m_events;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "scheduler-map.h"
|
||||
#include "event.h"
|
||||
#include "event-impl.h"
|
||||
#include <cassert>
|
||||
|
||||
#define noTRACE_MAP 1
|
||||
@@ -45,28 +45,28 @@ SchedulerMap::~SchedulerMap ()
|
||||
|
||||
|
||||
void
|
||||
SchedulerMap::store_in_event (Event ev, EventMapI i) const
|
||||
SchedulerMap::store_in_event (EventImpl *ev, EventMapI i) const
|
||||
{
|
||||
void *tag;
|
||||
memcpy (&(tag), &i, sizeof (tag));
|
||||
ev.set_tag (tag);
|
||||
ev->set_internal_iterator (tag);
|
||||
}
|
||||
SchedulerMap::EventMapI
|
||||
SchedulerMap::get_from_event (Event const ev) const
|
||||
SchedulerMap::get_from_event (EventImpl *ev) const
|
||||
{
|
||||
EventMapI i;
|
||||
void *tag = ev.get_tag ();
|
||||
void *tag = ev->get_internal_iterator ();
|
||||
memcpy (&i, &(tag), sizeof (i));
|
||||
return i;
|
||||
}
|
||||
|
||||
Event
|
||||
SchedulerMap::insert (Event event, Scheduler::EventKey key)
|
||||
EventId
|
||||
SchedulerMap::insert (EventImpl *event, Scheduler::EventKey key)
|
||||
{
|
||||
std::pair<EventMapI,bool> result = m_list.insert (std::make_pair (key, event));
|
||||
assert (result.second);
|
||||
store_in_event (event, result.first);
|
||||
return event;
|
||||
return EventId (event, key.m_time, key.m_uid);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -75,7 +75,7 @@ SchedulerMap::is_empty (void) const
|
||||
return m_list.empty ();
|
||||
}
|
||||
|
||||
Event
|
||||
EventImpl *
|
||||
SchedulerMap::peek_next (void) const
|
||||
{
|
||||
assert (!is_empty ());
|
||||
@@ -98,14 +98,23 @@ SchedulerMap::remove_next (void)
|
||||
m_list.erase (m_list.begin ());
|
||||
}
|
||||
|
||||
Scheduler::EventKey
|
||||
SchedulerMap::remove (Event const ev)
|
||||
EventImpl *
|
||||
SchedulerMap::remove (EventId id, Scheduler::EventKey *key)
|
||||
{
|
||||
assert (!is_empty ());
|
||||
EventMapI i = get_from_event (ev);
|
||||
EventKey key = (*i).first;
|
||||
EventMapI i = get_from_event (id.get_event_impl ());
|
||||
*key = i->first;
|
||||
m_list.erase (i);
|
||||
return key;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
bool
|
||||
SchedulerMap::is_valid (EventId id)
|
||||
{
|
||||
EventMapI i = get_from_event (id.get_event_impl ());
|
||||
Scheduler::EventKey key = i->first;
|
||||
return (key.m_time == id.get_time () &&
|
||||
key.m_uid == id.get_uid ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,25 +29,27 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class EventImpl;
|
||||
|
||||
class SchedulerMap : public Scheduler {
|
||||
public:
|
||||
SchedulerMap ();
|
||||
virtual ~SchedulerMap ();
|
||||
|
||||
virtual Event insert (Event event, Scheduler::EventKey key);
|
||||
virtual EventId insert (EventImpl *event, Scheduler::EventKey key);
|
||||
virtual bool is_empty (void) const;
|
||||
virtual Event peek_next (void) const;
|
||||
virtual EventImpl *peek_next (void) const;
|
||||
virtual Scheduler::EventKey peek_next_key (void) const;
|
||||
virtual void remove_next (void);
|
||||
virtual Scheduler::EventKey remove (Event const ev);
|
||||
virtual EventImpl *remove (EventId ev, Scheduler::EventKey *key);
|
||||
virtual bool is_valid (EventId id);
|
||||
private:
|
||||
typedef std::map<Scheduler::EventKey, Event, Scheduler::EventKeyCompare> EventMap;
|
||||
typedef std::map<Scheduler::EventKey, Event, Scheduler::EventKeyCompare>::iterator EventMapI;
|
||||
typedef std::map<Scheduler::EventKey, Event, Scheduler::EventKeyCompare>::const_iterator EventMapCI;
|
||||
|
||||
void store_in_event (Event ev, EventMapI i) const;
|
||||
EventMapI get_from_event (Event const ev) const;
|
||||
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare> EventMap;
|
||||
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare>::iterator EventMapI;
|
||||
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare>::const_iterator EventMapCI;
|
||||
|
||||
void store_in_event (EventImpl *ev, EventMapI i) const;
|
||||
SchedulerMap::EventMapI get_from_event (EventImpl *ev) const;
|
||||
|
||||
EventMap m_list;
|
||||
uint32_t m_uid;
|
||||
|
||||
@@ -23,10 +23,12 @@
|
||||
#define SCHEDULER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "event.h"
|
||||
#include "event-id.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class EventImpl;
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
struct EventKey {
|
||||
@@ -39,12 +41,13 @@ class Scheduler {
|
||||
};
|
||||
|
||||
virtual ~Scheduler () = 0;
|
||||
virtual Event insert (Event event, EventKey key) = 0;
|
||||
virtual EventId insert (EventImpl *event, EventKey key) = 0;
|
||||
virtual bool is_empty (void) const = 0;
|
||||
virtual Event peek_next (void) const = 0;
|
||||
virtual EventImpl *peek_next (void) const = 0;
|
||||
virtual EventKey peek_next_key (void) const = 0;
|
||||
virtual void remove_next (void) = 0;
|
||||
virtual EventKey remove (Event const ev) = 0;
|
||||
virtual EventImpl *remove (EventId id, EventKey *key) = 0;
|
||||
virtual bool is_valid (EventId id) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
|
||||
#include "simulator.h"
|
||||
#include "scheduler.h"
|
||||
#include "event.h"
|
||||
#include "event.tcc"
|
||||
#include "ns3/system-semaphore.h"
|
||||
#include "event-impl.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cassert>
|
||||
@@ -57,24 +55,20 @@ public:
|
||||
void enable_log_to (char const *filename);
|
||||
|
||||
bool is_finished (void) const;
|
||||
uint64_t next_us (void) const;
|
||||
Time next (void) const;
|
||||
void stop (void);
|
||||
void stop_at_us (uint64_t at);
|
||||
Event schedule_rel_us (Event event, uint64_t delta);
|
||||
Event schedule_rel_s (Event event, double delta);
|
||||
Event schedule_abs_us (Event event, uint64_t time);
|
||||
Event schedule_abs_s (Event event, double time);
|
||||
Event remove (Event const ev);
|
||||
void stop_at (Time time);
|
||||
EventId schedule (Time time, EventImpl *event);
|
||||
void remove (EventId ev);
|
||||
void cancel (EventId ev);
|
||||
bool is_expired (EventId ev);
|
||||
void run (void);
|
||||
uint64_t now_us (void);
|
||||
double now_s (void);
|
||||
void schedule_now (Event event);
|
||||
void schedule_destroy (Event event);
|
||||
Time now (void) const;
|
||||
|
||||
private:
|
||||
void process_one_event (void);
|
||||
|
||||
typedef std::list<std::pair<Event,uint32_t> > Events;
|
||||
typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
|
||||
Events m_destroy;
|
||||
uint64_t m_stop_at;
|
||||
bool m_stop;
|
||||
@@ -103,10 +97,11 @@ SimulatorPrivate::SimulatorPrivate (Scheduler *events)
|
||||
SimulatorPrivate::~SimulatorPrivate ()
|
||||
{
|
||||
while (!m_destroy.empty ()) {
|
||||
Event ev = m_destroy.front ().first;
|
||||
EventImpl *ev = m_destroy.front ().first;
|
||||
m_destroy.pop_front ();
|
||||
TRACE ("handle destroy " << ev);
|
||||
ev ();
|
||||
ev->invoke ();
|
||||
delete ev;
|
||||
}
|
||||
delete m_events;
|
||||
m_events = (Scheduler *)0xdeadbeaf;
|
||||
@@ -123,7 +118,7 @@ SimulatorPrivate::enable_log_to (char const *filename)
|
||||
void
|
||||
SimulatorPrivate::process_one_event (void)
|
||||
{
|
||||
Event next_ev = m_events->peek_next ();
|
||||
EventImpl *next_ev = m_events->peek_next ();
|
||||
Scheduler::EventKey next_key = m_events->peek_next_key ();
|
||||
m_events->remove_next ();
|
||||
TRACE ("handle " << next_ev);
|
||||
@@ -132,7 +127,8 @@ SimulatorPrivate::process_one_event (void)
|
||||
if (m_log_enable) {
|
||||
m_log << "e "<<next_key.m_uid << " " << next_key.m_time << std::endl;
|
||||
}
|
||||
next_ev ();
|
||||
next_ev->invoke ();
|
||||
delete next_ev;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -140,12 +136,12 @@ SimulatorPrivate::is_finished (void) const
|
||||
{
|
||||
return m_events->is_empty ();
|
||||
}
|
||||
uint64_t
|
||||
SimulatorPrivate::next_us (void) const
|
||||
Time
|
||||
SimulatorPrivate::next (void) const
|
||||
{
|
||||
assert (!m_events->is_empty ());
|
||||
Scheduler::EventKey next_key = m_events->peek_next_key ();
|
||||
return next_key.m_time;
|
||||
return AbsTimeUs (next_key.m_time);
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +149,7 @@ void
|
||||
SimulatorPrivate::run (void)
|
||||
{
|
||||
while (!m_events->is_empty () && !m_stop &&
|
||||
(m_stop_at == 0 || m_stop_at > next_us ())) {
|
||||
(m_stop_at == 0 || m_stop_at > next ().us ())) {
|
||||
process_one_event ();
|
||||
}
|
||||
m_log.close ();
|
||||
@@ -166,79 +162,67 @@ SimulatorPrivate::stop (void)
|
||||
m_stop = true;
|
||||
}
|
||||
void
|
||||
SimulatorPrivate::stop_at_us (uint64_t at)
|
||||
SimulatorPrivate::stop_at (Time at)
|
||||
{
|
||||
m_stop_at = at;
|
||||
m_stop_at = at.us ();
|
||||
}
|
||||
Event
|
||||
SimulatorPrivate::schedule_rel_us (Event event, uint64_t delta)
|
||||
EventId
|
||||
SimulatorPrivate::schedule (Time time, EventImpl *event)
|
||||
{
|
||||
uint64_t current = now_us ();
|
||||
return schedule_abs_us (event, current+delta);
|
||||
}
|
||||
Event
|
||||
SimulatorPrivate::schedule_abs_us (Event event, uint64_t time)
|
||||
{
|
||||
assert (time >= now_us ());
|
||||
Scheduler::EventKey key = {time, m_uid};
|
||||
if (time.is_destroy ()) {
|
||||
m_destroy.push_back (std::make_pair (event, m_uid));
|
||||
if (m_log_enable) {
|
||||
m_log << "id " << m_current_uid << " " << now ().us () << " "
|
||||
<< m_uid << std::endl;
|
||||
}
|
||||
m_uid++;
|
||||
//XXX
|
||||
return EventId ();
|
||||
}
|
||||
assert (time.us () >= now ().us ());
|
||||
Scheduler::EventKey key = {time.us (), m_uid};
|
||||
if (m_log_enable) {
|
||||
m_log << "i "<<m_current_uid<<" "<<now_us ()<<" "
|
||||
<<m_uid<<" "<<time << std::endl;
|
||||
m_log << "i "<<m_current_uid<<" "<<now ().us ()<<" "
|
||||
<<m_uid<<" "<<time.us () << std::endl;
|
||||
}
|
||||
m_uid++;
|
||||
return m_events->insert (event, key);
|
||||
}
|
||||
uint64_t
|
||||
SimulatorPrivate::now_us (void)
|
||||
Time
|
||||
SimulatorPrivate::now (void) const
|
||||
{
|
||||
return m_current_us;
|
||||
}
|
||||
Event
|
||||
SimulatorPrivate::schedule_rel_s (Event event, double delta)
|
||||
{
|
||||
int64_t delta_us = (int64_t)(delta * 1000000.0);
|
||||
uint64_t us = now_us () + delta_us;
|
||||
return schedule_abs_us (event, us);
|
||||
}
|
||||
Event
|
||||
SimulatorPrivate::schedule_abs_s (Event event, double time)
|
||||
{
|
||||
int64_t us = (int64_t)(time * 1000000.0);
|
||||
assert (us >= 0);
|
||||
return schedule_abs_us (event, (uint64_t)us);
|
||||
}
|
||||
double
|
||||
SimulatorPrivate::now_s (void)
|
||||
{
|
||||
double us = m_current_us;
|
||||
us /= 1000000;
|
||||
return us;
|
||||
}
|
||||
void
|
||||
SimulatorPrivate::schedule_now (Event event)
|
||||
{
|
||||
schedule_abs_us (event, now_us ());
|
||||
}
|
||||
void
|
||||
SimulatorPrivate::schedule_destroy (Event event)
|
||||
{
|
||||
m_destroy.push_back (std::make_pair (event, m_uid));
|
||||
if (m_log_enable) {
|
||||
m_log << "id " << m_current_uid << " " << now_us () << " "
|
||||
<< m_uid << std::endl;
|
||||
}
|
||||
m_uid++;
|
||||
return AbsTimeUs (m_current_us);
|
||||
}
|
||||
|
||||
Event
|
||||
SimulatorPrivate::remove (Event const ev)
|
||||
void
|
||||
SimulatorPrivate::remove (EventId ev)
|
||||
{
|
||||
Scheduler::EventKey key = m_events->remove (ev);
|
||||
Scheduler::EventKey key;
|
||||
EventImpl *impl = m_events->remove (ev, &key);
|
||||
delete impl;
|
||||
if (m_log_enable) {
|
||||
m_log << "r " << m_current_uid << " " << now_us () << " "
|
||||
m_log << "r " << m_current_uid << " " << now ().us () << " "
|
||||
<< key.m_uid << " " << key.m_time << std::endl;
|
||||
}
|
||||
return Event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
SimulatorPrivate::cancel (EventId id)
|
||||
{
|
||||
assert (m_events->is_valid (id));
|
||||
EventImpl *ev = id.get_event_impl ();
|
||||
ev->cancel ();
|
||||
}
|
||||
|
||||
bool
|
||||
SimulatorPrivate::is_expired (EventId ev)
|
||||
{
|
||||
if (ev.get_event_impl () != 0 &&
|
||||
ev.get_time () <= now ().us () &&
|
||||
ev.get_uid () < m_current_uid) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,10 +296,10 @@ Simulator::is_finished (void)
|
||||
{
|
||||
return get_priv ()->is_finished ();
|
||||
}
|
||||
uint64_t
|
||||
Simulator::next_us (void)
|
||||
Time
|
||||
Simulator::next (void)
|
||||
{
|
||||
return get_priv ()->next_us ();
|
||||
return get_priv ()->next ();
|
||||
}
|
||||
|
||||
|
||||
@@ -331,63 +315,39 @@ Simulator::stop (void)
|
||||
get_priv ()->stop ();
|
||||
}
|
||||
void
|
||||
Simulator::stop_at_us (uint64_t at)
|
||||
Simulator::stop_at (Time at)
|
||||
{
|
||||
get_priv ()->stop_at_us (at);
|
||||
get_priv ()->stop_at (at);
|
||||
}
|
||||
Event
|
||||
Simulator::schedule_rel_us (uint64_t delta, Event event)
|
||||
Time
|
||||
Simulator::now (void)
|
||||
{
|
||||
TRACE ("insert " << event << " in " << delta << "us");
|
||||
return get_priv ()->schedule_rel_us (event, delta);
|
||||
}
|
||||
Event
|
||||
Simulator::schedule_abs_us (uint64_t time, Event event)
|
||||
{
|
||||
TRACE ("insert " << event << " at " << time << "us");
|
||||
return get_priv ()->schedule_abs_us (event, time);
|
||||
}
|
||||
uint64_t
|
||||
Simulator::now_us (void)
|
||||
{
|
||||
return get_priv ()->now_us ();
|
||||
}
|
||||
Event
|
||||
Simulator::schedule_rel_s (double delta, Event event)
|
||||
{
|
||||
TRACE ("insert " << event << " in " << delta << "s");
|
||||
return get_priv ()->schedule_rel_s (event, delta);
|
||||
}
|
||||
Event
|
||||
Simulator::schedule_abs_s (double time, Event event)
|
||||
{
|
||||
TRACE ("insert " << event << " at " << time << "s");
|
||||
return get_priv ()->schedule_abs_s (event, time);
|
||||
}
|
||||
double
|
||||
Simulator::now_s (void)
|
||||
{
|
||||
return get_priv ()->now_s ();
|
||||
}
|
||||
void
|
||||
Simulator::schedule_now (Event event)
|
||||
{
|
||||
TRACE ("insert later " << event);
|
||||
return get_priv ()->schedule_now (event);
|
||||
}
|
||||
void
|
||||
Simulator::schedule_destroy (Event event)
|
||||
{
|
||||
TRACE ("insert at destroy " << event);
|
||||
return get_priv ()->schedule_destroy (event);
|
||||
return get_priv ()->now ();
|
||||
}
|
||||
|
||||
Event
|
||||
Simulator::remove (Event const ev)
|
||||
EventId
|
||||
Simulator::schedule (Time time, EventImpl *ev)
|
||||
{
|
||||
return get_priv ()->schedule (time, ev);
|
||||
}
|
||||
|
||||
void
|
||||
Simulator::remove (EventId ev)
|
||||
{
|
||||
return get_priv ()->remove (ev);
|
||||
}
|
||||
|
||||
void
|
||||
Simulator::cancel (EventId ev)
|
||||
{
|
||||
return get_priv ()->cancel (ev);
|
||||
}
|
||||
bool
|
||||
Simulator::is_expired (EventId id)
|
||||
{
|
||||
return get_priv ()->is_expired (id);
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
#define SIMULATOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "event.h"
|
||||
#include "event-id.h"
|
||||
#include "event-impl.h"
|
||||
#include "time.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
class SimulatorPrivate;
|
||||
|
||||
/**
|
||||
@@ -104,7 +107,7 @@ public:
|
||||
* method is undefined. Otherwise, it returns the microsecond-based
|
||||
* time of the next event expected to be scheduled.
|
||||
*/
|
||||
static uint64_t next_us (void);
|
||||
static Time next (void);
|
||||
|
||||
/**
|
||||
* Run the simulation until one of:
|
||||
@@ -127,75 +130,100 @@ public:
|
||||
* is greater than or equal to the stop time.
|
||||
* @param at the stop time.
|
||||
*/
|
||||
static void stop_at_us (uint64_t at);
|
||||
static void stop_at (Time time);
|
||||
|
||||
/**
|
||||
* Schedule an event to expire at delta, relative to the
|
||||
* current time.
|
||||
* @param delta the expiration time relative to the current
|
||||
* time. Expressed in microsecond units.
|
||||
* Schedule an event to expire at time.
|
||||
*
|
||||
* @param delta the expiration time of the event.
|
||||
* @param event the event to schedule.
|
||||
* @returns an id for the scheduled event.
|
||||
*/
|
||||
static Event schedule_rel_us (uint64_t delta, Event event);
|
||||
/**
|
||||
* Schedule an event to expire at delta, relative to the
|
||||
* current time.
|
||||
* @param delta the expiration time, relative to the current
|
||||
* time. Expressed in second units.
|
||||
* @param event the event to schedule.
|
||||
*/
|
||||
static Event schedule_rel_s (double delta, Event event);
|
||||
/**
|
||||
* Schedule an event to expire at an absolute time.
|
||||
* @param time the expiration time. Expressed in
|
||||
* microsecond units.
|
||||
* @param event the event to schedule.
|
||||
*/
|
||||
static Event schedule_abs_us (uint64_t time, Event event);
|
||||
/**
|
||||
* Schedule an event to expire at an absolute time.
|
||||
* @param time the expiration time. Expressed in
|
||||
* second units.
|
||||
* @param event the event to schedule.
|
||||
*/
|
||||
static Event schedule_abs_s (double time, Event event);
|
||||
template <typename T>
|
||||
static EventId schedule (Time time, void (T::*mem_ptr) (void), T *obj) {
|
||||
class EventMemberImpl0 : public EventImpl {
|
||||
public:
|
||||
typedef void (T::*F)(void);
|
||||
EventMemberImpl0 (T *obj, F function)
|
||||
: m_obj (obj),
|
||||
m_function (function)
|
||||
{}
|
||||
virtual ~EventMemberImpl0 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(m_obj->*m_function) ();
|
||||
}
|
||||
T* m_obj;
|
||||
F m_function;
|
||||
} *ev = new EventMemberImpl0 (obj, mem_ptr);
|
||||
return schedule (time, ev);
|
||||
}
|
||||
static EventId schedule (Time time, void (*f) (void)) {
|
||||
class EventFunctionImpl0 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(void);
|
||||
|
||||
EventFunctionImpl0 (F function)
|
||||
: m_function (function)
|
||||
{}
|
||||
protected:
|
||||
virtual void notify (void) {
|
||||
(*m_function) ();
|
||||
}
|
||||
private:
|
||||
virtual ~EventFunctionImpl0 () {}
|
||||
F m_function;
|
||||
} *ev = new EventFunctionImpl0 (f);
|
||||
return schedule (time, ev);
|
||||
}
|
||||
template <typename T1>
|
||||
static EventId schedule (Time time, void (*f) (T1), T1 a1) {
|
||||
class EventFunctionImpl1 : public EventImpl {
|
||||
public:
|
||||
typedef void (*F)(T1);
|
||||
|
||||
EventFunctionImpl1 (F function, T1 a1)
|
||||
: m_function (function),
|
||||
m_a1 (a1)
|
||||
{ }
|
||||
protected:
|
||||
virtual ~EventFunctionImpl1 () {}
|
||||
private:
|
||||
virtual void notify (void) {
|
||||
(*m_function) (m_a1);
|
||||
}
|
||||
F m_function;
|
||||
T1 m_a1;
|
||||
} *ev = new EventFunctionImpl1(f, a1);
|
||||
return schedule (time, ev);
|
||||
}
|
||||
/**
|
||||
* Unschedule the event. i.e.: the removed event never expires.
|
||||
* @param id the event to remove from the list of scheduled events.
|
||||
*/
|
||||
static Event remove (Event const id);
|
||||
/**
|
||||
* Return the "current time" in microsecond units.
|
||||
static void remove (EventId id);
|
||||
/*
|
||||
XXX
|
||||
*/
|
||||
static uint64_t now_us (void);
|
||||
/**
|
||||
* Return the "current time" in second units.
|
||||
static void cancel (EventId id);
|
||||
/*
|
||||
XXX
|
||||
*/
|
||||
static double now_s (void);
|
||||
static bool is_expired (EventId id);
|
||||
/**
|
||||
* Schedule an event to expire right now. i.e., it will
|
||||
* expire after the currently-executing event is executed.
|
||||
* If multiple events are scheduled with this method,
|
||||
* they are executed in FIFO order: the events scheduled first
|
||||
* are executed first.
|
||||
* @param event the event to schedule now.
|
||||
* Return the "current time".
|
||||
*/
|
||||
static void schedule_now (Event event);
|
||||
/**
|
||||
* Schedule an event to expire when the Simulator::destroy method
|
||||
* is invoked. Events are executed in FIFO order: the events
|
||||
* scheduled first are executed first.
|
||||
* @param event the event to schedule.
|
||||
*/
|
||||
static void schedule_destroy (Event event);
|
||||
static Time now (void);
|
||||
private:
|
||||
Simulator ();
|
||||
~Simulator ();
|
||||
static SimulatorPrivate *get_priv (void);
|
||||
static EventId schedule (Time time, EventImpl *event);
|
||||
static SimulatorPrivate *m_priv;
|
||||
static enum ListType {
|
||||
LINKED_LIST,
|
||||
BINARY_HEAP,
|
||||
|
||||
STD_MAP
|
||||
} m_list_type;
|
||||
};
|
||||
|
||||
99
src/simulator/time.cc
Normal file
99
src/simulator/time.cc
Normal file
@@ -0,0 +1,99 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
|
||||
/*
|
||||
* Copyright (c) 2005,2006 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "time.h"
|
||||
#include "simulator.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Time::Time ()
|
||||
: m_us (0),
|
||||
m_is_destroy (true)
|
||||
{}
|
||||
Time::Time (Time const &o)
|
||||
: m_us (o.m_us),
|
||||
m_is_destroy (o.m_is_destroy)
|
||||
{}
|
||||
Time &
|
||||
Time::operator = (Time const &o)
|
||||
{
|
||||
m_us = o.m_us;
|
||||
m_is_destroy = o.m_is_destroy;
|
||||
return *this;
|
||||
}
|
||||
Time::Time (uint64_t us)
|
||||
: m_us (us),
|
||||
m_is_destroy (false)
|
||||
{}
|
||||
|
||||
double
|
||||
Time::s (void) const
|
||||
{
|
||||
double us = m_us;
|
||||
us /= 1000000;
|
||||
return us;
|
||||
}
|
||||
uint64_t
|
||||
Time::us (void) const
|
||||
{
|
||||
return m_us;
|
||||
}
|
||||
|
||||
bool
|
||||
Time::is_destroy (void) const
|
||||
{
|
||||
return m_is_destroy;
|
||||
}
|
||||
|
||||
Time
|
||||
operator + (Time const &lhs, uint64_t delta_us)
|
||||
{
|
||||
return AbsTimeUs (lhs.us () + delta_us);
|
||||
}
|
||||
Time
|
||||
operator + (Time const &lhs, double delta_s)
|
||||
{
|
||||
uint64_t delta_us = (uint64_t)(int64_t)(delta_s * 1000000.0);
|
||||
return AbsTimeUs (lhs.us () + delta_us);
|
||||
}
|
||||
|
||||
|
||||
AbsTimeS::AbsTimeS (double s)
|
||||
: Time ((uint64_t)(int64_t)(s * 1000000.0))
|
||||
{}
|
||||
AbsTimeUs::AbsTimeUs (uint64_t us)
|
||||
: Time (us)
|
||||
{}
|
||||
RelTimeS::RelTimeS (double s)
|
||||
: Time (Simulator::now () + s)
|
||||
{}
|
||||
RelTimeUs::RelTimeUs (uint64_t us)
|
||||
: Time (Simulator::now () + us)
|
||||
{}
|
||||
|
||||
NowTime::NowTime ()
|
||||
: Time (Simulator::now ().us ())
|
||||
{}
|
||||
|
||||
DestroyTime::DestroyTime ()
|
||||
: Time ()
|
||||
{}
|
||||
|
||||
}; // namespace ns3
|
||||
76
src/simulator/time.h
Normal file
76
src/simulator/time.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
|
||||
/*
|
||||
* Copyright (c) 2005,2006 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef TIME_H
|
||||
#define TIME_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Time {
|
||||
public:
|
||||
Time (Time const &o);
|
||||
Time &operator = (Time const &o);
|
||||
double s (void) const;
|
||||
uint64_t us (void) const;
|
||||
bool is_destroy (void) const;
|
||||
protected:
|
||||
Time (uint64_t us);
|
||||
Time ();
|
||||
private:
|
||||
uint64_t m_us;
|
||||
bool m_is_destroy;
|
||||
};
|
||||
|
||||
Time operator + (Time const &lhs, uint64_t delta);
|
||||
Time operator + (Time const &lhs, double delta);
|
||||
|
||||
|
||||
class AbsTimeS : public Time {
|
||||
public:
|
||||
AbsTimeS (double s);
|
||||
};
|
||||
class AbsTimeUs : public Time {
|
||||
public:
|
||||
AbsTimeUs (uint64_t us);
|
||||
};
|
||||
class RelTimeS : public Time {
|
||||
public:
|
||||
RelTimeS (double s);
|
||||
};
|
||||
class RelTimeUs : public Time {
|
||||
public:
|
||||
RelTimeUs (uint64_t us);
|
||||
};
|
||||
|
||||
class NowTime : public Time {
|
||||
public:
|
||||
NowTime ();
|
||||
};
|
||||
|
||||
class DestroyTime : public Time {
|
||||
public:
|
||||
DestroyTime ();
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* TIME_H */
|
||||
Reference in New Issue
Block a user