Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:26

0001 //
0002 // Created by Nathan Brei on 6/18/20.
0003 //
0004 
0005 #pragma once
0006 
0007 #include <map>
0008 #include <mutex>
0009 #include <sstream>
0010 #include <iomanip>
0011 
0012 template <typename T>
0013 class JStatusBits {
0014 
0015     uint64_t m_status = 0L;
0016     static std::mutex m_mutex;
0017     static std::map<uint32_t, std::string> m_status_bit_descriptions;
0018 
0019 public:
0020 
0021     void SetStatus(uint64_t status) { m_status = status; }
0022 
0023     uint64_t GetStatus() const { return m_status; }
0024 
0025     bool GetStatusBit(T bit) const
0026     {
0027         /// Return the present value of the specified status bit.
0028         /// The value of "bit" should be from 0-63.
0029 
0030         return (m_status>>int(bit)) & 0x01;
0031     }
0032 
0033     bool SetStatusBit(T bit, bool val=true)
0034     {
0035         /// Set the value of the specified status bit. If the
0036         /// second argument is passed, the bit will be set to
0037         /// that value. Otherwise, the bit will be set to "true".
0038         /// The value of "bit" should be from 0-63.
0039         /// The value of the status bit prior to  this call is
0040         /// returned.
0041 
0042         bool old_val = (m_status>>int(bit)) & 0x01;
0043 
0044         uint64_t mask = ((uint64_t)0x01)<<int(bit);
0045 
0046         if(val){
0047             // Set bit
0048             m_status |= mask;
0049         }else{
0050             // Clear bit
0051             m_status &= ~mask;
0052         }
0053 
0054         return old_val;
0055     }
0056 
0057 
0058     bool ClearStatusBit(T bit)
0059     {
0060         /// Clear the specified status bit.
0061         /// The value of "bit" should be from 0-63.
0062         /// This is equivalent to calling SetStatusBit(bit, false).
0063         /// The value of the status bit prior to  this call is
0064         /// returned.
0065 
0066         bool old_val = (m_status>>int(bit)) & 0x01;
0067 
0068         uint64_t mask = ((uint64_t)0x01)<<int(bit);
0069 
0070         m_status &= ~mask;
0071 
0072         return old_val;
0073     }
0074 
0075 
0076     void ClearStatus()
0077     {
0078         /// Clear all bits in the status word. This
0079         /// is equivalent to calling SetStatus(0).
0080 
0081         m_status = 0L;
0082     }
0083 
0084 
0085     static void SetStatusBitDescription(T bit, std::string description)
0086     {
0087         /// Set the description of the specified bit.
0088         /// The value of "bit" should be from 0-63.
0089 
0090         std::lock_guard<std::mutex> lock(m_mutex);
0091         m_status_bit_descriptions[bit] = description;
0092     }
0093 
0094 
0095     static std::string GetStatusBitDescription(T bit)
0096     {
0097         /// Get the description of the specified status bit.
0098         /// The value of "bit" should be from 0-63.
0099 
0100         std::string description("no description available");
0101 
0102         std::lock_guard<std::mutex> lock(m_mutex);
0103         auto iter = m_status_bit_descriptions.find(bit);
0104         if(iter != m_status_bit_descriptions.end()) description = iter->second;
0105 
0106         return description;
0107     }
0108 
0109 
0110     static void GetStatusBitDescriptions(std::map<uint32_t, std::string> &status_bit_descriptions)
0111     {
0112         /// Get the full list of descriptions of status bits.
0113         /// Note that the meaning of the bits is implementation
0114         /// specific and so descriptions are optional. It may be
0115         /// that some or none of the bits used have an associated description.
0116 
0117         std::lock_guard<std::mutex> lock(m_mutex);
0118         status_bit_descriptions = m_status_bit_descriptions;
0119     }
0120 
0121 
0122     std::string ToString() const
0123     {
0124         /// Generate a formatted string suitable for printing to the screen, including the
0125         /// entire word in both hexadecimal and binary along with descriptions.
0126 
0127         // Lock mutex to prevent changes to status_bit_descriptions while we
0128         // read from it.
0129         std::lock_guard<std::mutex> lock(m_mutex);
0130 
0131         std::stringstream ss;
0132 
0133         // Add status in hex first
0134         ss << "status: 0x" << std::hex << std::setw(sizeof(uint64_t)*2) << std::setfill('0') << m_status << std::dec <<std::endl;
0135 
0136         // Binary
0137         ss << std::setw(0) << "   bin |";
0138         for(int i=sizeof(uint64_t)*8-1; i>=0; i--){
0139             ss << ((m_status>>i) & 0x1);
0140             if((i%8)==0) ss << "|";
0141         }
0142         ss << std::endl;
0143 
0144         // 1-byte hex under binary
0145         ss << "   hex ";
0146         for(int i=sizeof(uint64_t) - 1; i>=0; i--){
0147             ss << std::hex << "   0x"<< std::setw(2) << ((m_status>>(i*8)) & 0xFF) << "  ";
0148         }
0149         ss << std::endl;
0150 
0151         // Descriptions for each bit that has a description or is set
0152         for(unsigned int i=0; i<sizeof(uint64_t)*8; i++){
0153             uint64_t val = ((m_status>>i) & 0x1);
0154 
0155             auto iter = m_status_bit_descriptions.find(i);
0156 
0157             if(iter != m_status_bit_descriptions.end() || val != 0){
0158                 ss << std::dec << std::setw(2) << std::setfill(' ');
0159                 ss << " " << val << " - [" << std::setw(2) << std::setfill(' ') << i << "] " << m_status_bit_descriptions[i] << std::endl;
0160             }
0161         }
0162         ss << std::endl;
0163         return ss.str();
0164     }
0165 
0166 };
0167 
0168 template <typename T>
0169 std::mutex JStatusBits<T>::m_mutex;
0170 
0171 template <typename T>
0172 std::map<uint32_t, std::string> JStatusBits<T>::m_status_bit_descriptions;
0173 
0174