logbitvar.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include <limits.h>
  2. #include <limits>
  3. #include "logvar.h"
  4. #include "debug.h"
  5. #define GET_BOOL_VAL(p, m) (!!(*p & m))
  6. #define SET_BIT(p, m) (*p |= m)
  7. #define CLR_BIT(p, m) (*p &= ~m)
  8. #define STORE_BIT(p, m, b) (b) ? SET_BIT(p, m) : CLR_BIT(p, m)
  9. /////////////////////////////////////////////////////////////////////////////
  10. CLogBitVariable::CLogBitVariable(LogTypes lt, void *pData, size_t nOffset, unsigned int nBitNr, bool *pbLogCond, HSHM hShm, const char *pszName, CLoggable *pParent)
  11. : m_lt(lt), m_pbLogCond(pbLogCond), m_bOldLogCond(false), m_name(pszName), m_pszPath(NULL), m_fLastSample(0), m_fSamples(0), m_hShm(hShm),
  12. m_pParent(pParent), m_nUpdates(0), m_nTagID(0), m_nSampleCount(0), m_bCvIsBit(false), m_bIsDbPersistant(_IS_DB_PERSISTENT_LOGTYPE(lt))
  13. {
  14. if(!pData || !hShm || nBitNr > 7)
  15. {
  16. ASSERT(false);
  17. }
  18. m_bIsCondLog = _IS_CONDITIONAL_LOGTYPE(m_lt);
  19. m_bIsIntervalLog = _IS_INTERVAL_LOGTYPE(m_lt);
  20. if(m_bIsCondLog && !m_pbLogCond)
  21. {
  22. ASSERT(false);
  23. }
  24. m_fMin = std::numeric_limits<double>::infinity();
  25. m_fMax = -std::numeric_limits<double>::infinity();
  26. m_pnByte = (uint8_t*)pData + nOffset;
  27. m_nMask = 0x01 << nBitNr;
  28. Lock();
  29. m_cacheVal = GET_BOOL_VAL(m_pnByte, m_nMask);
  30. Unlock();
  31. }
  32. CLogBitVariable::CLogBitVariable(LogTypes lt, void *pData, size_t nOffset, unsigned int nBitNr, size_t nCvOffset, unsigned int nCvBitNr, HSHM hShm, const char *pszName, CLoggable *pParent)
  33. : m_lt(lt), m_pbLogCond(NULL), m_bOldLogCond(false), m_name(pszName), m_pszPath(NULL), m_fLastSample(0), m_fSamples(0), m_pParent(pParent), m_nUpdates(0),
  34. m_nTagID(0), m_nSampleCount(0), m_bCvIsBit(true), m_bIsDbPersistant(_IS_DB_PERSISTENT_LOGTYPE(lt))
  35. {
  36. if(!pData || !hShm || nBitNr > 7 || nCvBitNr > 7)
  37. {
  38. ASSERT(false);
  39. }
  40. m_bIsCondLog = _IS_CONDITIONAL_LOGTYPE(m_lt);
  41. m_bIsIntervalLog = _IS_INTERVAL_LOGTYPE(m_lt);
  42. m_hShm = hShm;
  43. m_fMin = std::numeric_limits<double>::infinity();
  44. m_fMax = -std::numeric_limits<double>::infinity();
  45. m_pnByte = (uint8_t*)pData + nOffset;
  46. m_nMask = 0x01 << nBitNr;
  47. m_pnCvByte = (uint8_t*)pData + nCvOffset;
  48. m_nCvMask = 0x01 << nCvBitNr;
  49. Lock();
  50. m_cacheVal = GET_BOOL_VAL(m_pnByte, m_nMask);
  51. Unlock();
  52. }
  53. CLogBitVariable::~CLogBitVariable(void)
  54. {
  55. }
  56. /////////////////////////////////////////////////////////////////////////////
  57. void CLogBitVariable::InitPath(CLoggable *pParent, const char *pszMemberName)
  58. {
  59. if(!pszMemberName)
  60. pszMemberName = "";
  61. if(pParent)
  62. {
  63. m_path = pParent->GetPath();
  64. m_path += "/";
  65. m_path += pszMemberName;
  66. }
  67. else
  68. {
  69. m_path = pszMemberName;
  70. }
  71. m_pszPath = m_path.c_str();
  72. }
  73. /////////////////////////////////////////////////////////////////////////////
  74. void CLogBitVariable::InitTagID(CDataLogger &rdl)
  75. {
  76. if((m_nTagID = rdl.GetTagID(m_pszPath, (int)CLogVariable::VT_bool, (int)m_lt)) == ULONG_MAX)
  77. {
  78. ASSERT(false);
  79. }
  80. }
  81. /////////////////////////////////////////////////////////////////////////////
  82. bool CLogBitVariable::CanLog(bool fLock)
  83. {
  84. if(!m_bIsCondLog)
  85. return true;
  86. bool bRet;
  87. if(fLock)
  88. Lock();
  89. if(m_bCvIsBit)
  90. bRet = GET_BOOL_VAL(m_pnCvByte, m_nCvMask);
  91. else
  92. bRet = *m_pbLogCond;
  93. if(fLock)
  94. Unlock();
  95. return bRet;
  96. }
  97. /////////////////////////////////////////////////////////////////////////////
  98. void CLogBitVariable::Sample(void)
  99. {
  100. if(!m_bIsIntervalLog)
  101. return;
  102. Lock();
  103. if(CanLog(false))
  104. {
  105. m_fLastSample = GET_BOOL_VAL(m_pnByte, m_nMask) ? 1.0 : 0.0;
  106. if(m_fMin > m_fLastSample)
  107. m_fMin = m_fLastSample;
  108. if(m_fMax < m_fLastSample)
  109. m_fMax = m_fLastSample;
  110. m_fSamples += m_fLastSample;
  111. m_nSampleCount++;
  112. }
  113. Unlock();
  114. }
  115. /////////////////////////////////////////////////////////////////////////////
  116. void CLogBitVariable::LogInterval(time_t nTimestamp, CDataLogger &rdl)
  117. {
  118. if(!m_bIsIntervalLog)
  119. {
  120. m_fSamples = 0;
  121. m_nSampleCount = 0;
  122. return;
  123. }
  124. if(!CanLog(true))
  125. {
  126. m_fSamples = 0;
  127. m_nSampleCount = 0;
  128. return;
  129. }
  130. if(m_nSampleCount > 0)
  131. {
  132. if(!m_bIsDbPersistant)
  133. {
  134. if(m_nSampleCount > 1)
  135. m_fSamples /= (double)m_nSampleCount;
  136. rdl.Log(m_nTagID, m_fSamples, m_fMin, m_fMax, nTimestamp, -1, m_lt);
  137. }
  138. else
  139. {
  140. rdl.Log(m_nTagID, m_fLastSample, m_fMin, m_fMax, nTimestamp, -1, m_lt);
  141. }
  142. }
  143. m_fSamples = 0;
  144. m_fMin = std::numeric_limits<double>::infinity();
  145. m_fMax = -std::numeric_limits<double>::infinity();
  146. m_nSampleCount = 0;
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. void CLogBitVariable::LogValueChanged(time_t nTimestamp, CDataLogger &rdl, bool bStartup, bool bWriteNull)
  150. {
  151. if(m_bIsIntervalLog)
  152. return;
  153. if(bWriteNull) // force write of a NULL value and exit
  154. {
  155. rdl.Log(m_nTagID, 0.0, 0.0, 0.0, nTimestamp, -1, m_lt, true, bStartup);
  156. return;
  157. }
  158. bool val, bCondition, bConditionChanged;
  159. Lock();
  160. if((bCondition = CanLog(false)))
  161. val = GET_BOOL_VAL(m_pnByte, m_nMask);
  162. Unlock();
  163. bConditionChanged = (m_bOldLogCond != bCondition) || bStartup;
  164. m_bOldLogCond = bCondition;
  165. if(!bCondition && !bConditionChanged)
  166. return;
  167. if(bCondition && ((m_cacheVal != val) || bConditionChanged)) // log value, if either the value has changed or a condition transition from 0 to 1 has occured
  168. {
  169. m_cacheVal = val;
  170. double fVal = m_cacheVal ? 1.0 : 0.0;
  171. rdl.Log(m_nTagID, fVal, 0.0, 0.0, nTimestamp, -1, m_lt);
  172. }
  173. else if(!bCondition && bConditionChanged) // log a NULL value , if a condition transition from 1 to 0 has occured
  174. {
  175. rdl.Log(m_nTagID, 0.0, 0.0, 0.0, nTimestamp, -1, m_lt, true);
  176. }
  177. }
  178. /////////////////////////////////////////////////////////////////////////////
  179. void CLogBitVariable::Lock(void)
  180. {
  181. ::GfaIpcLockSHM(m_hShm);
  182. }
  183. /////////////////////////////////////////////////////////////////////////////
  184. void CLogBitVariable::Unlock(void)
  185. {
  186. ::GfaIpcUnlockSHM(m_hShm);
  187. }