diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fc01ca..5f5ae3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ else() endif() project(Common - VERSION 0.0.0 + VERSION 1.5.0 DESCRIPTION "O2 Common library" LANGUAGES C CXX ) @@ -90,8 +90,6 @@ add_library(Common src/Thread.cxx src/Timer.cxx src/Configuration.cxx - src/DataBlock.cxx - src/DataBlockContainer.cxx src/MemPool.cxx) # Produce the final Version.h using template Version.h.in and substituting @@ -120,12 +118,6 @@ add_subdirectory(doc) #################################### enable_testing() -add_executable(testDataFormat test/testDataFormat.c) -target_link_libraries(testDataFormat Common) -set_source_files_properties(test/testDataFormat.c PROPERTIES LANGUAGE CXX) -add_test(NAME testDataFormat COMMAND testDataFormat) -set_tests_properties(testDataFormat PROPERTIES TIMEOUT 60) - add_executable(testSimpleLog test/testSimpleLog.cxx) target_link_libraries(testSimpleLog Common) @@ -136,7 +128,6 @@ set(TEST_SRCS test/TestSuffixNumber.cxx test/TestSuffixOption.cxx test/TestSystem.cxx - test/testMemPool.cxx test/testTimer.cxx ) diff --git a/include/Common/BasicThread.h b/include/Common/BasicThread.h index f8ed9bf..4e75971 100644 --- a/include/Common/BasicThread.h +++ b/include/Common/BasicThread.h @@ -23,49 +23,46 @@ namespace Common /// the function should stop its work. class BasicThread { - public: + public: + /// Start thread + /// \param stopFlag Pointer to flag indicating the function should stop + void start(std::function* stopFlag)> function) + { + join(); + mStopFlag = false; + mThread = std::thread(function, &mStopFlag); + } - /// Start thread - /// \param stopFlag Pointer to flag indicating the function should stop - void start(std::function* stopFlag)> function) - { - join(); - mStopFlag = false; - mThread = std::thread(function, &mStopFlag); - } + void stop() + { + mStopFlag = true; + } - void stop() - { - mStopFlag = true; + void join() + { + stop(); + if (mThread.joinable()) { + mThread.join(); } + } - void join() - { - stop(); - if (mThread.joinable()) { - mThread.join(); - } - } - - ~BasicThread() - { - try { - join(); - } - catch (const std::system_error& e) { - std::cout << "Failed to join thread: " << e.what() << '\n'; - } - catch (const std::exception& e) { - std::cout << "Unexpected exception while joining thread: " << e.what() << '\n'; - } + ~BasicThread() + { + try { + join(); + } catch (const std::system_error& e) { + std::cout << "Failed to join thread: " << e.what() << '\n'; + } catch (const std::exception& e) { + std::cout << "Unexpected exception while joining thread: " << e.what() << '\n'; } + } - private: - /// Thread object - std::thread mThread; + private: + /// Thread object + std::thread mThread; - /// Flag to stop the thread - std::atomic mStopFlag; + /// Flag to stop the thread + std::atomic mStopFlag; }; } // namespace Common diff --git a/include/Common/Configuration.h b/include/Common/Configuration.h index 7333ecb..82e57a3 100644 --- a/include/Common/Configuration.h +++ b/include/Common/Configuration.h @@ -12,185 +12,165 @@ class ConfigFilePrivate { - public: - ConfigFilePrivate(); - ~ConfigFilePrivate(); + public: + ConfigFilePrivate(); + ~ConfigFilePrivate(); - friend class ConfigFile; - friend class ConfigFileBrowser; - - protected: - boost::property_tree::ptree pt; + friend class ConfigFile; + friend class ConfigFileBrowser; + protected: + boost::property_tree::ptree pt; }; class ConfigFile { - public: - ConfigFile(); - - ~ConfigFile(); - - // explicitely disable automatically generated methods - // disable copy constructor - ConfigFile(const ConfigFile&) =delete; - // disable copy assignment operator - ConfigFile& operator=(const ConfigFile&) =delete; - - - /// Load the configuration from given path. - /// Existing ConfigFile data loaded previously is overwritten. - /// \param path Path to configuration data. - /// Example: file:/configDir/example.cfg - /// Accepted prefix: - /// file: for a file accessible from the filesystem - /// Accepted suffix, to define file format (TODO: separate doc for file formats): - /// .ini, .cfg see example.cfg - /// \exception Throws a exception on error. - void load(const std::string path); - - - /// Load the configuration directly from a given boost property_tree. - /// Existing ConfigFile data loaded previously is overwritten. - /// \param tree boost property_tree object to be used as configuration input. It is copied. - /// \exception Throws a exception on error. - void load(boost::property_tree::ptree const &tree); - - - /// Get the configuration value for given key path (by reference), failure causes exception. - /// \param key Key name (possibly hierarchical) - /// \param value Result value found (possible types: int, float, std::string), by reference (this variable is modified in case of success) - /// \returns Nothing - /// \exception Throws a exception on error. - template - void getValue(const std::string key, T &value) - { - try { - value = dPtr->pt.get(key); - } - catch (const boost::property_tree::ptree_error &e) { - throw std::string(e.what()); - } - } - - - /// Get the configuration value for given key path (by reference), failure does not cause exception. - /// \param key Key name (possibly hierarchical) - /// \param value Result value found (possible types: int, float, std::string), by reference (this variable is modified in case of success) - /// \returns 0 if value found, 1 if not found - /// \exception Does not throw exception if value not found - template - int getOptionalValue(const std::string key, T &value) - { - try { - value = dPtr->pt.get(key); - } - catch (...) { - return 1; - } - return 0; - } - - - /// Get the configuration value for given key path (by reference), failure does not cause exception, and provided default value is assigned instead. - /// \param key Key name (possibly hierarchical) - /// \param value Result value found (possible types: int, float, std::string), by reference (this variable is modified in case of success) - /// \param defaultValue Default value to be assigned in case of failure - /// \returns 0 if value found, 1 if not found - /// \exception Does not throw exception if value not found - template - int getOptionalValue(const std::string key, T &value, T defaultValue) - { - try { - value = dPtr->pt.get(key); - } - catch (...) { - value = defaultValue; - return 1; - } - return 0; + public: + ConfigFile(); + + ~ConfigFile(); + + // explicitely disable automatically generated methods + // disable copy constructor + ConfigFile(const ConfigFile&) = delete; + // disable copy assignment operator + ConfigFile& operator=(const ConfigFile&) = delete; + + /// Load the configuration from given path. + /// Existing ConfigFile data loaded previously is overwritten. + /// \param path Path to configuration data. + /// Example: file:/configDir/example.cfg + /// Accepted prefix: + /// file: for a file accessible from the filesystem + /// Accepted suffix, to define file format (TODO: separate doc for file formats): + /// .ini, .cfg see example.cfg + /// \exception Throws a exception on error. + void load(const std::string path); + + /// Load the configuration directly from a given boost property_tree. + /// Existing ConfigFile data loaded previously is overwritten. + /// \param tree boost property_tree object to be used as configuration input. It is copied. + /// \exception Throws a exception on error. + void load(boost::property_tree::ptree const& tree); + + /// Get the configuration value for given key path (by reference), failure causes exception. + /// \param key Key name (possibly hierarchical) + /// \param value Result value found (possible types: int, float, std::string), by reference (this variable is modified in case of success) + /// \returns Nothing + /// \exception Throws a exception on error. + template + void getValue(const std::string key, T& value) + { + try { + value = dPtr->pt.get(key); + } catch (const boost::property_tree::ptree_error& e) { + throw std::string(e.what()); } - - - /// Get the configuration value for given key path (by result) - /// \param key Key name (possibly hierarchical) - /// \returns Result value found (possible types: int, float, std::string) - /// \exception Throws a exception on error. - template - T getValue(const std::string key) - { - T res; - getValue(key, res); - return res; + } + + /// Get the configuration value for given key path (by reference), failure does not cause exception. + /// \param key Key name (possibly hierarchical) + /// \param value Result value found (possible types: int, float, std::string), by reference (this variable is modified in case of success) + /// \returns 0 if value found, 1 if not found + /// \exception Does not throw exception if value not found + template + int getOptionalValue(const std::string key, T& value) + { + try { + value = dPtr->pt.get(key); + } catch (...) { + return 1; } - - - /// Print configuration tree - void print(); - - /// Get configuration tree - boost::property_tree::ptree& get() - { - return dPtr->pt; + return 0; + } + + /// Get the configuration value for given key path (by reference), failure does not cause exception, and provided default value is assigned instead. + /// \param key Key name (possibly hierarchical) + /// \param value Result value found (possible types: int, float, std::string), by reference (this variable is modified in case of success) + /// \param defaultValue Default value to be assigned in case of failure + /// \returns 0 if value found, 1 if not found + /// \exception Does not throw exception if value not found + template + int getOptionalValue(const std::string key, T& value, T defaultValue) + { + try { + value = dPtr->pt.get(key); + } catch (...) { + value = defaultValue; + return 1; } - - private: - ConfigFilePrivate *dPtr; + return 0; + } + + /// Get the configuration value for given key path (by result) + /// \param key Key name (possibly hierarchical) + /// \returns Result value found (possible types: int, float, std::string) + /// \exception Throws a exception on error. + template + T getValue(const std::string key) + { + T res; + getValue(key, res); + return res; + } + + /// Print configuration tree + void print(); + + /// Get configuration tree + boost::property_tree::ptree& get() + { + return dPtr->pt; + } + + private: + ConfigFilePrivate* dPtr; friend class ConfigFileBrowser; }; - - - - /// Helper class to iterate over 1st level sub-tree of config file with a for range-based loop. /// /// \example To print section names starting with "part" found in a .ini file: /// \example for (auto sectionName : ConfigFileBrowser (&myConfigFile,"part") { std::cout << "Found section : " << sectionName << std::endl;} -class ConfigFileBrowser { +class ConfigFileBrowser +{ - -public: + public: /// Constructor /// \param cfgPtr Pointer to a ConfigFile object /// \param filter Optional string to be matched with sub-tree name. Non-matching elements will be skipped. Only sub-tree names starting by this string will be returned. - ConfigFileBrowser(ConfigFile *cfgPtr, std::string filter="", std::string startingNode=""); + ConfigFileBrowser(ConfigFile* cfgPtr, std::string filter = "", std::string startingNode = ""); ~ConfigFileBrowser(); - + class Iterator; Iterator begin(); Iterator end(); - -private: - ConfigFile *p; + + private: + ConfigFile* p; std::string filter; std::string startingNode; - boost::property_tree::ptree *ptPtr; + boost::property_tree::ptree* ptPtr; }; - /// Internal class used to implement ConfigFileBrowser iterator -class ConfigFileBrowser::Iterator { +class ConfigFileBrowser::Iterator +{ - typedef boost::property_tree::ptree::iterator t_Iterator; + typedef boost::property_tree::ptree::iterator t_Iterator; - private: - ConfigFileBrowser *bPtr; - t_Iterator it; - t_Iterator itEnd; - void findNext(); + private: + ConfigFileBrowser* bPtr; + t_Iterator it; + t_Iterator itEnd; + void findNext(); - public: - Iterator(ConfigFileBrowser *_bPtr, Iterator::t_Iterator _it, Iterator::t_Iterator _itEnd); - const std::string & operator*(); - Iterator& operator++(); - bool operator!=(const Iterator& _it) const; + public: + Iterator(ConfigFileBrowser* _bPtr, Iterator::t_Iterator _it, Iterator::t_Iterator _itEnd); + const std::string& operator*(); + Iterator& operator++(); + bool operator!=(const Iterator& _it) const; }; - - - - #endif /* SRC_CONFIGURATION_H_ */ - diff --git a/include/Common/Daemon.h b/include/Common/Daemon.h index 4b22e9c..70caf8f 100644 --- a/include/Common/Daemon.h +++ b/include/Common/Daemon.h @@ -8,30 +8,29 @@ #include - // class to define parameters for daemon runtime behavior. // default values are defined. -class DaemonConfigParameters { -public: - int isInteractive=0; // flag set when process to be kept in foreground - int idleSleepTime=100000; // sleep time in microseconds when doLoop() idle - std::string userName; // user name under which should run the process. Not changed if empty. - int redirectOutput=0; // flag set to redirect stdout/stderr to /dev/null - std::string logFile; // log file (leave empty to keep stdout/stderr) - int logRotateMaxBytes = 0; // log file max size (0: unlimited) - int logRotateMaxFiles = 0; // log file max number of files kept (0:unlimited) - int logRotateNow = 0; // log file rotate now (0: append current, 1: create new) +class DaemonConfigParameters +{ + public: + int isInteractive = 0; // flag set when process to be kept in foreground + int idleSleepTime = 100000; // sleep time in microseconds when doLoop() idle + std::string userName; // user name under which should run the process. Not changed if empty. + int redirectOutput = 0; // flag set to redirect stdout/stderr to /dev/null + std::string logFile; // log file (leave empty to keep stdout/stderr) + int logRotateMaxBytes = 0; // log file max size (0: unlimited) + int logRotateMaxFiles = 0; // log file max number of files kept (0:unlimited) + int logRotateNow = 0; // log file rotate now (0: append current, 1: create new) }; - // a class to initialize and run a daemon process // - user doLoop() called iteratively // - exit when doLoop() returns Completed or Error status, // - exit when termination signal received: SIGINT (CTRL+C), SIGQUIT, SIGTERM // This class should be derived with a custom doLoop() periodic main loop. -class Daemon { - public: - +class Daemon +{ + public: // constructor // takes as input main(argc,argv) command line parameters, and custom configuration options. // accepted command line parameters: @@ -42,8 +41,8 @@ class Daemon { // There is a 1-to-1 match between key names and members of the DaemonConfigParameters class. // i.e. user name running the daemon can be set by passing a pointer to a custom DaemonConfigParameters object, // but it is overwritten by value of [daemon] userName key in configuration file, if defined. - Daemon(int argc=0, char * argv[]=nullptr, DaemonConfigParameters * =nullptr); - + Daemon(int argc = 0, char* argv[] = nullptr, DaemonConfigParameters* = nullptr); + // destructor virtual ~Daemon(); @@ -56,31 +55,28 @@ class Daemon { // doLoop() recalled immediatetly on Ok or with short delay on Idle (delay set in idleSleepTime parameter). // run() will return when doLoop() returns Error or Completed. Corresponding error codes are 1 and 0. // run() will also be interrupted (with success return code) on external exit requests. - enum LoopStatus {Ok, Idle, Error, Completed}; + enum LoopStatus { Ok, + Idle, + Error, + Completed }; // Function called periodically, until Completed/Error returned or external exit request. // If returns Idle, a sleep time is inserted between consecutive calls. // If returns Ok, called again immediately. - virtual LoopStatus doLoop(); + virtual LoopStatus doLoop(); - - protected: - - SimpleLog log; // object for output logging. - ConfigFile config; // input configuration file, if any. Loaded if path provided on command line. + protected: + SimpleLog log; // object for output logging. + ConfigFile config; // input configuration file, if any. Loaded if path provided on command line. // check daemon status (e.g. after constructor, before starting main loop by calling run(), to know if init success) bool isOk(); - - private: - - DaemonConfigParameters params; // configuration parameters - bool isInitialized; // init status. 1 when daemon ok, 0 when error (failed to initialize, etc) + private: + DaemonConfigParameters params; // configuration parameters + bool isInitialized; // init status. 1 when daemon ok, 0 when error (failed to initialize, etc) }; - - /* TODO configure process name, user name, log file (or system), diff --git a/include/Common/DataBlock.h b/include/Common/DataBlock.h deleted file mode 100644 index f45a0a3..0000000 --- a/include/Common/DataBlock.h +++ /dev/null @@ -1,59 +0,0 @@ -/// \file DataBlock.h -/// \brief C interface for a general data format. -/// -/// Data are organized in a succession of continuous HEADER + PAYLOAD in memory. -/// Each PAYLOAD is also a succession of headers and payloads, up to a certain point (i.e. when payload is not a concatenation of things). -/// -/// A base header is defined, and common to all data block types. -/// Each data block type may have a specialized header based on DataBlockHeaderBase. -/// It should be a concatenation of DataBlockHeaderBase and of additionnal fields. -/// -/// \author Sylvain Chapeland, CERN - -#ifndef DATAFORMAT_DATABLOCK -#define DATAFORMAT_DATABLOCK - -#include - -/// Definition of data block types and their associated header. -typedef enum { - H_BASE = 0xBB, ///< base header type - H_EOM = 0xFF, ///< End Of Message header -} DataBlockType; - -/// Definition of a unique identifier for blocks -typedef uint64_t DataBlockId; - -/// Data structure is based on standard data types with specified width. -/// headerPtr + headerSize = payloadPtr -/// headerPtr + headerSize + dataSize = nextHeaderPtr (if not toplevel block header) -typedef struct { - uint32_t blockType; ///< ID to identify structure type - uint32_t headerSize; ///< header size in bytes - uint32_t dataSize; ///< data size following this structure (until next header, if this is not a toplevel block header) - DataBlockId blockId; ///< id of the block (strictly monotonic increasing sequence) - uint32_t linkId; ///< id of link - uint16_t equipmentId; ///< id of equipment generating the data - uint64_t timeframeId; ///< id of timeframe - DataBlockId id; ///< obsolete - kept for compatibility only. Use blockId or timeframeId instead. -} DataBlockHeaderBase; - -const uint64_t undefinedBlockId = 0; ///< default value, when blockId undefined -const uint32_t undefinedLinkId = 0xFF; ///< default value, when linkId undefined -const uint16_t undefinedEquipmentId = 0xFF; ///< default value, when equipmentId undefined -const uint64_t undefinedTimeframeId = 0; ///< default value, when timeframeId undefined - -/// Add extra types below, e.g. -/// -/// typedef struct { -/// DataBlockHeaderBase header; ///< Base common data header -/// int numberOfSubTimeframes; ///< number of subtimeframes in payload -/// } DataBlockHeaderTimeframe; - -typedef struct -{ - DataBlockHeaderBase header; ///< Base common data header - char* data; ///< Pointer to data. May or may not immediately follow this variable. -} DataBlock; - -#endif /* DATAFORMAT_DATABLOCK */ diff --git a/include/Common/DataBlockContainer.h b/include/Common/DataBlockContainer.h deleted file mode 100644 index f2bf513..0000000 --- a/include/Common/DataBlockContainer.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef DATAFORMAT_DATABLOCKCONTAINER -#define DATAFORMAT_DATABLOCKCONTAINER - -#include -#include - -#include -#include -#include -#include - -// A container class for data blocks. -// In particular, allows to take care of the block release after use. - -class DataBlockContainer { - - public: - DataBlockContainer(DataBlock* v_data = NULL, uint64_t v_dataBufferSize = 0); - virtual ~DataBlockContainer(); - DataBlock* getData(); - uint64_t getDataBufferSize(); - - using ReleaseCallback = std::function; - // NB: may use std::bind to add extra arguments - - // this constructor allows to specify a callback which is invoked when container is destroyed - DataBlockContainer(ReleaseCallback callback, DataBlock* v_data = NULL, uint64_t v_dataBufferSize = 0); - - protected: - DataBlock *data; - uint64_t dataBufferSize = 0; // Usable memory size pointed by data. Unspecified if zero. - ReleaseCallback releaseCallback; -}; - - - - -class DataBlockContainerFromMemPool : public DataBlockContainer { - - public: - DataBlockContainerFromMemPool(std::shared_ptr pool, DataBlock *v_data=NULL); - ~DataBlockContainerFromMemPool(); - - private: - std::shared_ptr mp; -}; - - -/** - * DataBlockContainer that takes ownership of the payload and deletes it when needed. - */ -class SelfReleasingBlockContainer : public DataBlockContainer -{ - - public: - SelfReleasingBlockContainer() - { - data = new DataBlock(); - data->data = nullptr; - } - - ~SelfReleasingBlockContainer() - { - if (data->data != nullptr) { - delete[] data->data; - } - delete data; - } -}; - -#endif diff --git a/include/Common/DataSet.h b/include/Common/DataSet.h deleted file mode 100644 index c8488ff..0000000 --- a/include/Common/DataSet.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - - -/* - A container to store a vector of shared pointers to data block containers. - Can typically be used to pass a set of blocks to a function. -*/ - -using DataBlockContainerReference=std::shared_ptr; - -using DataSet=std::vector; -using DataSetReference=std::shared_ptr; - - -/* TBD */ -/* -class DataSetHelper { -}; -*/ diff --git a/include/Common/Exception.h b/include/Common/Exception.h index 74d67f9..d3450a8 100644 --- a/include/Common/Exception.h +++ b/include/Common/Exception.h @@ -10,8 +10,10 @@ #include #include -namespace AliceO2 { -namespace Common { +namespace AliceO2 +{ +namespace Common +{ namespace ErrorInfo { @@ -20,17 +22,17 @@ using Input = boost::error_info; using Suffix = boost::error_info; using FileName = boost::error_info; using FilesystemType = boost::error_info; -} +} // namespace ErrorInfo -struct Exception : virtual std::exception, virtual boost::exception -{ - /// The what() function is overridden to use the 'ErrorInfo::Message' when available - virtual const char* what() const noexcept override; +struct Exception : virtual std::exception, virtual boost::exception { + /// The what() function is overridden to use the 'ErrorInfo::Message' when available + virtual const char* what() const noexcept override; }; -struct ProgramOptionException : virtual Exception {}; +struct ProgramOptionException : virtual Exception { +}; -} -} +} // namespace Common +} // namespace AliceO2 #endif //COMMON_EXCEPTION_H diff --git a/include/Common/Exceptions.h b/include/Common/Exceptions.h index ab2922f..e1a70e7 100644 --- a/include/Common/Exceptions.h +++ b/include/Common/Exceptions.h @@ -11,8 +11,10 @@ #include #include "Exception.h" -namespace AliceO2 { -namespace Common { +namespace AliceO2 +{ +namespace Common +{ /// Definitions of error_info structures to store extra info the boost way. typedef boost::error_info errinfo_object_name; @@ -21,22 +23,23 @@ typedef boost::error_info errinfo_details; typedef boost::error_info errinfo_db_errno; typedef boost::error_info errinfo_db_message; -struct ExceptionBase : public Exception -{ +struct ExceptionBase : public Exception { }; -struct ObjectNotFoundError : virtual ExceptionBase -{ - const char *what() const noexcept override +struct ObjectNotFoundError : virtual ExceptionBase { + const char* what() const noexcept override { return "Object not found error"; } }; -struct FatalException : virtual ExceptionBase {}; +struct FatalException : virtual ExceptionBase { +}; -struct DatabaseException : virtual ExceptionBase {}; -struct FatalDatabaseException : virtual FatalException{}; +struct DatabaseException : virtual ExceptionBase { +}; +struct FatalDatabaseException : virtual FatalException { +}; // we could define further exceptions this way : // struct io_error: virtual exception_base { }; @@ -48,7 +51,7 @@ struct FatalDatabaseException : virtual FatalException{}; // TODO add instructions on how to display diagnostic -} -} +} // namespace Common +} // namespace AliceO2 #endif //COMMON_EXCEPTIONS_H diff --git a/include/Common/Fifo.h b/include/Common/Fifo.h index b7c3ffa..38d7722 100644 --- a/include/Common/Fifo.h +++ b/include/Common/Fifo.h @@ -11,91 +11,91 @@ #include #include -namespace AliceO2 { -namespace Common { +namespace AliceO2 +{ +namespace Common +{ /// \brief Class to implement a lock-free 1-to-1 FIFO (1 writer, 1 reader) /// Two threads can safely work concurrently on the two sides of the FIFO (one using push(), the other using pop()). /// External protection is needed for other types of concurrent access, functions are not re-entrant. (e.g. 2 threads calling push(), or 2 threads calling pop()) /// \author Sylvain Chapeland template -class Fifo { - public: - - /// Constructor - /// \param[in] size Size of the FIFO (number of elements it can hold). - Fifo(int size); - - /// Destructor - ~Fifo(); - - /// Push an element in FIFO. - /// \param[in] data Element to be added to FIFO. - /// \return 0 on success - int push(const T &data); // push an element in FIFO. Returns 0 on success. - - /// Retrieve first element of FIFO. - /// \param[in,out] data Element read from FIFO (by reference). - /// \return 0 on success - int pop(T &data); - - /// Retrieve first element from FIFO, without removing it from FIFO. - /// \param[in,out] data Element read from FIFO (by reference). - /// \return 0 on success - int front(T &data); - - /// Check if Fifo is full. - /// \return non-zero if FIFO full - int isFull(); - - /// Check if Fifo is empty. - /// \return non-zero if FIFO empty - int isEmpty(); - - /// Retrieve space available in FIFO - /// \return number of free slots in FIFO - int getNumberOfFreeSlots(); - - /// Retrieve space used in FIFO - /// \return number of pending items in FIFO - int getNumberOfUsedSlots(); - - /// clears FIFO content - void clear(); - - - /// reset FIFO statistics - void resetStats(); - - /// \return number of items written to FIFO - unsigned long long getNumberIn(); - /// \return number of items read from FIFO - unsigned long long getNumberOut(); - - private: - - int size; // size of FIFO (number of elements it can store) - std::atomic indexStart; // index of latest element poped - std::atomic indexEnd; // index of latest element pushed - std::vector data; // array storing FIFO elements (circular buffer - has one more item than max number of elements stored) - - unsigned long long nIn; // statistics - number of elements pushed to FIFO - unsigned long long nOut; // statistics - number of elements retrieved from FIFO +class Fifo +{ + public: + /// Constructor + /// \param[in] size Size of the FIFO (number of elements it can hold). + Fifo(int size); + + /// Destructor + ~Fifo(); + + /// Push an element in FIFO. + /// \param[in] data Element to be added to FIFO. + /// \return 0 on success + int push(const T& data); // push an element in FIFO. Returns 0 on success. + + /// Retrieve first element of FIFO. + /// \param[in,out] data Element read from FIFO (by reference). + /// \return 0 on success + int pop(T& data); + + /// Retrieve first element from FIFO, without removing it from FIFO. + /// \param[in,out] data Element read from FIFO (by reference). + /// \return 0 on success + int front(T& data); + + /// Check if Fifo is full. + /// \return non-zero if FIFO full + int isFull(); + + /// Check if Fifo is empty. + /// \return non-zero if FIFO empty + int isEmpty(); + + /// Retrieve space available in FIFO + /// \return number of free slots in FIFO + int getNumberOfFreeSlots(); + + /// Retrieve space used in FIFO + /// \return number of pending items in FIFO + int getNumberOfUsedSlots(); + + /// clears FIFO content + void clear(); + + /// reset FIFO statistics + void resetStats(); + + /// \return number of items written to FIFO + unsigned long long getNumberIn(); + /// \return number of items read from FIFO + unsigned long long getNumberOut(); + + private: + int size; // size of FIFO (number of elements it can store) + std::atomic indexStart; // index of latest element poped + std::atomic indexEnd; // index of latest element pushed + std::vector data; // array storing FIFO elements (circular buffer - has one more item than max number of elements stored) + + unsigned long long nIn; // statistics - number of elements pushed to FIFO + unsigned long long nOut; // statistics - number of elements retrieved from FIFO }; - - template -Fifo::Fifo(int s) { - indexStart=0; - indexEnd=0; - size=s; - data.resize(size+1); // keep one extra slot to mark separation between begin/end of circular buffer +Fifo::Fifo(int s) +{ + indexStart = 0; + indexEnd = 0; + size = s; + data.resize(size + 1); // keep one extra slot to mark separation between begin/end of circular buffer resetStats(); } template -Fifo::~Fifo() { +Fifo::~Fifo() +{ /* if (nIn!=nOut) { printf("FIFO stats - warning: %llu in, %llu out\n",nIn,nOut); @@ -106,30 +106,32 @@ Fifo::~Fifo() { } template -int Fifo::push(const T &item) { +int Fifo::push(const T& item) +{ int indexEndNew; -// printf("push : start=%d end=%d\n",(int)indexStart,(int)indexEnd); + // printf("push : start=%d end=%d\n",(int)indexStart,(int)indexEnd); - indexEndNew=this->indexEnd+1; - if (indexEndNew>this->size) { - indexEndNew=0; + indexEndNew = this->indexEnd + 1; + if (indexEndNew > this->size) { + indexEndNew = 0; } // append new item only if some space left - if (indexEndNew==this->indexStart) { + if (indexEndNew == this->indexStart) { return -1; } - - //printf("push \ %d = %p\n",indexEndNew,item); - data[indexEndNew]=item; - this->indexEnd=indexEndNew; + + //printf("push \ %d = %p\n",indexEndNew,item); + data[indexEndNew] = item; + this->indexEnd = indexEndNew; nIn++; return 0; } template -int Fifo::pop(T &item) { +int Fifo::pop(T& item) +{ //printf("pop : start=%d end=%d\n",(int)indexStart,(int)indexEnd); @@ -139,21 +141,22 @@ int Fifo::pop(T &item) { } int new_indexStart; - new_indexStart=this->indexStart+1; - if (new_indexStart>this->size) { - new_indexStart=0; + new_indexStart = this->indexStart + 1; + if (new_indexStart > this->size) { + new_indexStart = 0; } - this->indexStart=new_indexStart; - - item=data[this->indexStart]; - data[this->indexStart]=0; // reset value, in case it is a shared_ptr - //printf("pop \ %d = %p\n",new_indexStart,item); + this->indexStart = new_indexStart; + + item = data[this->indexStart]; + data[this->indexStart] = 0; // reset value, in case it is a shared_ptr + //printf("pop \ %d = %p\n",new_indexStart,item); nOut++; return 0; } template -int Fifo::front(T &item) { +int Fifo::front(T& item) +{ //printf("front : start=%d end=%d\n",(int)indexStart,(int)indexEnd); @@ -162,62 +165,72 @@ int Fifo::front(T &item) { return -1; } - item=data[(this->indexStart+1)%(this->size+1)]; + item = data[(this->indexStart + 1) % (this->size + 1)]; return 0; } - - template -int Fifo::isEmpty() { - if (indexEnd==indexStart) { +int Fifo::isEmpty() +{ + if (indexEnd == indexStart) { return 1; } return 0; } template -int Fifo::isFull() { - if ( ((indexEnd+1)==indexStart) || ((indexEnd+1>size)&&(indexStart==0)) ) { +int Fifo::isFull() +{ + if (((indexEnd + 1) == indexStart) || ((indexEnd + 1 > size) && (indexStart == 0))) { return 1; } return 0; } template -int Fifo::getNumberOfFreeSlots() { - int i1=indexEnd; - int i2=indexStart; - if (i1>=i2) { - return size-i1+i2; +int Fifo::getNumberOfFreeSlots() +{ + int i1 = indexEnd; + int i2 = indexStart; + if (i1 >= i2) { + return size - i1 + i2; } - return i2-i1-1; + return i2 - i1 - 1; } template -int Fifo::getNumberOfUsedSlots() { - return size-getNumberOfFreeSlots(); +int Fifo::getNumberOfUsedSlots() +{ + return size - getNumberOfFreeSlots(); } template -void Fifo::clear() { +void Fifo::clear() +{ data.clear(); - indexStart=0; - indexEnd=0; + indexStart = 0; + indexEnd = 0; return; } -template void Fifo::resetStats() { - nIn=0; - nOut=0; +template +void Fifo::resetStats() +{ + nIn = 0; + nOut = 0; } -template unsigned long long Fifo::getNumberIn() {return nIn;} - -template unsigned long long Fifo::getNumberOut() {return nOut;} - - +template +unsigned long long Fifo::getNumberIn() +{ + return nIn; +} +template +unsigned long long Fifo::getNumberOut() +{ + return nOut; +} } // namespace Common } // namespace AliceO2 diff --git a/include/Common/GuardFunction.h b/include/Common/GuardFunction.h index e9148d1..2e1d155 100644 --- a/include/Common/GuardFunction.h +++ b/include/Common/GuardFunction.h @@ -16,20 +16,20 @@ namespace Common /// Class that executes a function on scope exit class GuardFunction { - public: - /// \param function Function to execute on scope exit. Must not throw. - GuardFunction(std::function function) - : mFunction(function) - { - } - - ~GuardFunction() - { - mFunction(); - } - - private: - std::function mFunction; + public: + /// \param function Function to execute on scope exit. Must not throw. + GuardFunction(std::function function) + : mFunction(function) + { + } + + ~GuardFunction() + { + mFunction(); + } + + private: + std::function mFunction; }; } // namespace Common diff --git a/include/Common/LineBuffer.h b/include/Common/LineBuffer.h index e540f45..599198d 100644 --- a/include/Common/LineBuffer.h +++ b/include/Common/LineBuffer.h @@ -7,8 +7,9 @@ #include #include -class LineBuffer { -public: +class LineBuffer +{ + public: /// Constructor LineBuffer(); @@ -20,15 +21,15 @@ class LineBuffer { /// \param[in] timeout timeout in milliseconds, -1 for blocking call /// \return 0 on success, -1 if EOF int appendFromFileDescriptor(int fd, int timeout); - + // Retrieve next complete line from buffer, immediate returns. /// \param[out] nextLine Next complete line from buffer. /// \return 0 on success, -1 if no complete line yet - int getNextLine(std::string &nextLine); - + int getNextLine(std::string& nextLine); + //void appendString(const char *s); - - private: + + private: std::queue completeLines; std::string pendingLine; }; diff --git a/include/Common/MemPool.h b/include/Common/MemPool.h index 8c74f25..1b65ee7 100644 --- a/include/Common/MemPool.h +++ b/include/Common/MemPool.h @@ -1,36 +1,33 @@ #ifndef DATAFORMAT_MEMPOOL #define DATAFORMAT_MEMPOOL - #include - // class to create a pool of memory pages from standard allocated memory. // lock-free mechanism for fast concurrent page request/release -class MemPool { - public: - MemPool(int numberOfPages, int pageSize=1024*1024, int align=1024); +class MemPool +{ + public: + MemPool(int numberOfPages, int pageSize = 1024 * 1024, int align = 1024); ~MemPool(); - - void *getPage(); // thread-safe ... can be called in parallel - void releasePage(void *page); // thread-safe ... can be called in parallel + + void* getPage(); // thread-safe ... can be called in parallel + void releasePage(void* page); // thread-safe ... can be called in parallel int getPageSize(); - - private: - - void deletePages(); // release memory allocated for data members of this object + + private: + void deletePages(); // release memory allocated for data members of this object int numberOfPages; int pageSize; - void **pageTable; // table with list of allocated pages - std::atomic_flag *pageIsUsed; // table to flag pages in use + void** pageTable; // table with list of allocated pages + std::atomic_flag* pageIsUsed; // table to flag pages in use - std::atomic lastPageIndexGet; // cache for last page index reserved, will start search of free page from there + std::atomic lastPageIndexGet; // cache for last page index reserved, will start search of free page from there std::atomic lastPageIndexRelease; // cache for last page index reserved, will start search of free page from there }; - #endif diff --git a/include/Common/Program.h b/include/Common/Program.h index 7afc804..113a436 100644 --- a/include/Common/Program.h +++ b/include/Common/Program.h @@ -22,57 +22,56 @@ namespace Common /// - SIGINT signals class Program { - public: - Program(); - virtual ~Program(); + public: + Program(); + virtual ~Program(); - /// Execute the program using the given arguments - int execute(int argc, char** argv); + /// Execute the program using the given arguments + int execute(int argc, char** argv); - /// Returns true if the SIGINT signal been given (e.g. with Ctrl-c in a terminal) - static bool isSigInt(std::memory_order memoryOrder = std::memory_order_relaxed) - { - return sFlagSigInt.load(memoryOrder); - } + /// Returns true if the SIGINT signal been given (e.g. with Ctrl-c in a terminal) + static bool isSigInt(std::memory_order memoryOrder = std::memory_order_relaxed) + { + return sFlagSigInt.load(memoryOrder); + } - /// Get the atomic interrupt flag - static const std::atomic& getInterruptFlag() - { - return sFlagSigInt; - } + /// Get the atomic interrupt flag + static const std::atomic& getInterruptFlag() + { + return sFlagSigInt; + } - protected: - /// Should output be verbose - bool isVerbose() const - { - return mVerbose; - } + protected: + /// Should output be verbose + bool isVerbose() const + { + return mVerbose; + } - struct Description - { - std::string name; ///< Name of the utility - std::string description; ///< Short description - std::string usage; ///< Usage example - }; + struct Description { + std::string name; ///< Name of the utility + std::string description; ///< Short description + std::string usage; ///< Usage example + }; - private: - /// Get the description of the program - /// \return A tuple containing name, description and example usage of the program - virtual Description getDescription() = 0; + private: + /// Get the description of the program + /// \return A tuple containing name, description and example usage of the program + virtual Description getDescription() = 0; - /// Add the program's options - virtual void addOptions(boost::program_options::options_description& optionsDescription) = 0; + /// Add the program's options + virtual void addOptions(boost::program_options::options_description& optionsDescription) = 0; - /// The main function of the program - virtual void run(const boost::program_options::variables_map& variablesMap) = 0; + /// The main function of the program + virtual void run(const boost::program_options::variables_map& variablesMap) = 0; - static void sigIntHandler(int); + static void sigIntHandler(int); - void printHelp(const boost::program_options::options_description& optionsDescription); + void printHelp(const boost::program_options::options_description& optionsDescription); - static std::atomic sFlagSigInt; + static std::atomic sFlagSigInt; - bool mVerbose; + bool mVerbose; }; } // namespace Common diff --git a/include/Common/SuffixNumber.h b/include/Common/SuffixNumber.h index 3d630f6..31bb0ab 100644 --- a/include/Common/SuffixNumber.h +++ b/include/Common/SuffixNumber.h @@ -12,11 +12,11 @@ #include #include "Common/Exceptions.h" -namespace AliceO2 +namespace AliceO2 { -namespace Common +namespace Common { -namespace _SuffixNumberTable +namespace _SuffixNumberTable { const std::vector>& get(); } // namespace _SuffixNumberTable @@ -28,81 +28,81 @@ const std::vector>& get(); template class SuffixNumber { - public: - using NumberType = Number; - - SuffixNumber() : mNumber(0) - { - } - - SuffixNumber(Number number) : mNumber(number) - { - } - - SuffixNumber(std::string input) : mNumber(parse(input)) - { - } - - Number getNumber() const - { - return mNumber; + public: + using NumberType = Number; + + SuffixNumber() : mNumber(0) + { + } + + SuffixNumber(Number number) : mNumber(number) + { + } + + SuffixNumber(std::string input) : mNumber(parse(input)) + { + } + + Number getNumber() const + { + return mNumber; + } + + void setNumber(std::string input) + { + mNumber = parse(input); + } + + void setNumber(Number number) + { + mNumber = number; + } + + private: + Number parse(std::string input) const + { + // Find the non-numeric suffix + auto pos = input.find_first_not_of("-.0123456789"); + + // Convert numeric part + auto numberString = input.substr(0, pos); + Number number; + if (!boost::conversion::try_lexical_convert(numberString, number)) { + BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not convert number") + << ErrorInfo::Input(numberString)); } - void setNumber(std::string input) - { - mNumber = parse(input); + if (pos == std::string::npos) { + // There's no unit + return number; } - void setNumber(Number number) - { - mNumber = number; - } - - private: - Number parse(std::string input) const - { - // Find the non-numeric suffix - auto pos = input.find_first_not_of("-.0123456789"); - - // Convert numeric part - auto numberString = input.substr(0, pos); - Number number; - if (!boost::conversion::try_lexical_convert(numberString, number)) { - BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not convert number") - << ErrorInfo::Input(numberString)); - } - - if (pos == std::string::npos) { - // There's no unit - return number; - } - - // Find unit and multiply number with it - auto unitString = input.substr(pos); - for (const auto& unit : _SuffixNumberTable::get()) { - if (unitString == unit.first) { - // We found the right unit, multiply it with the number - Number a = number; - Number b = unit.second; - Number multiplied = a * b; - if (std::is_integral::value) { - // Check for overflow for integers - if ((a != 0) && ((multiplied / a) != b)) { - BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Number too large for representation") - << ErrorInfo::Input(input)); - } + // Find unit and multiply number with it + auto unitString = input.substr(pos); + for (const auto& unit : _SuffixNumberTable::get()) { + if (unitString == unit.first) { + // We found the right unit, multiply it with the number + Number a = number; + Number b = unit.second; + Number multiplied = a * b; + if (std::is_integral::value) { + // Check for overflow for integers + if ((a != 0) && ((multiplied / a) != b)) { + BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Number too large for representation") + << ErrorInfo::Input(input)); } - return multiplied; } + return multiplied; } - BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Unrecognized unit") << ErrorInfo::Suffix(unitString)); } + BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Unrecognized unit") << ErrorInfo::Suffix(unitString)); + } - Number mNumber; + Number mNumber; }; template -std::istream& operator>>(std::istream &stream, SuffixNumber& suffixNumber) +std::istream& operator>>(std::istream& stream, SuffixNumber& suffixNumber) { std::string string; stream >> string; diff --git a/include/Common/SuffixOption.h b/include/Common/SuffixOption.h index f1a481c..92fbf1c 100644 --- a/include/Common/SuffixOption.h +++ b/include/Common/SuffixOption.h @@ -10,7 +10,7 @@ #include #include "Common/SuffixNumber.h" -namespace AliceO2 +namespace AliceO2 { namespace Common { @@ -22,117 +22,116 @@ namespace Common template class SuffixOption final : public boost::program_options::value_semantic { - public: - using ThisType = SuffixOption; - using SuffixNumberType = SuffixNumber; - - SuffixOption(SuffixNumberType* storeTo = nullptr) : mStoreToSuffixNumber(storeTo) - { - } - - SuffixOption(Number* storeTo = nullptr) : mStoreToNumber(storeTo) - { - } - - ThisType* required() - { - mRequired = true; - return this; - } - - ThisType* default_value(std::string defaultValue) - { - mHasDefault = true; - mName = std::string("(=" + defaultValue + ")"); - mDefaultValue.setNumber(defaultValue); - return this; - } - - ThisType* default_value(Number defaultValue) - { - mHasDefault = true; - mName = std::string("(=" + std::to_string(defaultValue) + ")"); - mDefaultValue.setNumber(defaultValue); - return this; - } - - - virtual ~SuffixOption() - { - } - - virtual std::string name() const override - { - return mName; - } - - virtual unsigned min_tokens() const override - { - return 1; - } - - virtual unsigned max_tokens() const override - { - return 16; - } - - virtual bool adjacent_tokens_only() const //override // <-- for some reason it does not work on mac - { - return true; - } - - virtual bool is_composing() const override - { + public: + using ThisType = SuffixOption; + using SuffixNumberType = SuffixNumber; + + SuffixOption(SuffixNumberType* storeTo = nullptr) : mStoreToSuffixNumber(storeTo) + { + } + + SuffixOption(Number* storeTo = nullptr) : mStoreToNumber(storeTo) + { + } + + ThisType* required() + { + mRequired = true; + return this; + } + + ThisType* default_value(std::string defaultValue) + { + mHasDefault = true; + mName = std::string("(=" + defaultValue + ")"); + mDefaultValue.setNumber(defaultValue); + return this; + } + + ThisType* default_value(Number defaultValue) + { + mHasDefault = true; + mName = std::string("(=" + std::to_string(defaultValue) + ")"); + mDefaultValue.setNumber(defaultValue); + return this; + } + + virtual ~SuffixOption() + { + } + + virtual std::string name() const override + { + return mName; + } + + virtual unsigned min_tokens() const override + { + return 1; + } + + virtual unsigned max_tokens() const override + { + return 16; + } + + virtual bool adjacent_tokens_only() const //override // <-- for some reason it does not work on mac + { + return true; + } + + virtual bool is_composing() const override + { + return false; + } + + virtual bool is_required() const override + { + return mRequired; + } + + virtual void parse(boost::any& valueStore, const std::vector& newTokens, bool) const override + { + valueStore = SuffixNumberType(newTokens.at(0)); + } + + virtual bool apply_default(boost::any& value) const override + { + if (!mHasDefault) { return false; } + value = mDefaultValue; + return true; + } - virtual bool is_required() const override - { - return mRequired; + virtual void notify(const boost::any& value) const override + { + if (mStoreToSuffixNumber) { + *mStoreToSuffixNumber = boost::any_cast(value); } - virtual void parse(boost::any& valueStore, const std::vector& newTokens, bool) const override - { - valueStore = SuffixNumberType(newTokens.at(0)); + if (mStoreToNumber) { + *mStoreToNumber = boost::any_cast(value).getNumber(); } + } - virtual bool apply_default(boost::any& value) const override - { - if (!mHasDefault) { - return false; - } - value = mDefaultValue; - return true; - } - - virtual void notify(const boost::any& value) const override - { - if (mStoreToSuffixNumber) { - *mStoreToSuffixNumber = boost::any_cast(value); - } - - if (mStoreToNumber) { - *mStoreToNumber = boost::any_cast(value).getNumber(); - } - } + static ThisType* make(SuffixNumberType* number) + { + return new ThisType(number); + } - static ThisType* make(SuffixNumberType* number) - { - return new ThisType(number); - } - - static ThisType* make(Number* number) - { - return new ThisType(number); - } + static ThisType* make(Number* number) + { + return new ThisType(number); + } - private: - Number* mStoreToNumber = nullptr; - SuffixNumberType* mStoreToSuffixNumber = nullptr; - bool mRequired = false; - bool mHasDefault = false; - SuffixNumberType mDefaultValue; - std::string mName; + private: + Number* mStoreToNumber = nullptr; + SuffixNumberType* mStoreToSuffixNumber = nullptr; + bool mRequired = false; + bool mHasDefault = false; + SuffixNumberType mDefaultValue; + std::string mName; }; } // namespace Common diff --git a/include/Common/System.h b/include/Common/System.h index c508e18..167383c 100644 --- a/include/Common/System.h +++ b/include/Common/System.h @@ -18,7 +18,7 @@ namespace System { /// Sets the given function as the SIGINT handler -void setSigIntHandler(void(*function)(int)); +void setSigIntHandler(void (*function)(int)); /// Checks if there's a SIGINT handler installed (not sure if it actually works correctly) bool isSigIntHandlerSet(); diff --git a/include/Common/Thread.h b/include/Common/Thread.h index 5ab8300..67543d4 100644 --- a/include/Common/Thread.h +++ b/include/Common/Thread.h @@ -6,60 +6,64 @@ #ifndef COMMON_THREAD_H #define COMMON_THREAD_H - #include #include #include #include -namespace AliceO2 { -namespace Common { +namespace AliceO2 +{ +namespace Common +{ /// \brief Class to implement controllable looping threads /// User just needs to overload the "doLoop()" method or to provide a callback function to the base class constructor /// \author Sylvain Chapeland -class Thread { - public: - enum CallbackResult {Ok,Idle,Done,Error}; - - /// Constructor - /// \param[in] vLoopCallback Pointer to user-defined function called periodically. (optional) - /// \param[in] vLoopArg Pointer to argument passed to user-defined function, if any. - /// \param[in] vThreadName Name to be used to identify this thread (for debug printouts) - /// \param[in] loopSleepTime Idle sleep time (in microseconds), when loop callback function/method returns idle. This is the maximum time between 2 calls. - Thread(Thread::CallbackResult (*vLoopCallback)(void *) = NULL , void *vLoopArg = NULL, std::string vThreadName = "", int loopSleepTime=1000); +class Thread +{ + public: + enum CallbackResult { Ok, + Idle, + Done, + Error }; + + /// Constructor + /// \param[in] vLoopCallback Pointer to user-defined function called periodically. (optional) + /// \param[in] vLoopArg Pointer to argument passed to user-defined function, if any. + /// \param[in] vThreadName Name to be used to identify this thread (for debug printouts) + /// \param[in] loopSleepTime Idle sleep time (in microseconds), when loop callback function/method returns idle. This is the maximum time between 2 calls. + Thread(Thread::CallbackResult (*vLoopCallback)(void*) = NULL, void* vLoopArg = NULL, std::string vThreadName = "", int loopSleepTime = 1000); + + /// Destructor + ~Thread(); + + /// start thread loop + void start(); + /// request thread termination + void stop(); + /// wait thread termination (blocking call) + void join(); + + /// get thread name + /// \returns name of the thread, as defined at construct time. + std::string getName(); + + private: + std::atomic shutdown; // flag set to 1 to request thread termination + std::atomic running; // flag set to 1 when thread running + std::thread* theThread; - /// Destructor - ~Thread(); + std::string name; // name of the thread, used in debug printouts + int loopSleepTime; // sleep time between 2 loop calls - /// start thread loop - void start(); - /// request thread termination - void stop(); - /// wait thread termination (blocking call) - void join(); + CallbackResult (*loopCallback)(void*); // callback provided at create time + void* loopArg; // arg to be passed to callback function - /// get thread name - /// \returns name of the thread, as defined at construct time. - std::string getName(); - - - private: - std::atomic shutdown; // flag set to 1 to request thread termination - std::atomic running; // flag set to 1 when thread running - std::thread *theThread; + CallbackResult doLoop(); // function called at each thread iteration. Returns a result code. + static void threadMain(Thread* e); // this is the (internal) thread entry point - std::string name; // name of the thread, used in debug printouts - int loopSleepTime; // sleep time between 2 loop calls - - CallbackResult (*loopCallback)(void *); // callback provided at create time - void *loopArg; // arg to be passed to callback function - - CallbackResult doLoop(); // function called at each thread iteration. Returns a result code. - static void threadMain(Thread *e); // this is the (internal) thread entry point - - private: - std::chrono::time_point t0; // time of reset + private: + std::chrono::time_point t0; // time of reset }; } // namespace Common diff --git a/include/Common/Timer.h b/include/Common/Timer.h index 7e272f8..098ebcc 100644 --- a/include/Common/Timer.h +++ b/include/Common/Timer.h @@ -7,48 +7,48 @@ #ifndef COMMON_TIMER_H #define COMMON_TIMER_H - #include - -namespace AliceO2 { -namespace Common { +namespace AliceO2 +{ +namespace Common +{ /// \brief Class to implement a high resolution timer function. /// All times in microseconds. /// Functionality: reset counter, set timeout value, get counter value, check timeout, fixed interval timeout. /// \author Sylvain Chapeland -class Timer { - public: - - /// Constructor - /// Timer is reset. - Timer(); - /// Destructor - ~Timer(); - - /// Reset timer. Accepts an optionnal timeout value. - /// param timeout (In) Timeout value, in microseconds since reset. (optional) - void reset(int timeout=0); - - /// Reset timer by adding timeout value to starting time value. - /// Usefull when called in loops, prevents loosing time elapsed after previous timeout. - /// (e.g.: to implement timeout every 1 second without drift in time) - void increment(); - - /// Check if time elapsed since timer reset (or last increment set) is bigger than timeout value set. - /// \return Returns 1 if timeout, 0 otherwise. - int isTimeout(); - - /// \return Returns time elapsed since reset, in seconds. - double getTime(); - - /// \return Returns the time until next timeout, in seconds. This may be a negative value if timeout occured already. - double getRemainingTime(); - - private: - std::chrono::time_point t0; // time of reset - double tmax; // duration between reset and timeout condition, in seconds +class Timer +{ + public: + /// Constructor + /// Timer is reset. + Timer(); + /// Destructor + ~Timer(); + + /// Reset timer. Accepts an optionnal timeout value. + /// param timeout (In) Timeout value, in microseconds since reset. (optional) + void reset(int timeout = 0); + + /// Reset timer by adding timeout value to starting time value. + /// Usefull when called in loops, prevents loosing time elapsed after previous timeout. + /// (e.g.: to implement timeout every 1 second without drift in time) + void increment(); + + /// Check if time elapsed since timer reset (or last increment set) is bigger than timeout value set. + /// \return Returns 1 if timeout, 0 otherwise. + int isTimeout(); + + /// \return Returns time elapsed since reset, in seconds. + double getTime(); + + /// \return Returns the time until next timeout, in seconds. This may be a negative value if timeout occured already. + double getRemainingTime(); + + private: + std::chrono::time_point t0; // time of reset + double tmax; // duration between reset and timeout condition, in seconds }; } // namespace Common diff --git a/include/Common/Version.h.in b/include/Common/Version.h.in index bdc6c93..5a1a264 100644 --- a/include/Common/Version.h.in +++ b/include/Common/Version.h.in @@ -10,8 +10,10 @@ #include #include -namespace AliceO2 { -namespace Common { +namespace AliceO2 +{ +namespace Common +{ /// The current major version. #define COMMON_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ @@ -28,29 +30,34 @@ namespace Common { #define COMMON_VERSION_GT(MAJOR, MINOR, PATCH) \ ((COMMON_VERSION_MAJOR > MAJOR) || \ (COMMON_VERSION_MAJOR == \ - MAJOR&&(COMMON_VERSION_MINOR > MINOR || (COMMON_VERSION_MINOR == MINOR&& COMMON_VERSION_PATCH > PATCH)))) + MAJOR && \ + (COMMON_VERSION_MINOR > MINOR || (COMMON_VERSION_MINOR == MINOR && COMMON_VERSION_PATCH > PATCH)))) /// True if the current version is equal or newer to the given. #define COMMON_VERSION_GE(MAJOR, MINOR, PATCH) \ ((COMMON_VERSION_MAJOR > MAJOR) || \ (COMMON_VERSION_MAJOR == \ - MAJOR&&(COMMON_VERSION_MINOR > MINOR || (COMMON_VERSION_MINOR == MINOR&& COMMON_VERSION_PATCH >= PATCH)))) + MAJOR && \ + (COMMON_VERSION_MINOR > MINOR || (COMMON_VERSION_MINOR == MINOR && COMMON_VERSION_PATCH >= PATCH)))) /// True if the current version is older than the given one. #define COMMON_VERSION_LT(MAJOR, MINOR, PATCH) \ ((COMMON_VERSION_MAJOR < MAJOR) || \ (COMMON_VERSION_MAJOR == \ - MAJOR&&(COMMON_VERSION_MINOR < MINOR || (COMMON_VERSION_MINOR == MINOR&& COMMON_VERSION_PATCH < PATCH)))) + MAJOR && \ + (COMMON_VERSION_MINOR < MINOR || (COMMON_VERSION_MINOR == MINOR && COMMON_VERSION_PATCH < PATCH)))) /// True if the current version is older or equal to the given. #define COMMON_VERSION_LE(MAJOR, MINOR, PATCH) \ ((COMMON_VERSION_MAJOR < MAJOR) || \ (COMMON_VERSION_MAJOR == \ - MAJOR&&(COMMON_VERSION_MINOR < MINOR || (COMMON_VERSION_MINOR == MINOR&& COMMON_VERSION_PATCH <= PATCH)))) + MAJOR && \ + (COMMON_VERSION_MINOR < MINOR || (COMMON_VERSION_MINOR == MINOR && COMMON_VERSION_PATCH <= PATCH)))) /// Information about the current Common version. -class Version { -public: +class Version +{ + public: /// @return the current major version of Common. static int getMajor() { @@ -91,7 +98,7 @@ public: return version.str(); } }; -} -} +} // namespace Common +} // namespace AliceO2 #endif // COMMON_VERSION_H diff --git a/include/Common/signalUtilities.h b/include/Common/signalUtilities.h index 0797ba5..f4ed19f 100644 --- a/include/Common/signalUtilities.h +++ b/include/Common/signalUtilities.h @@ -19,7 +19,7 @@ /// \author Barthelemy von Haller void printStack() { - void *array[10]; + void* array[10]; int size; size = backtrace(array, 10); backtrace_symbols_fd(array, size, 2); @@ -56,8 +56,7 @@ bool keepRunning = true; /// Indicates whether we should continue the execution void handler_interruption(int sig) { if (keepRunning) { - std::cout << "Catched signal " << sig << - "\n Exit the process at the end of this cycle. \n Press again Ctrl-C to force immediate exit" << std::endl; + std::cout << "Catched signal " << sig << "\n Exit the process at the end of this cycle. \n Press again Ctrl-C to force immediate exit" << std::endl; keepRunning = false; } else { std::cout << "Second interruption : immediate exit" << std::endl; diff --git a/src/Configuration.cxx b/src/Configuration.cxx index 94974e9..befb8f6 100644 --- a/src/Configuration.cxx +++ b/src/Configuration.cxx @@ -18,7 +18,6 @@ ConfigFilePrivate::~ConfigFilePrivate() { } - ConfigFile::ConfigFile() { dPtr = new ConfigFilePrivate(); @@ -32,20 +31,24 @@ ConfigFile::~ConfigFile() } #define PREFIX_FILE "file:" -#define SUFFIX_FILE_INI {".ini", ".cfg"} +#define SUFFIX_FILE_INI \ + { \ + ".ini", ".cfg" \ + } void ConfigFile::load(const std::string path) { - if (path.length() == 0) { throw std::string("Invalid argument"); } + if (path.length() == 0) { + throw std::string("Invalid argument"); + } // // open location according to prefix // - // filesystem file if (boost::algorithm::starts_with(path.c_str(), PREFIX_FILE)) { - const char *filename; + const char* filename; filename = &path[strlen(PREFIX_FILE)]; // TODO: filter out comments in file with boost filtering_stream @@ -60,8 +63,7 @@ void ConfigFile::load(const std::string path) if (boost::algorithm::ends_with(filename, suffix)) { try { boost::property_tree::ini_parser::read_ini(filename, dPtr->pt); - } - catch (boost::property_tree::ini_parser::ini_parser_error perr) { + } catch (boost::property_tree::ini_parser::ini_parser_error perr) { std::stringstream ss; if (perr.line()) { ss << perr.message() << " in " << perr.filename() << " line " << perr.line(); @@ -79,105 +81,105 @@ void ConfigFile::load(const std::string path) } } -void ConfigFile::load(boost::property_tree::ptree const &tree) { +void ConfigFile::load(boost::property_tree::ptree const& tree) +{ // copy input property_tree object - dPtr->pt=tree; + dPtr->pt = tree; } - -void getValueSpecialization(void) { +void getValueSpecialization(void) +{ ConfigFile f; const std::string s(""); int vInt; - f.getValue(s,vInt); - vInt=f.getValue(s); + f.getValue(s, vInt); + vInt = f.getValue(s); float vFloat; - f.getValue("",vFloat); - vFloat=f.getValue(s); + f.getValue("", vFloat); + vFloat = f.getValue(s); std::string vString; - f.getValue("",vString); - vString=f.getValue(s); + f.getValue("", vString); + vString = f.getValue(s); } - //template void ConfigFile::getValue(std::string, float&); - - - - // http://stackoverflow.com/questions/4586768/how-to-iterate-a-boost-property-tree -string indent(int level) { - string s; - for (int i=0; ifirst << "\": "; - printTree(pos->second, level + 1); - ++pos; + cerr << indent(level + 1) << "\"" << pos->first << "\": "; + printTree(pos->second, level + 1); + ++pos; if (pos != pt.end()) { - cerr << ","; + cerr << ","; } cerr << endl; - } - cerr << indent(level) << " }"; + } + cerr << indent(level) << " }"; } - return; + return; } -void ConfigFile::print() { - printTree(dPtr->pt,0); +void ConfigFile::print() +{ + printTree(dPtr->pt, 0); } - - - - - - -ConfigFileBrowser::Iterator::Iterator(ConfigFileBrowser *_bPtr, ConfigFileBrowser::Iterator::t_Iterator _it, ConfigFileBrowser::Iterator::t_Iterator _itEnd) -:bPtr(_bPtr),it(_it),itEnd(_itEnd) { +ConfigFileBrowser::Iterator::Iterator(ConfigFileBrowser* _bPtr, ConfigFileBrowser::Iterator::t_Iterator _it, ConfigFileBrowser::Iterator::t_Iterator _itEnd) + : bPtr(_bPtr), it(_it), itEnd(_itEnd) +{ // skip initial elements if filter defined findNext(); } // iterate until matching sub-tree name found, in case a filter is defined -void ConfigFileBrowser::Iterator::findNext() { - int l=bPtr->filter.length(); +void ConfigFileBrowser::Iterator::findNext() +{ + int l = bPtr->filter.length(); if (l) { - while (it!=itEnd) { + while (it != itEnd) { std::string s((*it).first); - if (!s.compare(0,l,bPtr->filter)) { - break; + if (!s.compare(0, l, bPtr->filter)) { + break; } ++it; } } } -const std::string & ConfigFileBrowser::Iterator::operator*() { +const std::string& ConfigFileBrowser::Iterator::operator*() +{ return (*it).first; } -ConfigFileBrowser::Iterator& ConfigFileBrowser::Iterator::operator++() { - ++it; - findNext(); - return *this; +ConfigFileBrowser::Iterator& ConfigFileBrowser::Iterator::operator++() +{ + ++it; + findNext(); + return *this; } -bool ConfigFileBrowser::Iterator::operator!=(const ConfigFileBrowser::Iterator& _it) const { - return it!=_it.it; +bool ConfigFileBrowser::Iterator::operator!=(const ConfigFileBrowser::Iterator& _it) const +{ + return it != _it.it; } - /* +/* To use separator character other than default '.', each of the get versions has another form, which takes an additional parameter in front of path. This parameter of type char/wchar_t specifies the separating character. This is a lifesaving device for those who may have dots in their keys: pt.get('/', "p.a.t.h/t.o/v.a.l.u.e"); @@ -185,25 +187,28 @@ pt.get('/', "p.a.t.h/t.o/v.a.l.u.e", 0, NULL); pt.get_optional('/', "p.a.t.h/t.o/v.a.l.u.e"); */ -ConfigFileBrowser::ConfigFileBrowser(ConfigFile *_p, std::string _filter, std::string _startingNode) { - p=_p; - filter=_filter; - startingNode=_startingNode; - if (startingNode.length()>0) { - ptPtr=&p->dPtr->pt.get_child(startingNode); +ConfigFileBrowser::ConfigFileBrowser(ConfigFile* _p, std::string _filter, std::string _startingNode) +{ + p = _p; + filter = _filter; + startingNode = _startingNode; + if (startingNode.length() > 0) { + ptPtr = &p->dPtr->pt.get_child(startingNode); } else { - ptPtr=&p->dPtr->pt; + ptPtr = &p->dPtr->pt; } } -ConfigFileBrowser::~ConfigFileBrowser() { +ConfigFileBrowser::~ConfigFileBrowser() +{ } -ConfigFileBrowser::Iterator ConfigFileBrowser::begin() { - return {this,ptPtr->begin(),ptPtr->end()}; +ConfigFileBrowser::Iterator ConfigFileBrowser::begin() +{ + return { this, ptPtr->begin(), ptPtr->end() }; } -ConfigFileBrowser::Iterator ConfigFileBrowser::end() { - return Iterator(this,ptPtr->end(),ptPtr->end()); +ConfigFileBrowser::Iterator ConfigFileBrowser::end() +{ + return Iterator(this, ptPtr->end(), ptPtr->end()); } - diff --git a/src/DataBlock.cxx b/src/DataBlock.cxx deleted file mode 100644 index f186bf1..0000000 --- a/src/DataBlock.cxx +++ /dev/null @@ -1,15 +0,0 @@ -/// -/// @file DataBlock.cxx -/// @author Barthelemy von Haller -/// - -#include "Common/DataBlock.h" - -namespace AliceO2 { -namespace ProjectTemplate { -namespace DataFormat { - - -} // namespace DataFormat -} // namespace ProjectTemplate -} // namespace AliceO2 diff --git a/src/DataBlockContainer.cxx b/src/DataBlockContainer.cxx deleted file mode 100644 index 192cbbf..0000000 --- a/src/DataBlockContainer.cxx +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include - -// base DataBlockContainer class - -DataBlockContainer::DataBlockContainer(DataBlock* v_data, uint64_t v_dataBufferSize) : data(v_data), dataBufferSize(v_dataBufferSize), releaseCallback(nullptr) -{ -} - -DataBlockContainer::DataBlockContainer(ReleaseCallback v_callback, DataBlock* v_data, uint64_t v_dataBufferSize) - : data(v_data), dataBufferSize(v_dataBufferSize), releaseCallback(v_callback) -{ -} - -DataBlockContainer::~DataBlockContainer() { - if (releaseCallback != nullptr) { - releaseCallback(); - } -} - -DataBlock * DataBlockContainer::getData() { - return data; -} - -uint64_t DataBlockContainer::getDataBufferSize() -{ - return dataBufferSize; -} - -// container for data pages coming fom MemPool class - -DataBlockContainerFromMemPool::DataBlockContainerFromMemPool(std::shared_ptr pool, DataBlock *v_data) { - mp=pool; - if (mp==nullptr) { - throw std::string("NULL argument"); - } - data=v_data; - if (data==NULL) { - data=(DataBlock*)mp->getPage(); - if (data==NULL) { - throw std::string("No page available"); - } - } -} - - -DataBlockContainerFromMemPool::~DataBlockContainerFromMemPool() { - if (mp!=nullptr) { - if (data!=nullptr) { - mp->releasePage(data); - } - } -} diff --git a/src/Exception.cxx b/src/Exception.cxx index 878b499..e58f77c 100644 --- a/src/Exception.cxx +++ b/src/Exception.cxx @@ -7,7 +7,7 @@ #include #include -namespace AliceO2 +namespace AliceO2 { namespace Common { @@ -20,8 +20,7 @@ const char* Exception::what() const noexcept } else { return "AliceO2::Common::Exception"; } - } - catch (const std::exception& e) { + } catch (const std::exception& e) { return "AliceO2::Common::Exception"; } } diff --git a/src/Iommu.cxx b/src/Iommu.cxx index 9d4476d..457160c 100644 --- a/src/Iommu.cxx +++ b/src/Iommu.cxx @@ -19,6 +19,6 @@ bool isEnabled() return boost::filesystem::exists("/sys/kernel/iommu_groups/0"); } -} // namespace Util +} // namespace Iommu } // namespace Common } // namespace AliceO2 diff --git a/src/LineBuffer.cxx b/src/LineBuffer.cxx index 29236d9..c372354 100644 --- a/src/LineBuffer.cxx +++ b/src/LineBuffer.cxx @@ -11,67 +11,70 @@ #include #include -LineBuffer::LineBuffer() { +LineBuffer::LineBuffer() +{ } -LineBuffer::~LineBuffer() { +LineBuffer::~LineBuffer() +{ } -int LineBuffer::appendFromFileDescriptor(int fd, int timeout) { +int LineBuffer::appendFromFileDescriptor(int fd, int timeout) +{ fd_set rfds; int ret; struct timeval tv; - - const int bufferSize=1000; // size of chunks read from file descriptor + + const int bufferSize = 1000; // size of chunks read from file descriptor char buffer[bufferSize]; - - for(;;) { + + for (;;) { // wait new data until timeout, if any FD_ZERO(&rfds); - FD_SET(fd,&rfds); - if (timeout>=0) { - tv.tv_sec=timeout/1000; - tv.tv_usec=(timeout-tv.tv_sec*1000)*1000; - ret=select(fd+1,&rfds,NULL,NULL,&tv); + FD_SET(fd, &rfds); + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; + ret = select(fd + 1, &rfds, NULL, NULL, &tv); } else { - ret=select(fd+1,&rfds,NULL,NULL,NULL); - } - if (ret==-1) { + ret = select(fd + 1, &rfds, NULL, NULL, NULL); + } + if (ret == -1) { break; } - - if (FD_ISSET(fd,&rfds)) { + + if (FD_ISSET(fd, &rfds)) { // read data (keep a spare char in buffer for zero-termination) - ret=read(fd,buffer,bufferSize-1); + ret = read(fd, buffer, bufferSize - 1); // process new chars - if (ret>0) { + if (ret > 0) { // add zero-termination - buffer[ret]=0; - + buffer[ret] = 0; + // parse and extract lines from buffer - char *ptr=buffer; - while (*ptr!=0) { - char *endline; + char* ptr = buffer; + while (*ptr != 0) { + char* endline; // where's the next end of line? - endline=strchr(ptr,'\n'); - if (endline==NULL) { + endline = strchr(ptr, '\n'); + if (endline == NULL) { // not found, keep pending chars for next round pendingLine.append(ptr); break; } // add separator at end of line - *endline=0; + *endline = 0; // append to previous pending buffer pendingLine.append(ptr); // append to vector of completed lines completeLines.push(pendingLine); pendingLine.clear(); // iterate with next part - ptr=++endline; + ptr = ++endline; } - } else if (ret==0) { + } else if (ret == 0) { return -1; } else { break; @@ -79,24 +82,23 @@ int LineBuffer::appendFromFileDescriptor(int fd, int timeout) { } else { break; } - + // continue to iterate reading from fd, but don't wait if nothing left - timeout=0; + timeout = 0; } return 0; } - -int LineBuffer::getNextLine(std::string &nextLine) { +int LineBuffer::getNextLine(std::string& nextLine) +{ if (completeLines.empty()) { // no complete line yet return -1; } // return next line from buffer (by reference) - nextLine=completeLines.front(); + nextLine = completeLines.front(); completeLines.pop(); return 0; } - //void LineBuffer::appendString(const char *s) {} diff --git a/src/MemPool.cxx b/src/MemPool.cxx index abc6768..268f046 100644 --- a/src/MemPool.cxx +++ b/src/MemPool.cxx @@ -4,13 +4,14 @@ #include #include -void MemPool::deletePages() { - int nPagesUsed=0; - - if (pageTable!=NULL) { - for (int i=0;i=0) { + if (errorIx >= 0) { deletePages(); std::stringstream err; err << boost::format("Failed to allocate page %d / %d sized %d") % errorIx % numberOfPages % pageSize; throw err.str(); } - lastPageIndexGet=-1; - lastPageIndexRelease=-1; + lastPageIndexGet = -1; + lastPageIndexRelease = -1; } -MemPool::~MemPool() { +MemPool::~MemPool() +{ deletePages(); } - -void *MemPool::getPage() { - int j=0; - for (int i=0;i %d\n",j); return pageTable[newIx]; } @@ -87,14 +90,14 @@ void *MemPool::getPage() { // todo: use HASH for fast ptr->index access - -void MemPool::releasePage(void *pagePtr) { - int j=0; - for (int i=0;i %d\n",j); return; } @@ -102,7 +105,7 @@ void MemPool::releasePage(void *pagePtr) { } } -int MemPool::getPageSize () { +int MemPool::getPageSize() +{ return pageSize; } - diff --git a/src/Program.cxx b/src/Program.cxx index c373be1..b9974c9 100644 --- a/src/Program.cxx +++ b/src/Program.cxx @@ -22,21 +22,21 @@ namespace Common { namespace { - const std::string HELP_SWITCH = "help"; - const std::string VERBOSE_SWITCH = "verbose"; - const std::string VERSION_SWITCH = "version"; - - po::options_description createOptionsDescription() - { - // Get size of the terminal, the amount of columns is used for formatting the options - struct winsize w; - ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); - - po::options_description optionsDescription("Allowed options", w.ws_col, w.ws_col/2); - optionsDescription.add_options()("help", "Produce help message"); - return optionsDescription; - } +const std::string HELP_SWITCH = "help"; +const std::string VERBOSE_SWITCH = "verbose"; +const std::string VERSION_SWITCH = "version"; + +po::options_description createOptionsDescription() +{ + // Get size of the terminal, the amount of columns is used for formatting the options + struct winsize w; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); + + po::options_description optionsDescription("Allowed options", w.ws_col, w.ws_col / 2); + optionsDescription.add_options()("help", "Produce help message"); + return optionsDescription; } +} // namespace std::atomic Program::sFlagSigInt(false); @@ -46,7 +46,7 @@ void Program::sigIntHandler(int) } Program::Program() - : mVerbose(false) + : mVerbose(false) { } @@ -54,16 +54,16 @@ Program::~Program() { } -void Program::printHelp (const po::options_description& optionsDescription) +void Program::printHelp(const po::options_description& optionsDescription) { const auto& description = getDescription(); cout << "#### " << description.name << "\n" - << description.description << '\n' - << '\n' - << optionsDescription - << '\n' - << "Example:\n" - << " " << description.usage << '\n'; + << description.description << '\n' + << '\n' + << optionsDescription + << '\n' + << "Example:\n" + << " " << description.usage << '\n'; } int Program::execute(int argc, char** argv) @@ -73,9 +73,7 @@ int Program::execute(int argc, char** argv) auto optionsDescription = createOptionsDescription(); // We add a verbose switch - optionsDescription.add_options() - (VERBOSE_SWITCH.c_str(), "Verbose output") - (VERSION_SWITCH.c_str(), "Display RORC library version"); + optionsDescription.add_options()(VERBOSE_SWITCH.c_str(), "Verbose output")(VERSION_SWITCH.c_str(), "Display RORC library version"); // Subclass will add own options addOptions(optionsDescription); @@ -90,15 +88,15 @@ int Program::execute(int argc, char** argv) return 0; } po::notify(variablesMap); - } - catch (const po::unknown_option& e) { + } catch (const po::unknown_option& e) { BOOST_THROW_EXCEPTION(ProgramOptionException() - << ErrorInfo::Message("Unknown option '" + e.get_option_name() + "'")); + << ErrorInfo::Message("Unknown option '" + e.get_option_name() + "'")); } if (variablesMap.count(VERSION_SWITCH)) { - cout << "Common lib " << Version::getString() << '\n' << "Revision " << Version::getRevision() - << '\n'; + cout << "Common lib " << Version::getString() << '\n' + << "Revision " << Version::getRevision() + << '\n'; return 0; } @@ -106,22 +104,21 @@ int Program::execute(int argc, char** argv) // Start the actual program run(variablesMap); - } - catch (const ProgramOptionException& e) { + } catch (const ProgramOptionException& e) { auto message = boost::get_error_info(e); std::cout << "Program options invalid: " << *message << "\n\n"; printHelp(optionsDescription); - } - catch (const po::error& e) { + } catch (const po::error& e) { std::cout << "Program options error: " << e.what() << "\n\n"; printHelp(optionsDescription); - } - catch (const std::exception& e) { + } catch (const std::exception& e) { #if (BOOST_VERSION >= 105400) - std::cout << "Error: " << e.what() << '\n' << boost::diagnostic_information(e, isVerbose()) << '\n'; + std::cout << "Error: " << e.what() << '\n' + << boost::diagnostic_information(e, isVerbose()) << '\n'; #else #pragma message "BOOST_VERSION < 105400" - std::cout << "Error: " << e.what() << '\n' << boost::diagnostic_information(e) << '\n'; + std::cout << "Error: " << e.what() << '\n' + << boost::diagnostic_information(e) << '\n'; #endif } diff --git a/src/SuffixNumber.cxx b/src/SuffixNumber.cxx index f186881..ace2523 100644 --- a/src/SuffixNumber.cxx +++ b/src/SuffixNumber.cxx @@ -6,32 +6,32 @@ #include "Common/SuffixNumber.h" #include -namespace AliceO2 +namespace AliceO2 { -namespace Common +namespace Common { -namespace _SuffixNumberTable +namespace _SuffixNumberTable { const std::vector>& get() { - static const std::vector> units { - {"k", 1000}, - {"M", 1000000}, - {"G", 1000000000}, - {"T", 1000000000000}, - {"P", 1000000000000000}, - {"E", 1000000000000000000}, -// {"Z", 1000000000000000000000}, // Too large -// {"Y", 1000000000000000000000000}, // Too large - {"Ki", 1024}, - {"Mi", 1048576}, - {"Gi", 1073741824}, - {"Ti", 1099511627776}, - {"Pi", 1125899906842624}, - {"Ei", 1152921504606846976}, -// {"Zi", 1180591620717411303424}, // Too large -// {"Yi", 1208925819614629174706176}, // Too large + static const std::vector> units{ + { "k", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + { "T", 1000000000000 }, + { "P", 1000000000000000 }, + { "E", 1000000000000000000 }, + // {"Z", 1000000000000000000000}, // Too large + // {"Y", 1000000000000000000000000}, // Too large + { "Ki", 1024 }, + { "Mi", 1048576 }, + { "Gi", 1073741824 }, + { "Ti", 1099511627776 }, + { "Pi", 1125899906842624 }, + { "Ei", 1152921504606846976 }, + // {"Zi", 1180591620717411303424}, // Too large + // {"Yi", 1208925819614629174706176}, // Too large }; return units; } diff --git a/src/System.cxx b/src/System.cxx index d478496..6bd7115 100644 --- a/src/System.cxx +++ b/src/System.cxx @@ -23,7 +23,7 @@ namespace System namespace b = boost; namespace bfs = boost::filesystem; -void setSigIntHandler(void(*function)(int)) +void setSigIntHandler(void (*function)(int)) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); @@ -62,15 +62,15 @@ void touchFile(const std::string& path) std::string executeCommand(const std::string& command) { - std::unique_ptr input(popen(command.c_str(), "r"), [](FILE* f){pclose(f);}); + std::unique_ptr input(popen(command.c_str(), "r"), [](FILE* f) { pclose(f); }); - if(!input.get()){ + if (!input.get()) { BOOST_THROW_EXCEPTION(std::runtime_error("Call to popen failed")); } std::vector buffer(128); std::ostringstream oss; - while(fgets(buffer.data(), buffer.size(), input.get()) != NULL){ + while (fgets(buffer.data(), buffer.size(), input.get()) != NULL) { oss << buffer.data(); } @@ -79,7 +79,7 @@ std::string executeCommand(const std::string& command) std::string getFileSystemType(const std::string& path) { - std::string type {""}; + std::string type{ "" }; std::string result = executeCommand(b::str(b::format("df %s") % path)); // We need the second line of the output (first line is a header) @@ -98,10 +98,10 @@ std::string getFileSystemType(const std::string& path) } std::pair isFileSystemTypeAnyOf(const std::string& path, - const std::set& types) + const std::set& types) { auto type = getFileSystemType(path); - return {types.count(type), type}; + return { types.count(type), type }; } /// Throws if the file system type of the given file/directory is not one of the given valid types @@ -123,9 +123,9 @@ void assertFileSystemType(const std::string& path, const std::set& oss << ")"; BOOST_THROW_EXCEPTION(Exception() - << ErrorInfo::Message(oss.str()) - << ErrorInfo::FileName(path) - << ErrorInfo::FilesystemType(type)); + << ErrorInfo::Message(oss.str()) + << ErrorInfo::FileName(path) + << ErrorInfo::FilesystemType(type)); } } diff --git a/src/Thread.cxx b/src/Thread.cxx index 2abd393..34c811b 100644 --- a/src/Thread.cxx +++ b/src/Thread.cxx @@ -3,85 +3,93 @@ #include using namespace AliceO2::Common; -Thread::Thread(Thread::CallbackResult (*vLoopCallback)(void *), void *vLoopArg, std::string vThreadName, int vLoopSleepTime) { - shutdown=0; - running=0; - theThread=NULL; - name=vThreadName; - loopCallback=vLoopCallback; - loopArg=vLoopArg; - loopSleepTime=vLoopSleepTime; +Thread::Thread(Thread::CallbackResult (*vLoopCallback)(void*), void* vLoopArg, std::string vThreadName, int vLoopSleepTime) +{ + shutdown = 0; + running = 0; + theThread = NULL; + name = vThreadName; + loopCallback = vLoopCallback; + loopArg = vLoopArg; + loopSleepTime = vLoopSleepTime; } -Thread::~Thread() { - if (theThread!=NULL) { +Thread::~Thread() +{ + if (theThread != NULL) { stop(); join(); } } -void Thread::start() { - if (theThread==NULL) { - shutdown=0; - running=0; - theThread= new std::thread(threadMain,this); +void Thread::start() +{ + if (theThread == NULL) { + shutdown = 0; + running = 0; + theThread = new std::thread(threadMain, this); } - return; + return; } -void Thread::stop() { - if (theThread!=NULL) { - shutdown=1; +void Thread::stop() +{ + if (theThread != NULL) { + shutdown = 1; } } -void Thread::join() { - if (theThread!=NULL) { - shutdown=1; +void Thread::join() +{ + if (theThread != NULL) { + shutdown = 1; theThread->join(); delete theThread; - theThread=NULL; + theThread = NULL; } - return; + return; } -void Thread::threadMain(Thread *e) { - e->running=1; - int maxIterOnShutdown=100; - int nIterOnShutdown=0; - - for(;;) { +void Thread::threadMain(Thread* e) +{ + e->running = 1; + int maxIterOnShutdown = 100; + int nIterOnShutdown = 0; + + for (;;) { if (e->shutdown) { - if (nIterOnShutdown>=maxIterOnShutdown) break; + if (nIterOnShutdown >= maxIterOnShutdown) + break; nIterOnShutdown++; } - int r=e->doLoop(); - if (r==Thread::CallbackResult::Ok) { - } else if (r==Thread::CallbackResult::Idle) { - if (e->shutdown) break; // exit immediately on shutdown - if (e->loopSleepTime>0) { + int r = e->doLoop(); + if (r == Thread::CallbackResult::Ok) { + } else if (r == Thread::CallbackResult::Idle) { + if (e->shutdown) + break; // exit immediately on shutdown + if (e->loopSleepTime > 0) { usleep(e->loopSleepTime); } - } else if (r==Thread::CallbackResult::Error) { + } else if (r == Thread::CallbackResult::Error) { // account this error... maybe do something if repetitive - if (e->shutdown) break; // exit immediately on shutdown + if (e->shutdown) + break; // exit immediately on shutdown } else { break; } } - e->running=0; + e->running = 0; } - -Thread::CallbackResult Thread::doLoop() { - if (loopCallback!=NULL) { +Thread::CallbackResult Thread::doLoop() +{ + if (loopCallback != NULL) { return loopCallback(loopArg); } return Thread::CallbackResult::Idle; } - -std::string Thread::getName() { +std::string Thread::getName() +{ return name; } - diff --git a/src/Timer.cxx b/src/Timer.cxx index 1d95f6d..92ba90c 100644 --- a/src/Timer.cxx +++ b/src/Timer.cxx @@ -5,43 +5,51 @@ #include "Common/Timer.h" +namespace AliceO2 +{ +namespace Common +{ -namespace AliceO2 { -namespace Common { - -Timer::Timer() { +Timer::Timer() +{ reset(0); } -Timer::~Timer(){ +Timer::~Timer() +{ } -void Timer::reset(int timeout) { - t0 = std::chrono::high_resolution_clock::now(); - tmax=timeout/1000000.0; +void Timer::reset(int timeout) +{ + t0 = std::chrono::high_resolution_clock::now(); + tmax = timeout / 1000000.0; } -void Timer::increment() { - t0+=std::chrono::microseconds((int)(tmax*1000000.0)); +void Timer::increment() +{ + t0 += std::chrono::microseconds((int)(tmax * 1000000.0)); } -int Timer::isTimeout() { - std::chrono::duration tdiff= std::chrono::high_resolution_clock::now() - t0; - if (tdiff.count()>=tmax) { - return 1; - } - return 0; +int Timer::isTimeout() +{ + std::chrono::duration tdiff = std::chrono::high_resolution_clock::now() - t0; + if (tdiff.count() >= tmax) { + return 1; + } + return 0; } -double Timer::getTime() { - std::chrono::duration tdiff= std::chrono::high_resolution_clock::now() - t0; - return tdiff.count(); -} +double Timer::getTime() +{ + std::chrono::duration tdiff = std::chrono::high_resolution_clock::now() - t0; + return tdiff.count(); +} -double Timer::getRemainingTime() { - std::chrono::duration tdiff= std::chrono::high_resolution_clock::now() - t0; - return tmax-tdiff.count(); -} +double Timer::getRemainingTime() +{ + std::chrono::duration tdiff = std::chrono::high_resolution_clock::now() - t0; + return tmax - tdiff.count(); +} } // namespace Common } // namespace AliceO2 diff --git a/test/TestSuffixNumber.cxx b/test/TestSuffixNumber.cxx index ab746f7..dbfb487 100644 --- a/test/TestSuffixNumber.cxx +++ b/test/TestSuffixNumber.cxx @@ -35,4 +35,3 @@ BOOST_AUTO_TEST_CASE(TestFloatingPoint) sn.setNumber("-123"); BOOST_CHECK_EQUAL(sn.getNumber(), -123); } - diff --git a/test/TestSuffixOption.cxx b/test/TestSuffixOption.cxx index 4d8cef2..36d2f94 100644 --- a/test/TestSuffixOption.cxx +++ b/test/TestSuffixOption.cxx @@ -20,13 +20,17 @@ BOOST_AUTO_TEST_CASE(TestSuffixOption) options.add_options()("numC", SuffixOption::make(&numberC), ""); // Mock arguments - std::vector args = { "/test", "--numA=1Mi", "--numB=123", "--numC=-1k", }; + std::vector args = { + "/test", + "--numA=1Mi", + "--numB=123", + "--numC=-1k", + }; po::variables_map map; po::store(po::parse_command_line(args.size(), args.data(), options), map); po::notify(map); - BOOST_CHECK(numberA == 1*1024*1024); + BOOST_CHECK(numberA == 1 * 1024 * 1024); BOOST_CHECK(numberB.getNumber() == 123); BOOST_CHECK(numberC == -1000.0); } - diff --git a/test/TestSystem.cxx b/test/TestSystem.cxx index a4a5d8d..9774bff 100644 --- a/test/TestSystem.cxx +++ b/test/TestSystem.cxx @@ -7,7 +7,6 @@ #define BOOST_TEST_DYN_LINK #include - /* void setSigIntHandler(void(*function)(int)); bool isSigIntHandlerSet(); @@ -23,12 +22,12 @@ using namespace AliceO2::Common; namespace { -std::atomic sSignalRaised { false }; +std::atomic sSignalRaised{ false }; void sigIntHandler(int) { sSignalRaised = true; } -} // Anyonymous namespace +} // namespace BOOST_AUTO_TEST_CASE(TestSetSigIntHandler) { @@ -73,7 +72,7 @@ BOOST_AUTO_TEST_CASE(TestGetFileSystemType) BOOST_AUTO_TEST_CASE(TestIsFileSystemTypeAnyOf) { #ifdef __linux__ - BOOST_CHECK(System::isFileSystemTypeAnyOf("/sys", {"sysfs", "ext4", "tmpfs"}).first == true); - BOOST_CHECK(System::isFileSystemTypeAnyOf("/sys", {"blahfs", "ext42"}).first == false); + BOOST_CHECK(System::isFileSystemTypeAnyOf("/sys", { "sysfs", "ext4", "tmpfs" }).first == true); + BOOST_CHECK(System::isFileSystemTypeAnyOf("/sys", { "blahfs", "ext42" }).first == false); #endif } diff --git a/test/testDaemon.cxx b/test/testDaemon.cxx index 8829890..c22b90c 100644 --- a/test/testDaemon.cxx +++ b/test/testDaemon.cxx @@ -4,7 +4,8 @@ #include -int main(int argc, char* argv[]) { - Daemon d(argc,argv); +int main(int argc, char* argv[]) +{ + Daemon d(argc, argv); return d.run(); } diff --git a/test/testDataFormat.c b/test/testDataFormat.c deleted file mode 100644 index 11b0b97..0000000 --- a/test/testDataFormat.c +++ /dev/null @@ -1,60 +0,0 @@ -/// \file testDataFormat.c -/// \brief Example of C usage of data format used in DataBlock.h. -/// -/// \author Sylvain Chapeland, CERN - -#include "Common/DataBlock.h" -#include -#include - -int main() { - - int i; - - // construct a data block with 1 level of sub-blocks - int payloadSize=100; - int numberOfSubBlocks=10; - int subBlocksSize=numberOfSubBlocks*(sizeof(DataBlockHeaderBase)+payloadSize); - - DataBlockHeaderBase *topHeader=(DataBlockHeaderBase *) malloc(sizeof(DataBlockHeaderBase)+subBlocksSize); - - topHeader->blockType=H_BASE; - topHeader->headerSize=sizeof(DataBlockHeaderBase); - topHeader->dataSize=subBlocksSize; - - for (i=0; iblockType=H_BASE; - subHeader->headerSize=sizeof(DataBlockHeaderBase); - subHeader->dataSize=payloadSize; - char *payload=&((char *)subHeader)[subHeader->headerSize]; - for (int j=0;jblockType,mainBlockPtr->headerSize,mainBlockPtr->dataSize); - - // compute end of data block - DataBlockHeaderBase *endPtr=(DataBlockHeaderBase *)&((char *)mainBlockPtr)[mainBlockPtr->headerSize+mainBlockPtr->dataSize]; - - // iterate on sub-blocks - DataBlockHeaderBase *subBlockPtr=(DataBlockHeaderBase *)&((char *)mainBlockPtr)[mainBlockPtr->headerSize]; - for (i=1; ; i++) { - if (subBlockPtr>=endPtr) break; - printf(" sub-block %d @ 0x%p\n",i,subBlockPtr); - printf(" type=%X headerSize=%d payloadSize=%d\n",(int)subBlockPtr->blockType,subBlockPtr->headerSize,subBlockPtr->dataSize); - char *data; - data=&((char *)subBlockPtr)[subBlockPtr->headerSize]; - for (int j=0;jdataSize;j++) { - printf("%d ",(int)data[j]); - } - printf("\n"); - subBlockPtr=(DataBlockHeaderBase *)&((char *)subBlockPtr)[sizeof(DataBlockHeaderBase)+payloadSize]; - } - - free(topHeader); - return 0; -} diff --git a/test/testFifo.cxx b/test/testFifo.cxx index a4660bf..a1589fc 100644 --- a/test/testFifo.cxx +++ b/test/testFifo.cxx @@ -6,45 +6,43 @@ #include #include - - BOOST_AUTO_TEST_CASE(fifo_test) { - int fifoSz=100; + int fifoSz = 100; AliceO2::Common::Fifo f(fifoSz); - int *v=new int[fifoSz]; - int j=-1; - int sum1=0; - int sum2=0; - - BOOST_CHECK_EQUAL(f.isEmpty(),1); - BOOST_CHECK_EQUAL(f.isFull(),0); - BOOST_CHECK_PREDICATE( std::not_equal_to(), (f.pop(j))(0) ); - for (int i=0;i(), (f.pop(j))(0)); + for (int i = 0; i < fifoSz; i++) { + v[i] = i; + sum1 += i; + BOOST_CHECK_EQUAL(f.isFull(), 0); + BOOST_CHECK_EQUAL(f.push(v[i]), 0); + BOOST_CHECK_EQUAL(f.isEmpty(), 0); } - BOOST_CHECK_EQUAL(f.isFull(),1); - BOOST_CHECK_PREDICATE( std::not_equal_to(), (f.push(-1))(0) ); - BOOST_CHECK_EQUAL(f.front(j),0); - BOOST_CHECK_EQUAL(j,0); + BOOST_CHECK_EQUAL(f.isFull(), 1); + BOOST_CHECK_PREDICATE(std::not_equal_to(), (f.push(-1))(0)); + BOOST_CHECK_EQUAL(f.front(j), 0); + BOOST_CHECK_EQUAL(j, 0); - for (int i=0;i(), (f.pop(j))(0) ); + BOOST_CHECK_EQUAL(f.isEmpty(), 1); + BOOST_CHECK_PREDICATE(std::not_equal_to(), (f.pop(j))(0)); - BOOST_CHECK_EQUAL(sum1,sum2); + BOOST_CHECK_EQUAL(sum1, sum2); delete[] v; - - printf("fifoSz=%d sum=%d\n",fifoSz,sum2); + + printf("fifoSz=%d sum=%d\n", fifoSz, sum2); } diff --git a/test/testMemPool.cxx b/test/testMemPool.cxx deleted file mode 100644 index a5f2c32..0000000 --- a/test/testMemPool.cxx +++ /dev/null @@ -1,97 +0,0 @@ -/// \file testDataFormat.c -/// \brief Example of C usage of data format used in DataBlock.h. -/// -/// \author Sylvain Chapeland, CERN - -#include "Common/MemPool.h" -#include "Common/DataBlockContainer.h" - -#include -#include -#include -#include -#include -#include - -int main() { - - int nErr=0; - MemPool *mp; - int nPages=100; - int pageSize=10*1024*1024; - std::vector pageUsed; - - - printf("Creating pool %d pages x %d bytes\n",nPages,pageSize); - mp=new MemPool(nPages,pageSize); - - printf("Get %d pages from pool\n",nPages); - nErr=0; - for (int i=0;igetPage(); - if (newPage!=NULL) { - pageUsed.push_back(newPage); - } else { - nErr++; - } - } - if (nErr) { - printf("%d errors\n",nErr); - } - - printf("Release %d pages\n",nPages/2); - nErr=0; - for (int i=0;ireleasePage(newPage); - } else { - nErr++; - } - } - if (nErr) { - printf("%d errors\n",nErr); - } - - printf("Get %d pages from pool\n",nPages); - nErr=0; - for (int i=0;igetPage(); - if (newPage!=NULL) { - pageUsed.push_back(newPage); - } else { - nErr++; - } - } - if (nErr) { - printf("%d errors\n",nErr); - } - - printf("Release all pages\n"); - nErr=0; - while (!pageUsed.empty()) { - void *newPage=pageUsed.back(); - pageUsed.pop_back(); - if (newPage!=NULL) { - mp->releasePage(newPage); - } else { - nErr++; - } - } - if (nErr) { - printf("%d errors\n",nErr); - } - - DataBlockContainer *bc=nullptr; - auto releaseCallback = [bc] (void) -> void { - printf("release callback for %p\n",bc); - return; - }; - bc=new DataBlockContainer(releaseCallback,nullptr); - delete bc; - - printf("Delete pool\n"); - delete mp; - return 0; -} diff --git a/test/testTimer.cxx b/test/testTimer.cxx index a3e9950..a9dc340 100644 --- a/test/testTimer.cxx +++ b/test/testTimer.cxx @@ -13,18 +13,20 @@ BOOST_AUTO_TEST_CASE(timer_test) { AliceO2::Common::Timer t; time_t t0; - t0=time(NULL); - - while (time(NULL)==t0) {} + t0 = time(NULL); + + while (time(NULL) == t0) { + } t.reset(); - while (time(NULL)<=t0+1) {} - - double elapsed=t.getTime(); - - printf("Timer elapsed=%.4lf\n",elapsed); - int success=0; - if (std::fabs(elapsed-1.0)<0.01) { - success=1; + while (time(NULL) <= t0 + 1) { + } + + double elapsed = t.getTime(); + + printf("Timer elapsed=%.4lf\n", elapsed); + int success = 0; + if (std::fabs(elapsed - 1.0) < 0.01) { + success = 1; } BOOST_CHECK_EQUAL(success, 1);