LCOV - code coverage report
Current view: top level - artdaq/DAQdata - Globals.hh (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 83.3 % 42 35
Test Date: 2025-09-04 00:45:34 Functions: 100.0 % 6 6

            Line data    Source code
       1              : #ifndef ARTDAQ_DAQDATA_GLOBALS_HH
       2              : #define ARTDAQ_DAQDATA_GLOBALS_HH
       3              : 
       4              : #ifndef TRACE_DEFINE  // as set in Globals.cc
       5              : #define TRACE_DECLARE
       6              : #endif
       7              : #include "artdaq-utilities/Plugins/MetricManager.hh"
       8              : #include "artdaq/DAQdata/PortManager.hh"
       9              : 
      10              : #define my_rank artdaq::Globals::my_rank_
      11              : #define app_name artdaq::Globals::app_name_
      12              : #define metricMan artdaq::Globals::metricMan_
      13              : #define portMan artdaq::Globals::portMan_
      14              : 
      15              : // https://stackoverflow.com/questions/21594140/c-how-to-ensure-different-random-number-generation-in-c-when-program-is-execut
      16              : #include <fcntl.h>
      17              : #include <unistd.h>
      18              : #include <cstdlib>
      19              : #include <memory>
      20              : #include <mutex>
      21              : #include <sstream>
      22              : #include <string>
      23              : 
      24              : /**
      25              :  * \brief The artdaq namespace
      26              :  */
      27              : namespace artdaq {
      28              : /**
      29              :  * \brief The artdaq::Globals class contains several variables which are useful across the entire artdaq system
      30              :  */
      31              : class Globals
      32              : {
      33              : public:
      34              :         static int my_rank_;                               ///< The rank of the current application
      35              :         static std::unique_ptr<MetricManager> metricMan_;  ///< A handle to MetricManager
      36              :         static std::unique_ptr<PortManager> portMan_;      ///< A handle to PortManager
      37              :         static std::string app_name_;                      ///< The name of the current application, to be used in logging and metrics
      38              :         static int partition_number_;                      ///< The partition number of the current application
      39              :         static int my_art_id_;                             ///< The ID number of the current art application. Used by art processes connected to the same rank
      40              : 
      41              :         static std::mutex mftrace_mutex_;       ///< Mutex to protect mftrace_module_ and mftrace_iteration_
      42              :         static std::string mftrace_module_;     ///< MessageFacility's module and iteration are thread-local, but we want to use them to represent global state in artdaq.
      43              :         static std::string mftrace_iteration_;  ///< MessageFacility's module and iteration are thread-local, but we want to use them to represent global state in artdaq.
      44              : 
      45              :         /**
      46              :          * \brief Seed the C random number generator with the current time (if that has not been done already) and generate a random value
      47              :          * \return A random number.
      48              :          */
      49            2 :         static uint32_t SeedAndRandom()
      50              :         {
      51              :                 static bool initialized_ = false;
      52            2 :                 if (!initialized_)
      53              :                 {
      54            2 :                         int fp = open("/dev/random", O_RDONLY);
      55            2 :                         if (fp == -1) abort();
      56              :                         unsigned seed;
      57            2 :                         unsigned pos = 0;
      58            4 :                         while (pos < sizeof(seed))
      59              :                         {
      60            2 :                                 int amt = read(fp, reinterpret_cast<char *>(&seed) + pos, sizeof(seed) - pos);  // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
      61            2 :                                 if (amt <= 0) abort();
      62            2 :                                 pos += amt;
      63              :                         }
      64            2 :                         srand(seed);
      65            2 :                         close(fp);
      66            2 :                         initialized_ = true;
      67              :                 }
      68            2 :                 return rand();  // NOLINT(cert-msc50-cpp)
      69              :         }
      70              : 
      71              :         /**
      72              :          * \brief Get the current partition number, as defined by the ARTDAQ_PARTITION_NUMBER environment variable
      73              :          * \return The current partition number (defaults to 0 if unset, will be between 0 and 127)
      74              :          */
      75           51 :         static int GetPartitionNumber()
      76              :         {
      77           51 :                 uint32_t part_u = 0;
      78              : 
      79              :                 // 23-May-2018, KAB: added the option to return the partition number data member
      80              :                 // and gave it precedence over the env var since it is typcally based on information
      81              :                 // that the user specified on the command line.
      82           51 :                 if (partition_number_ >= 0)
      83              :                 {
      84           44 :                         part_u = static_cast<uint32_t>(partition_number_);
      85              :                 }
      86              :                 else
      87              :                 {
      88            7 :                         auto part = getenv("ARTDAQ_PARTITION_NUMBER");  // Valid values 0-127
      89            7 :                         if (part != nullptr)
      90              :                         {
      91              :                                 try
      92              :                                 {
      93            0 :                                         auto part_s = std::string(part);
      94            0 :                                         part_u = static_cast<uint32_t>(std::stoll(part_s, nullptr, 0));
      95            0 :                                 }
      96            0 :                                 catch (const std::invalid_argument &)
      97            0 :                                 {}
      98            0 :                                 catch (const std::out_of_range &)
      99            0 :                                 {}
     100              :                         }
     101            7 :                         partition_number_ = part_u & 0x7F;
     102              :                 }
     103              : 
     104           51 :                 return (part_u & 0x7F);
     105              :         }
     106              : 
     107              :         /**
     108              :          * \brief Get the Shared Memory Key for a given partition number
     109              :          */
     110           30 :         static uint32_t SharedMemoryKey(uint32_t seed, bool useParentPID = false)
     111              :         {
     112           30 :                 return seed + ((GetPartitionNumber() + 1) << 16) + ((useParentPID ? getppid() : getpid()) & 0xFFFF);
     113              :         }
     114              : 
     115              :         /**
     116              :          * \brief Get the current iteration for MessageFacility messages
     117              :          * \return The current iteration
     118              :          */
     119              :         static std::string GetMFIteration()
     120              :         {
     121              :                 std::unique_lock<std::mutex> lk(mftrace_mutex_);
     122              :                 return mftrace_iteration_;
     123              :         }
     124              : 
     125              :         /**
     126              :          * \brief Get the current module name for MessageFacility messages
     127              :          * \return The current module name
     128              :          */
     129              :         static std::string GetMFModuleName()
     130              :         {
     131              :                 std::unique_lock<std::mutex> lk(mftrace_mutex_);
     132              :                 return mftrace_module_;
     133              :         }
     134              : 
     135              :         /**
     136              :          * \brief Set the current iteration for MessageFacility messages
     137              :          * \param name The current iteration
     138              :          */
     139          443 :         static void SetMFIteration(std::string const &name)
     140              :         {
     141          443 :                 std::unique_lock<std::mutex> lk(mftrace_mutex_);
     142          443 :                 mftrace_iteration_ = name;
     143          443 :         }
     144              : 
     145              :         /**
     146              :          * \brief Set the current module name for MessageFacility messages
     147              :          * \param name The current module name
     148              :          */
     149           15 :         static void SetMFModuleName(std::string const &name)
     150              :         {
     151           15 :                 std::unique_lock<std::mutex> lk(mftrace_mutex_);
     152           15 :                 mftrace_module_ = name;
     153           15 :         }
     154              : 
     155              :         /**
     156              :          * \brief Clean up statically-allocated Manager class instances
     157              :          */
     158            2 :         static void CleanUpGlobals()
     159              :         {
     160            2 :                 metricMan_.reset(nullptr);
     161            2 :                 portMan_.reset(nullptr);
     162            2 :         }
     163              : };
     164              : }  // namespace artdaq
     165              : 
     166              : #include "tracemf.h"
     167              : 
     168              : #endif  // ARTDAQ_DAQDATA_GLOBALS_HH
        

Generated by: LCOV version 2.0-1