Skip to content
Snippets Groups Projects

Local_dc work on issue #201.

5 files
+ 378
40
Compare changes
  • Side-by-side
  • Inline
Files
5
+ 191
0
//
// Created by jonathan.hanks on 12/17/20.
//
#include <args.h>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <array>
#include <atomic>
#include <chrono>
#include <iostream>
#include <iterator>
#include <thread>
#include <set>
#include <string>
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp>
#include "drv/shmem.h"
#include "daq_core.h"
std::vector< unsigned int >
parse_dcu_list( const char* dcu_list )
{
std::vector< unsigned int > dcus;
std::string list( dcu_list ? dcu_list : "" );
std::array< char, 2 > delims{ ' ', ',' };
std::vector< std::string > str_list;
boost::algorithm::split(
str_list, list, boost::algorithm::is_any_of( delims ) );
dcus.reserve( str_list.size( ) );
std::transform( str_list.begin( ),
str_list.end( ),
std::back_inserter( dcus ),
[]( const std::string& s ) -> int {
std::istringstream os( s );
unsigned int val;
os >> val;
return val;
} );
return dcus;
}
template < typename T >
T
atomic_read( const volatile T& val )
{
return reinterpret_cast< const std::atomic< const T >* >(
const_cast< T* const >( &val ) )
->load( );
}
volatile daq_multi_cycle_data_t*
from_raw_buffer( volatile void* buffer )
{
return reinterpret_cast< volatile daq_multi_cycle_data_t* >( buffer );
}
unsigned int
get_cur_cycle( volatile void* buffer )
{
return atomic_read( from_raw_buffer( buffer )->header.curCycle );
}
unsigned int
get_cycle_data_size( volatile void* buffer )
{
return atomic_read( from_raw_buffer( buffer )->header.cycleDataSize );
}
volatile char*
get_main_data_block( volatile void* buffer )
{
return &from_raw_buffer( buffer )->dataBlock[ 0 ];
}
volatile daq_multi_dcu_data_t*
get_cycle_header( volatile void* buffer,
unsigned int cycle,
unsigned int cycle_data_size )
{
auto data = get_main_data_block( buffer );
return reinterpret_cast< volatile daq_multi_dcu_data_t* >(
data + cycle * cycle_data_size );
}
int
main( int argc, char* argv[] )
{
int period = 0;
int size_mb = 0;
const char* mbuf_name = nullptr;
const char* dcu_expected_str = nullptr;
const char* dcu_prohibited_str = nullptr;
auto parser = args_create_parser(
"Test a daq_multi_cycle mbuf for the existence or absence of dcus" );
args_add_string_ptr( parser,
'b',
ARGS_NO_LONG,
"name",
"Mbuf to check",
&mbuf_name,
"local_dc" );
args_add_int( parser,
'm',
ARGS_NO_LONG,
"MB",
"Size in MB of the mbuf",
&size_mb,
100 );
args_add_int(
parser, 'p', "period", "s", "Seconds to run test for", &period, 5 );
args_add_string_ptr( parser,
ARGS_NO_SHORT,
"require-dcus",
"dcus",
"comma seperated list of required dcus",
&dcu_expected_str,
"" );
args_add_string_ptr( parser,
ARGS_NO_SHORT,
"prohibit-dcus",
"dcus",
"comma seperated list of unexpected dcus",
&dcu_prohibited_str,
"" );
if ( args_parse( parser, argc, argv ) < 0 || size_mb < 20 ||
size_mb > 100 || period < 1 || period > 100 )
{
args_fprint_usage( parser, argv[ 0 ], stderr );
std::exit( 1 );
}
auto expected_dcus = parse_dcu_list( dcu_expected_str );
auto prohibited_dcus = parse_dcu_list( dcu_prohibited_str );
auto raw_buffer = shmem_open_segment( mbuf_name, size_mb * 1024 * 1024 );
auto prev_cycle = get_cur_cycle( raw_buffer );
std::set< unsigned int > dcus_seen;
auto end_at =
std::chrono::steady_clock::now( ) + std::chrono::seconds( period );
while ( std::chrono::steady_clock::now( ) < end_at )
{
auto cur_cycle = get_cur_cycle( raw_buffer );
if ( cur_cycle != prev_cycle )
{
auto cycle_size = get_cycle_data_size( raw_buffer );
auto multi_dcus =
get_cycle_header( raw_buffer, cur_cycle, cycle_size );
auto total_models =
atomic_read( multi_dcus->header.dcuTotalModels );
for ( auto i = 0; i < total_models; ++i )
{
auto& cur_header = multi_dcus->header.dcuheader[ i ];
auto cur_dcu_id = atomic_read( cur_header.dcuId );
dcus_seen.insert( cur_dcu_id );
if ( std::find( prohibited_dcus.begin( ),
prohibited_dcus.end( ),
cur_dcu_id ) != prohibited_dcus.end( ) )
{
std::cerr << "Found prohibited dcuid " << cur_dcu_id
<< std::endl;
std::exit( 1 );
}
}
}
std::this_thread::sleep_for( std::chrono::milliseconds( 5 ) );
}
for ( const auto& cur_dcu_id : expected_dcus )
{
if ( dcus_seen.find( cur_dcu_id ) == dcus_seen.end( ) )
{
std::cerr << "Missing required dcuid " << cur_dcu_id << std::endl;
std::exit( 1 );
}
}
return 0;
}
Loading