10 changed files with 1939 additions and 0 deletions
@ -0,0 +1,58 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ |
||||
#include "yans/callback.h" |
||||
#include <cassert> |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
static double
|
||||
cb_one (double a, double b) |
||||
{ |
||||
std::cout << "invoke cb_one a=" << a << ", b=" << b << std::endl; |
||||
return a; |
||||
} |
||||
|
||||
class MyCb { |
||||
public: |
||||
int cb_two (double a) { |
||||
std::cout << "invoke cb_two a=" << a << std::endl; |
||||
return -5; |
||||
} |
||||
}; |
||||
|
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
// return type: double
|
||||
// first arg type: double
|
||||
// second arg type: double
|
||||
Callback<double, double, double> one; |
||||
// build callback instance which points to cb_one function
|
||||
one = make_callback (&cb_one); |
||||
// this is not a null callback
|
||||
assert (!one.is_null ()); |
||||
// invoke cb_one function through callback instance
|
||||
double ret_one; |
||||
ret_one = one (10.0, 20.0); |
||||
|
||||
// return type: int
|
||||
// first arg type: double
|
||||
Callback<int, double> two; |
||||
MyCb cb; |
||||
// build callback instance which points to MyCb::cb_two
|
||||
two = make_callback (&MyCb::cb_two, &cb); |
||||
// this is not a null callback
|
||||
assert (!two.is_null ()); |
||||
// invoke MyCb::cb_two through callback instance
|
||||
int ret_two; |
||||
ret_two = two (10.0);
|
||||
|
||||
two = make_null_callback<int, double> (); |
||||
// invoking a null callback is just like
|
||||
// invoking a null function pointer:
|
||||
// it will crash.
|
||||
//int ret_two_null = two (20.0);
|
||||
assert (two.is_null ()); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,42 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ |
||||
#include "yans/event.h" |
||||
#include "yans/event.tcc" |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
class MyModel { |
||||
public: |
||||
void deal_with_event (double event_value); |
||||
}; |
||||
|
||||
void |
||||
MyModel::deal_with_event (double value) |
||||
{ |
||||
std::cout << "Member method received event." << std::endl; |
||||
} |
||||
|
||||
static void
|
||||
random_function (void) |
||||
{ |
||||
std::cout << "Function received event." << std::endl; |
||||
} |
||||
|
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
Event ev; |
||||
// create event to forward to random_function
|
||||
ev = make_event (&random_function); |
||||
// set cancel bit to on
|
||||
ev.cancel (); |
||||
// try to invoke the random_function through the event.
|
||||
// This does nothing since cancel bit is on.
|
||||
ev (); |
||||
MyModel model; |
||||
// create event to forward to MyModel::deal_with_event
|
||||
// on the class instance "model".
|
||||
ev = make_event (&MyModel::deal_with_event, &model, 10.0); |
||||
// invoke member method through the event.
|
||||
ev (); |
||||
} |
@ -0,0 +1,100 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ |
||||
#include "yans/packet.h" |
||||
#include "yans/chunk.h" |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
/* A sample Chunk implementation
|
||||
*/ |
||||
class MyChunk : public Chunk { |
||||
public: |
||||
MyChunk (); |
||||
virtual ~MyChunk (); |
||||
|
||||
void set_data (uint16_t data); |
||||
uint16_t get_data (void) const; |
||||
private: |
||||
virtual void print (std::ostream *os) const; |
||||
virtual void add_to (Buffer *buffer) const; |
||||
virtual void peek_from (Buffer const *buffer); |
||||
virtual void remove_from (Buffer *buffer); |
||||
|
||||
uint16_t m_data; |
||||
}; |
||||
|
||||
MyChunk::MyChunk () |
||||
{} |
||||
MyChunk::~MyChunk () |
||||
{} |
||||
void
|
||||
MyChunk::print (std::ostream *os) const |
||||
{ |
||||
*os << "MyChunk data=" << m_data << std::endl; |
||||
} |
||||
void
|
||||
MyChunk::add_to (Buffer *buffer) const |
||||
{ |
||||
// reserve 2 bytes at head of buffer
|
||||
buffer->add_at_start (2); |
||||
Buffer::Iterator i = buffer->begin (); |
||||
// serialize in head of buffer
|
||||
i.write_hton_u16 (m_data); |
||||
} |
||||
void
|
||||
MyChunk::peek_from (Buffer const *buffer) |
||||
{ |
||||
Buffer::Iterator i = buffer->begin (); |
||||
// deserialize from head of buffer
|
||||
m_data = i.read_ntoh_u16 (); |
||||
} |
||||
void
|
||||
MyChunk::remove_from (Buffer *buffer) |
||||
{ |
||||
// remove deserialized data
|
||||
buffer->remove_at_start (2); |
||||
} |
||||
|
||||
void
|
||||
MyChunk::set_data (uint16_t data) |
||||
{ |
||||
m_data = data; |
||||
} |
||||
uint16_t
|
||||
MyChunk::get_data (void) const |
||||
{ |
||||
return m_data; |
||||
} |
||||
|
||||
/* A sample Tag implementation
|
||||
*/ |
||||
struct MyTag { |
||||
uint16_t m_stream_id; |
||||
}; |
||||
|
||||
|
||||
static void |
||||
receive (Packet p) |
||||
{ |
||||
MyChunk my; |
||||
p.peek (&my); |
||||
p.remove (&my); |
||||
std::cout << "received data=" << my.get_data () << std::endl; |
||||
struct MyTag my_tag; |
||||
p.peek_tag (&my_tag); |
||||
} |
||||
|
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
Packet p; |
||||
MyChunk my; |
||||
my.set_data (2); |
||||
std::cout << "send data=2" << std::endl; |
||||
p.add (&my); |
||||
struct MyTag my_tag; |
||||
my_tag.m_stream_id = 5; |
||||
p.add_tag (&my_tag); |
||||
receive (p); |
||||
return 0; |
||||
} |
@ -0,0 +1,46 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ |
||||
#include "yans/event.h" |
||||
#include "yans/event.tcc" |
||||
#include "yans/simulator.h" |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
class MyModel { |
||||
public: |
||||
void start (void); |
||||
private: |
||||
void deal_with_event (double event_value); |
||||
}; |
||||
|
||||
void
|
||||
MyModel::start (void) |
||||
{ |
||||
Simulator::schedule_rel_s (10.0, make_event (&MyModel::deal_with_event,
|
||||
this, Simulator::now_s ())); |
||||
} |
||||
void |
||||
MyModel::deal_with_event (double value) |
||||
{ |
||||
std::cout << "Member method received event at " << Simulator::now_s () << " started at " << value << std::endl; |
||||
} |
||||
|
||||
static void
|
||||
random_function (MyModel *model) |
||||
{ |
||||
std::cout << "random function received event at " << Simulator::now_s () << std::endl; |
||||
model->start (); |
||||
} |
||||
|
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
MyModel model; |
||||
|
||||
Simulator::schedule_rel_s (10.0, make_event (&random_function,
|
||||
&model)); |
||||
|
||||
Simulator::run (); |
||||
|
||||
Simulator::destroy (); |
||||
} |
@ -0,0 +1,60 @@
|
||||
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ |
||||
#include "yans/trace-container.h" |
||||
#include "yans/ui-traced-variable.tcc" |
||||
#include "yans/packet-logger.h" |
||||
#include "yans/trace-stream.h" |
||||
#include "yans/pcap-writer.h" |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
PacketLogger a; |
||||
UiTracedVariable<unsigned short> b; |
||||
TraceStream c; |
||||
CallbackLogger<double, int> d; |
||||
|
||||
void |
||||
register_all_trace_sources (TraceContainer *container) |
||||
{ |
||||
container->register_packet_logger ("source-a", &a); |
||||
container->register_ui_variable ("source-b", &b); |
||||
container->register_stream ("source-c", &c); |
||||
container->register_callback ("source-d", &d); |
||||
} |
||||
void |
||||
generate_trace_events (void) |
||||
{ |
||||
// log en empty packet
|
||||
a.log (Packet ()); |
||||
b = 10; |
||||
b += 100; |
||||
b += 50; |
||||
b = (unsigned short) -20; |
||||
c << "this is a simple test b=" << b << std::endl; |
||||
d (3.1415, 3); |
||||
} |
||||
|
||||
void |
||||
variable_event (uint64_t old, uint64_t cur) |
||||
{} |
||||
|
||||
void |
||||
callback_event (double a, int b) |
||||
{} |
||||
|
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
TraceContainer traces; |
||||
register_all_trace_sources (&traces); |
||||
PcapWriter pcap; |
||||
pcap.open ("trace-test.log"); |
||||
pcap.write_header_ethernet (); |
||||
traces.set_packet_logger_callback ("source-a",
|
||||
make_callback (&PcapWriter::write_packet, &pcap)); |
||||
traces.set_ui_variable_callback ("source-b", make_callback (&variable_event)); |
||||
traces.set_stream ("source-c", &std::cout); |
||||
traces.set_callback ("source-d", make_callback (&callback_event)); |
||||
generate_trace_events (); |
||||
return 0; |
||||
} |
@ -0,0 +1,135 @@
|
||||
/* -*- 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 "yans/wall-clock-ms.h" |
||||
#include "yans/packet.h" |
||||
#include "yans/chunk-constant-data.h" |
||||
#include "yans/chunk-udp.h" |
||||
#include "yans/chunk-ipv4.h" |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
static void
|
||||
bench_ptr_a (uint32_t n) |
||||
{ |
||||
ChunkConstantData data = ChunkConstantData (2000, 1); |
||||
ChunkUdp udp; |
||||
ChunkIpv4 ipv4; |
||||
|
||||
for (uint32_t i = 0; i < n; i++) { |
||||
Packet p; |
||||
p.add (&data); |
||||
p.add (&udp); |
||||
p.add (&ipv4); |
||||
Packet o = p; |
||||
o.peek (&ipv4); |
||||
o.remove (&ipv4); |
||||
o.peek (&udp); |
||||
o.remove (&udp); |
||||
o.peek (&data); |
||||
o.remove (&data); |
||||
} |
||||
} |
||||
|
||||
static void
|
||||
bench_ptr_b (uint32_t n) |
||||
{ |
||||
ChunkConstantData data = ChunkConstantData (2000, 1); |
||||
ChunkUdp udp; |
||||
ChunkIpv4 ipv4; |
||||
|
||||
for (uint32_t i = 0; i < n; i++) { |
||||
Packet p; |
||||
p.add (&data); |
||||
p.add (&udp); |
||||
p.add (&ipv4); |
||||
} |
||||
} |
||||
|
||||
static void |
||||
ptr_c2 (Packet p) |
||||
{ |
||||
ChunkConstantData data = ChunkConstantData (2000, 1); |
||||
ChunkUdp udp; |
||||
|
||||
p.peek (&udp); |
||||
p.remove (&udp); |
||||
p.peek (&data); |
||||
p.remove (&data); |
||||
} |
||||
|
||||
static void
|
||||
ptr_c1 (Packet p) |
||||
{ |
||||
ChunkIpv4 ipv4; |
||||
p.peek (&ipv4); |
||||
p.remove (&ipv4); |
||||
ptr_c2 (p); |
||||
} |
||||
|
||||
static void |
||||
bench_ptr_c (uint32_t n) |
||||
{ |
||||
ChunkConstantData data = ChunkConstantData (2000, 1); |
||||
ChunkUdp udp; |
||||
ChunkIpv4 ipv4; |
||||
|
||||
for (uint32_t i = 0; i < n; i++) { |
||||
Packet p; |
||||
p.add (&data); |
||||
p.add (&udp); |
||||
p.add (&ipv4); |
||||
ptr_c1 (p); |
||||
} |
||||
} |
||||
|
||||
|
||||
static void |
||||
run_bench (void (*bench) (uint32_t), uint32_t n, char const *name) |
||||
{ |
||||
WallClockMs time; |
||||
time.start (); |
||||
(*bench) (n); |
||||
unsigned long long delta_ms = time.end (); |
||||
double ps = n; |
||||
ps *= 1000; |
||||
ps /= delta_ms; |
||||
std::cout << name<<"=" << ps << " packets/s" << std::endl; |
||||
} |
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
uint32_t n = 0; |
||||
while (argc > 0) { |
||||
if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) { |
||||
char const *n_ascii = argv[0] + strlen ("--n="); |
||||
n = atoi (n_ascii); |
||||
} |
||||
argc--; |
||||
argv++; |
||||
} |
||||
|
||||
run_bench (&bench_ptr_a, n, "a"); |
||||
run_bench (&bench_ptr_b, n, "b"); |
||||
run_bench (&bench_ptr_c, n, "c"); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,148 @@
|
||||
/* -*- 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 "yans/simulator.h" |
||||
#include "yans/event.h" |
||||
#include "yans/event.tcc" |
||||
#include "yans/wall-clock-ms.h" |
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <vector> |
||||
|
||||
using namespace yans; |
||||
|
||||
|
||||
bool g_debug = false; |
||||
|
||||
class Bench { |
||||
public: |
||||
void read_distribution (std::istream &istream); |
||||
void set_total (uint32_t total); |
||||
void bench (void); |
||||
private: |
||||
void cb (void); |
||||
std::vector<uint64_t> m_distribution; |
||||
std::vector<uint64_t>::const_iterator m_current; |
||||
uint32_t m_n; |
||||
uint32_t m_total; |
||||
}; |
||||
|
||||
void
|
||||
Bench::set_total (uint32_t total) |
||||
{ |
||||
m_total = total; |
||||
} |
||||
|
||||
void |
||||
Bench::read_distribution (std::istream &input) |
||||
{ |
||||
double data; |
||||
while (!input.eof ()) { |
||||
if (input >> data) { |
||||
uint64_t us = (uint64_t) (data * 1000000); |
||||
m_distribution.push_back (us); |
||||
} else { |
||||
input.clear (); |
||||
std::string line; |
||||
input >> line; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void |
||||
Bench::bench (void)
|
||||
{ |
||||
WallClockMs time; |
||||
double init, simu; |
||||
time.start (); |
||||
for (std::vector<uint64_t>::const_iterator i = m_distribution.begin (); |
||||
i != m_distribution.end (); i++) { |
||||
Simulator::schedule_rel_us (*i, make_event (&Bench::cb, this)); |
||||
} |
||||
init = time.end (); |
||||
|
||||
m_current = m_distribution.begin (); |
||||
|
||||
time.start (); |
||||
Simulator::run (); |
||||
simu = time.end (); |
||||
|
||||
std::cout << |
||||
"init n=" << m_distribution.size () << ", time=" << init << "s" << std::endl << |
||||
"simu n=" << m_n << ", time=" <<simu << "s" << std::endl << |
||||
"init " << ((double)m_distribution.size ()) / init << " insert/s, avg insert=" << |
||||
init / ((double)m_distribution.size ())<< "s" << std::endl << |
||||
"simu " << ((double)m_n) / simu<< " hold/s, avg hold=" <<
|
||||
simu / ((double)m_n) << "s" << std::endl |
||||
; |
||||
} |
||||
|
||||
void |
||||
Bench::cb (void) |
||||
{ |
||||
if (m_n > m_total) { |
||||
return; |
||||
} |
||||
if (m_current == m_distribution.end ()) { |
||||
m_current = m_distribution.begin (); |
||||
} |
||||
if (g_debug) { |
||||
std::cerr << "event at " << Simulator::now_s () << std::endl; |
||||
} |
||||
Simulator::schedule_rel_us (*m_current, make_event (&Bench::cb, this)); |
||||
m_current++; |
||||
m_n++; |
||||
} |
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
char const *filename = argv[1]; |
||||
std::istream *input; |
||||
argc-=2; |
||||
argv+= 2; |
||||
if (strcmp (filename, "-") == 0) { |
||||
input = &std::cin; |
||||
} else { |
||||
input = new std::ifstream (filename); |
||||
} |
||||
while (argc > 0) { |
||||
if (strcmp ("--list", argv[0]) == 0) { |
||||
Simulator::set_linked_list (); |
||||
} else if (strcmp ("--heap", argv[0]) == 0) { |
||||
Simulator::set_binary_heap (); |
||||
} else if (strcmp ("--map", argv[0]) == 0) { |
||||
Simulator::set_std_map (); |
||||
} else if (strcmp ("--debug", argv[0]) == 0) { |
||||
g_debug = true; |
||||
} else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) { |
||||
char const *filename = argv[0] + strlen ("--log="); |
||||
Simulator::enable_log_to (filename); |
||||
} |
||||
argc--; |
||||
argv++; |
||||
} |
||||
Bench *bench = new Bench (); |
||||
bench->read_distribution (*input); |
||||
bench->set_total (20000); |
||||
bench->bench (); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,265 @@
|
||||
/* -*- 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 "yans/simulator.h" |
||||
#include "yans/event.h" |
||||
#include "yans/event.tcc" |
||||
#include "yans/wall-clock-ms.h" |
||||
#include <vector> |
||||
#include <deque> |
||||
#include <fstream> |
||||
#include <iostream> |
||||
|
||||
using namespace yans; |
||||
|
||||
class LogReader { |
||||
public: |
||||
void read_from_filename (char const *filename); |
||||
void run (void); |
||||
void print_stats (void); |
||||
private: |
||||
struct Command { |
||||
enum { |
||||
REMOVE, |
||||
INSERT, |
||||
INSERT_LATER, |
||||
INSERT_REMOVE |
||||
} m_type; |
||||
// uid at which this command is supposed to be executed.
|
||||
uint32_t m_uid; |
||||
union { |
||||
struct { |
||||
// time at which the event is supposed to expire
|
||||
uint64_t m_ev_us; |
||||
} insert; |
||||
struct { |
||||
// location in the array of events to remove where
|
||||
// to insert this event once it is inserted in
|
||||
// the scheduler.
|
||||
uint32_t m_ev_loc;
|
||||
// time at which the event is supposed to expire
|
||||
uint64_t m_ev_us; |
||||
} insert_remove; |
||||
}; |
||||
}; |
||||
void execute_log_commands (uint32_t uid); |
||||
|
||||
typedef std::deque<struct Command> Commands; |
||||
typedef std::deque<struct Command>::iterator CommandsI; |
||||
typedef std::deque<Event > RemoveEvents; |
||||
|
||||
|
||||
Commands m_commands; |
||||
CommandsI m_command; |
||||
RemoveEvents m_remove_events; |
||||
uint32_t m_uid; |
||||
}; |
||||
|
||||
typedef std::vector<std::pair<uint32_t, uint32_t> > Removes; |
||||
typedef std::vector<std::pair<uint32_t, uint32_t> >::iterator RemovesI; |
||||
|
||||
void |
||||
LogReader::read_from_filename (char const *filename) |
||||
{ |
||||
std::ifstream log; |
||||
std::cout << "read log..." << std::endl; |
||||
Removes removes; |
||||
log.open (filename); |
||||
while (!log.eof ()) { |
||||
std::string type; |
||||
log >> type; |
||||
if (type == "i") { |
||||
uint32_t now_uid, ev_uid; |
||||
uint64_t now_us, ev_us; |
||||
log >> now_uid >> now_us >> ev_uid >> ev_us; |
||||
struct Command cmd; |
||||
cmd.m_type = Command::INSERT; |
||||
cmd.m_uid = now_uid; |
||||
cmd.insert.m_ev_us = ev_us; |
||||
m_commands.push_back (cmd); |
||||
} else if (type == "r") { |
||||
uint32_t now_uid, ev_uid; |
||||
uint64_t now_us, ev_us; |
||||
log >> now_uid >> now_us >> ev_uid >> ev_us; |
||||
struct Command cmd; |
||||
cmd.m_type = Command::REMOVE; |
||||
cmd.m_uid = now_uid; |
||||
m_commands.push_back (cmd); |
||||
removes.push_back (std::make_pair (now_uid, ev_uid)); |
||||
} else if (type == "il") { |
||||
uint32_t now_uid, ev_uid; |
||||
uint64_t now_us, ev_us; |
||||
log >> now_uid >> now_us >> ev_uid >> ev_us; |
||||
struct Command cmd; |
||||
cmd.m_type = Command::INSERT_LATER; |
||||
cmd.m_uid = now_uid; |
||||
m_commands.push_back (cmd); |
||||
} |
||||
} |
||||
log.close (); |
||||
|
||||
std::cout << "gather insert removes..." << std::endl; |
||||
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) { |
||||
if (i->m_type == Command::INSERT) { |
||||
for (RemovesI j = removes.begin (); j != removes.end (); j++) { |
||||
if (j->second == i->m_uid) { |
||||
// this insert will be removed later.
|
||||
uint64_t us = i->insert.m_ev_us; |
||||
uint32_t uid = i->m_uid; |
||||
i->m_type = Command::INSERT_REMOVE; |
||||
i->m_uid = uid; |
||||
i->insert_remove.m_ev_us = us; |
||||
i->insert_remove.m_ev_loc = j->first; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
std::cout << "calculate remove locations..." << std::endl; |
||||
// calculate the final insert/remove location.
|
||||
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) { |
||||
if (i->m_type == Command::INSERT_REMOVE) { |
||||
uint32_t loc = 0; |
||||
for (CommandsI tmp = i; tmp != m_commands.end (); tmp++) { |
||||
if (tmp->m_type == Command::REMOVE && |
||||
tmp->m_uid == i->insert_remove.m_ev_loc) { |
||||
i->insert_remove.m_ev_loc = loc; |
||||
break; |
||||
} |
||||
loc++; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
void |
||||
LogReader::execute_log_commands (uint32_t uid) |
||||
{ |
||||
if (m_command == m_commands.end ()) { |
||||
return; |
||||
} |
||||
//std::cout << "one event, uid=" <<m_uid<< std::endl;
|
||||
struct Command cmd = *m_command; |
||||
//std::cout << "cmd uid=" <<cmd.m_uid<< std::endl;
|
||||
while (cmd.m_uid == uid) { |
||||
m_command++; |
||||
switch (cmd.m_type) { |
||||
case Command::INSERT: |
||||
//std::cout << "exec insert now=" << Simulator::now_us ()
|
||||
//<< ", time=" << cmd.insert.m_ev_us << std::endl;
|
||||
Simulator::schedule_abs_us (cmd.insert.m_ev_us,
|
||||
make_event (&LogReader::execute_log_commands, this, m_uid)); |
||||
m_uid++; |
||||
break; |
||||
case Command::INSERT_LATER: |
||||
//std::cout << "exec insert later" << std::endl;
|
||||
Simulator::schedule_now (make_event (&LogReader::execute_log_commands, this, m_uid)); |
||||
m_uid++; |
||||
break; |
||||
case Command::REMOVE: { |
||||
//std::cout << "exec remove" << std::endl;
|
||||
Event ev = m_remove_events.front (); |
||||
m_remove_events.pop_front (); |
||||
Simulator::remove (ev); |
||||
} break; |
||||
case Command::INSERT_REMOVE: { |
||||
//std::cout << "exec insert remove" << std::endl;
|
||||
Event ev = make_event (&LogReader::execute_log_commands, this, m_uid); |
||||
Simulator::schedule_abs_us (cmd.insert_remove.m_ev_us, ev); |
||||
m_remove_events[cmd.insert_remove.m_ev_loc] = ev; |
||||
m_uid++; |
||||
} break; |
||||
} |
||||
cmd = *m_command; |
||||
} |
||||
} |
||||
|
||||
void |
||||
LogReader::print_stats (void) |
||||
{ |
||||
uint32_t n_inserts = 0; |
||||
uint32_t n_removes = 0; |
||||
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) { |
||||
switch (i->m_type) { |
||||
case Command::INSERT: |
||||
n_inserts++; |
||||
break; |
||||
case Command::INSERT_LATER: |
||||
n_inserts++; |
||||
break; |
||||
case Command::INSERT_REMOVE: |
||||
n_inserts++; |
||||
break; |
||||
case Command::REMOVE: |
||||
n_removes++; |
||||
break; |
||||
} |
||||
} |
||||
std::cout << "inserts="<<n_inserts<<", removes="<<n_removes<<std::endl; |
||||
std::cout << "run simulation..."<<std::endl; |
||||
} |
||||
|
||||
void |
||||
LogReader::run (void) |
||||
{ |
||||
m_uid = 0; |
||||
WallClockMs time; |
||||
time.start (); |
||||
m_command = m_commands.begin (); |
||||
execute_log_commands (m_uid); |
||||
Simulator::run (); |
||||
unsigned long long delta = time.end (); |
||||
double delay = ((double)delta)/1000; |
||||
std::cout << "runtime="<<delay<<"s"<<std::endl; |
||||
} |
||||
|
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
char const *input = 0; |
||||
uint32_t n = 1; |
||||
while (argc > 0) { |
||||
if (strcmp ("--list", argv[0]) == 0) { |
||||
Simulator::set_linked_list (); |
||||
} else if (strcmp ("--heap", argv[0]) == 0) { |
||||
Simulator::set_binary_heap (); |
||||
} else if (strcmp ("--map", argv[0]) == 0) { |
||||
Simulator::set_std_map (); |
||||
} else if (strncmp ("--n=", argv[0], strlen("--n=")) == 0) { |
||||
n = atoi (argv[0]+strlen ("--n=")); |
||||
} else if (strncmp ("--input=", argv[0],strlen ("--input=")) == 0) { |
||||
input = argv[0] + strlen ("--input="); |
||||
} else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) { |
||||
char const *filename = argv[0] + strlen ("--log="); |
||||
Simulator::enable_log_to (filename); |
||||
} |
||||
argc--; |
||||
argv++; |
||||
} |
||||
if (input == 0) { |
||||
std::cerr << "need --input=[filename] option" << std::endl; |
||||
return 1; |
||||
} |
||||
LogReader log; |
||||
log.read_from_filename (input); |
||||
for (uint32_t i = 0; i < n; i++) { |
||||
log.run (); |
||||
} |
||||
} |
@ -0,0 +1,32 @@
|
||||
/* -*- 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 "yans/test.h" |
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
#ifdef RUN_SELF_TESTS |
||||
yans::TestManager::enable_verbose (); |
||||
yans::TestManager::run_tests (); |
||||
#endif /* RUN_SELF_TESTS */ |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue