#include <iostream>
#include <cstring>
#include <cstdlib>
struct cfg_t
{
unsigned long long m_messages = 5000000;
std::chrono::milliseconds m_delay = std::chrono::milliseconds{ 100 };
enum class timer_type_t {
wheel,
list,
heap
} m_timer_type = { timer_type_t::wheel };
};
template< class T >
T str_to_value( const char * s )
{
std::stringstream stream;
stream << s;
stream.seekg( 0 );
T r;
stream >> r;
if( !stream || !stream.eof() )
throw std::invalid_argument(
std::string( "unable to parse value '" ) + s + "'" );
return r;
}
cfg_t parse_args( int argc, char ** argv )
{
cfg_t result;
for( char ** current = &argv[1], ** last = &argv[argc];
current != last; ++current )
{
if( 0 == std::strcmp( *current, "-h" ) )
{
std::cout << "Usage:\n\n"
"sample.so_5.many_timers [options]\n\n"
"Where options are:\n"
"-m <count> count of delayed messages to be sent\n"
"-d <millisecons> pause for delayed messages\n"
"-t <type> timer type (wheel, list, heap)\n"
"-h show this help\n"
<< std::flush;
std::exit( 1 );
}
else if( 0 == std::strcmp( *current, "-d" ) )
{
++current;
if( current == last )
throw std::invalid_argument( "-d requires value (milliseconds)" );
result.m_delay = std::chrono::milliseconds(
str_to_value< unsigned int >( *current ) );
}
else if( 0 == std::strcmp( *current, "-m" ) )
{
++current;
if( current == last )
throw std::invalid_argument( "-m requires value (message count)" );
result.m_messages = str_to_value< unsigned long long >( *current );
}
else if( 0 == std::strcmp( *current, "-t" ) )
{
++current;
if( current == last )
throw std::invalid_argument( "-t requires value (timer type)" );
if( 0 == std::strcmp( *current, "wheel" ) )
result.m_timer_type = cfg_t::timer_type_t::wheel;
else if( 0 == std::strcmp( *current, "list" ) )
result.m_timer_type = cfg_t::timer_type_t::list;
else if( 0 == std::strcmp( *current, "heap" ) )
result.m_timer_type = cfg_t::timer_type_t::heap;
else
throw std::invalid_argument( "unknown type of timer" );
}
else
throw std::invalid_argument( std::string( "unknown argument: " ) +
*current );
}
return result;
}
void show_cfg( const cfg_t & cfg )
{
std::string timer_type = "wheel";
if( cfg.m_timer_type == cfg_t::timer_type_t::list )
timer_type = "list";
else if( cfg.m_timer_type == cfg_t::timer_type_t::heap )
timer_type = "heap";
std::cout << "timer: " << timer_type
<< ", messages: " << cfg.m_messages
<< ", delay: " << cfg.m_delay.count() << "ms"
<< std::endl;
}
{
public :
a_receiver_t(
context_t ctx,
unsigned long long messages )
, m_messages_to_receive( messages )
{}
{
}
void evt_timer(mhood_t< msg_timer >)
{
++m_messages_received;
if( m_messages_received == m_messages_to_receive )
}
private :
const unsigned long long m_messages_to_receive;
unsigned long long m_messages_received = { 0 };
};
{
public :
a_sender_t(
context_t ctx,
unsigned long long messages_to_send,
std::chrono::milliseconds delay )
, m_dest_mbox( std::move( dest_mbox ) )
, m_messages_to_send( messages_to_send )
, m_delay( delay )
{}
{
for( unsigned long long i = 0; i != m_messages_to_send; ++i )
so_5::send_delayed< msg_timer >( m_dest_mbox, m_delay );
}
private :
const unsigned long long m_messages_to_send;
const std::chrono::milliseconds m_delay;
};
void run_sobjectizer( const cfg_t & cfg )
{
{
auto a_receiver = coop.
make_agent< a_receiver_t >( cfg.m_messages );
a_receiver->so_direct_mbox(), cfg.m_messages, cfg.m_delay );
});
},
{
if( cfg.m_timer_type == cfg_t::timer_type_t::list )
else if( cfg.m_timer_type == cfg_t::timer_type_t::heap )
params.timer_thread( timer );
} );
}
int main( int argc, char ** argv )
{
try
{
const auto cfg = parse_args( argc, argv );
show_cfg( cfg );
run_sobjectizer( cfg );
return 0;
}
catch( const std::exception & x )
{
std::cerr << "Exception caught: " << x.what() << std::endl;
}
return 2;
}