29 #include <boost/program_options.hpp> 30 #include <boost/program_options/positional_options.hpp> 31 #include <boost/assign/list_of.hpp> 32 #include <boost/algorithm/string/case_conv.hpp> 34 #ifdef ORO_BUILD_RTALLOC 36 #define ORO_MEMORY_POOL 40 #include <boost/date_time/posix_time/posix_time.hpp> 45 #if defined(ORO_SUPPORT_CPU_AFFINITY) 49 #if defined(ORO_BUILD_LOGGING) && defined(OROSEM_LOG4CPP_LOGGING) 57 namespace po = boost::program_options;
59 namespace bpt = boost::posix_time;
65 #define ORO_xstr(s) ORO_str(s) 72 std::map<std::string, RTT::Logger::LogLevel>
logMap =
73 boost::assign::map_list_of
85 std::string& siteFile,
86 std::vector<std::string>& scriptFiles,
88 bool& requireNameService,
89 bool& deploymentOnlyChecked,
91 po::variables_map& vm,
92 po::options_description* otherOptions)
94 std::string logLevel(
"info");
95 po::options_description options;
96 po::options_description allowed(
"Allowed options");
97 po::positional_options_description pos;
100 "Show program usage")
102 "Show program version")
104 "Makes this program a daemon such that it runs in the background. Returns 1 in case of success.")
106 po::value< std::vector<std::string> >(&scriptFiles),
107 "Deployment XML or script file (eg 'config-file.xml', 'script.ops' or 'script.lua')")
109 po::value<std::string>(&siteFile),
110 "Site deployment XML file (eg 'Deployer-site.cpf' or 'Deployer-site.xml')")
112 po::value<std::string>(&logLevel),
113 "Level at which to log from RTT (case-insensitive) Never,Fatal,Critical,Error,Warning,Info,Debug,Realtime")
115 "Turn off RTT logging to the console (will still log to 'orocos.log')")
117 "Only check component loading, connecting peers and ports. Returns 255 in case of errors.")
118 (
"require-name-service",
119 "Require CORBA name service")
121 po::value<int>(&minNumberCPU),
122 "The minimum number of CPUs required for deployment (0 <= value) [0==no minimum (default)]")
124 po::value< std::vector<std::string> >(),
125 "Name of deployer component (the --DeployerName flag is optional). If you provide a script or XML file name, that will be run instead.")
127 pos.add(
"DeployerName", -1);
130 options.add(allowed);
131 if (NULL != otherOptions)
133 options.add(*otherOptions);
138 po::store(po::command_line_parser(argc, argv).
139 options(options).positional(pos).run(),
144 if (vm.count(
"help"))
146 std::cout << options << std::endl;
151 if (vm.count(
"version"))
153 std::cout<<
" OROCOS Toolchain version '" ORO_xstr(RTT_VERSION)
"'";
157 #ifdef OROPKG_OS_LXRT 158 std::cout<<
" -- LXRT/RTAI.";
160 #ifdef OROPKG_OS_GNULINUX 161 std::cout<<
" -- GNU/Linux.";
163 #ifdef OROPKG_OS_XENOMAI 164 std::cout<<
" -- Xenomai.";
170 if (vm.count(
"daemon"))
172 if (vm.count(
"check"))
173 log(
Warning) <<
"--check and --daemon are incompatible. Skipping the --daemon flag." <<
endlog();
179 if ( !(0 <= minNumberCPU) )
181 std::cout << std::endl
182 <<
"ERROR: Invalid minimum number CPU. Require 0 <= value" 183 << std::endl << options << std::endl;
188 if (vm.count(
"no-consolelog"))
194 if (vm.count(
"check"))
196 deploymentOnlyChecked =
true;
197 log(
Info) <<
"Deployment check: Only check component loading, connecting peers and ports. Returns 255 in case of errors." <<
endlog();
200 if (vm.count(
"require-name-service"))
202 requireNameService =
true;
207 logLevel = boost::algorithm::to_lower_copy(logLevel);
208 if (vm.count(
"log-level"))
210 if (0 != logMap.count(logLevel))
216 std::cout <<
"Did not understand log level: " 217 << logLevel << std::endl
218 << options << std::endl;
222 if (vm.count(
"DeployerName")) {
223 const std::vector<std::string> &positional_arguments = vm[
"DeployerName"].as< std::vector<std::string> >();
224 for(std::vector<std::string>::const_iterator it = positional_arguments.begin(); it != positional_arguments.end(); ++it) {
225 if (it->size() >= 1 && it->at(0) ==
'_')
continue;
226 std::string arg = *it;
227 if (arg.rfind(
".xml") != std::string::npos ||
228 arg.rfind(
".cpf") != std::string::npos ||
229 arg.rfind(
".osd") != std::string::npos ||
230 arg.rfind(
".ops") != std::string::npos ||
231 arg.rfind(
".lua") != std::string::npos ) {
232 scriptFiles.push_back(arg);
239 catch (std::logic_error e)
241 std::cerr <<
"Exception:" << e.what() << std::endl << options << std::endl;
250 assert(0 <= minNumberCPU);
253 if (0 < minNumberCPU)
255 #if defined(ORO_SUPPORT_CPU_AFFINITY) 257 int numCPU = sysconf( _SC_NPROCESSORS_ONLN );
259 #error Unsupported configuration! 263 std::cerr <<
"ERROR: Unable to determine the number of CPUs for minimum number CPU support." 267 else if (numCPU < minNumberCPU)
269 std::cerr <<
"ERROR: Number of CPUS (" << numCPU
270 <<
") is less than minimum required (" << minNumberCPU
277 std::cout <<
"WARNING: Ignoring minimum number of CPU requirement " 278 <<
"as RTT does not support CPU affinity on this platform." 286 #ifdef ORO_BUILD_RTALLOC 288 void validate(boost::any& v,
289 const std::vector<std::string>&
values,
290 memorySize* target_type,
int)
295 po::validators::check_first_occurrence(v);
298 const std::string& memSize = po::validators::get_single_string(values);
309 if (2 == sscanf(memSize.c_str(),
"%f%c", &value, &units))
314 units = toupper(units);
329 e <<
"Invalid units in rtalloc-mem-size option: " << memSize
330 <<
". Valid units: 'k','m','g' (case-insensitive).";
331 throw po::invalid_option_value(e.str());
335 else if (1 == sscanf(memSize.c_str(),
"%f", &value))
341 throw po::invalid_option_value(
"Could not parse rtalloc-mem-size option: " + memSize);
352 e <<
"Invalid memory size of " << value <<
" given. Value must be >= 0.";
353 throw po::invalid_option_value(e.str());
356 v = memorySize((
size_t)value);
360 boost::program_options::options_description deployerRtallocOptions(memorySize& rtallocMemorySize)
362 boost::program_options::options_description rtallocOptions(
"Real-time memory allocation options");
363 rtallocOptions.add_options()
365 po::value<memorySize>(&rtallocMemorySize)->default_value(rtallocMemorySize),
366 "Amount of memory to provide for real-time memory allocations (e.g. 10000, 1K, 4.3m)\n" 367 "NB the minimum size depends on TLSF build options, but it is several kilobytes.")
369 return rtallocOptions;
372 TLSFMemoryPool::TLSFMemoryPool() :
376 TLSFMemoryPool::~TLSFMemoryPool()
381 bool TLSFMemoryPool::initialize(
const size_t memSize)
383 if (0 != rtMem)
return false;
384 if (0 >= memSize)
return false;
387 rtMem = malloc(memSize);
390 if ((
size_t)-1 == freeMem)
392 std::cerr << std::dec
393 <<
"Invalid memory pool size of " << memSize
394 <<
" bytes (TLSF has a several kilobyte overhead)." << std::endl;
399 std::cout << std::dec
400 <<
"Real-time memory: " << freeMem <<
" bytes free of " 401 << memSize <<
" allocated." << std::endl;
405 void TLSFMemoryPool::shutdown()
410 if (NULL != getenv(
"ORO_DEPLOYER_DUMP_TLSF_ON_SHUTDOWN"))
412 OCL::deployerDumpTLSF();
416 std::cout << std::dec
418 <<
" overhead=" << overhead
429 void deployerDumpTLSF()
435 const bpt::ptime now = bpt::microsec_clock::local_time();
436 static const size_t START = strlen(
"YYYYMMDDTHHMMSS,");
437 std::string now_s = bpt::to_iso_string(now);
438 now_s.replace(START-1, 1,
".");
439 now_s.erase(now_s.size()-3, 3);
442 FILE* ff = fopen(
"deployer_tlsf_dump.txt",
"a");
445 fprintf(ff,
"# Log at %s\n", now_s.c_str());
446 print_all_blocks_mp(ff);
453 #endif // ORO_BUILD_RTALLOC 456 #if defined(ORO_BUILD_LOGGING) && defined(OROSEM_LOG4CPP_LOGGING) 458 boost::program_options::options_description deployerRttLog4cppOptions(std::string& rttLog4cppConfigFile)
460 po::options_description rttLog4cppOptions(
"RTT/Log4cpp options");
461 rttLog4cppOptions.add_options()
462 (
"rtt-log4cpp-config-file",
463 po::value<std::string>(&rttLog4cppConfigFile),
464 std::string(
"Log4cpp configuration file to support RTT category '" + RTT::Logger::log4cppCategoryName +
"'\n"+
465 "WARNING Configure only this category. Use deployment files to configure realtime logging!").c_str())
467 return rttLog4cppOptions;
470 int deployerConfigureRttLog4cppCategory(
const std::string& rttLog4cppConfigFile)
474 if (!rttLog4cppConfigFile.empty())
482 std::cerr <<
"ERROR: Unable to read/parse log4cpp configuration file\n" 483 << e.what() << std::endl;
508 #endif // OROSEM_LOG4CPP_LOGGING
size_t get_max_size(void *mem_pool)
static Logger * Instance(std::ostream &str=std::cerr)
static Category & getInstance(const std::string &name)
size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
virtual void setConversionPattern(const std::string &conversionPattern)
void setAppender(Appender *appender)
int deployerParseCmdLine(int argc, char **argv, std::string &siteFile, std::vector< std::string > &scriptFiles, std::string &name, bool &requireNameService, bool &deploymentOnlyChecked, int &minNumberCPU, po::variables_map &vm, po::options_description *otherOptions)
void destroy_memory_pool(void *mem_pool)
void mayLogStdOut(bool tf)
std::map< std::string, RTT::Logger::LogLevel > logMap
basic_ostreams & endl(basic_ostreams &s)
size_t get_pool_size(void *mem_pool)
size_t get_overhead_size(void *mem_pool)
std::vector< typename MapT::mapped_type > values(const MapT &map)
size_t get_used_size(void *mem_pool)
int enforceMinNumberCPU(const int minNumberCPU)
virtual void setLayout(Layout *layout)=0
static Logger::LogFunction endlog()
static void configure(const std::string &initFileName)
void setLogLevel(LogLevel ll)