18 #ifndef __SAFE_COUNTER_HPP 
   19 #define __SAFE_COUNTER_HPP 
   51 #include <NodeBitmask.hpp> 
   53 #include "VMSignal.hpp" 
   67   bool setSize(Uint32 maxNoOfActiveMutexes, 
bool exit_on_error = 
true);
 
   68   Uint32 getSize() 
const ;
 
   69   Uint32 getNoOfFree() 
const;
 
   71   void execNODE_FAILREP(
Signal*); 
 
   72   void printNODE_FAILREP(); 
 
   75   struct ActiveCounter { 
 
   83       Uint8 m_senderRefOffset;
 
   84       Uint8 m_senderDataOffset;
 
   85       Uint8 m_errorCodeOffset;
 
   86       Uint8 m_nodeFailErrorCode;
 
   97   bool seize(ActiveCounterPtr& ptr);
 
   98   void release(ActiveCounterPtr& ptr);
 
   99   void getPtr(ActiveCounterPtr& ptr, Uint32 ptrI);
 
  105   BlockReference reference() 
const;
 
  106   void progError(
int line, 
int err_code, 
const char* 
extra = 0);
 
  123   Uint32 m_activeCounterPtrI;
 
  131   template<
typename SignalClass>
 
  132     bool init(Uint16 
block, Uint16 GSN, Uint32 senderData);
 
  134   template<
typename SignalClass>
 
  137   template<
typename SignalClass>
 
  142   void clearWaitingFor();
 
  148   bool clearWaitingFor(Uint32 nodeId);
 
  149   bool forceClearWaitingFor(Uint32 nodeId);
 
  151   bool isWaitingFor(Uint32 nodeId) 
const;
 
  154   const char * getText() 
const; 
 
  165   Uint32 & m_activeCounterPtrI;
 
  169 SafeCounterHandle::SafeCounterHandle(){
 
  170   m_activeCounterPtrI = RNIL;
 
  175 SafeCounterHandle::done()
 const {
 
  176   return m_activeCounterPtrI == RNIL;
 
  182     m_activeCounterPtrI(handle.m_activeCounterPtrI)
 
  184   m_ptr.i = handle.m_activeCounterPtrI;
 
  185   if (m_ptr.i == RNIL) {
 
  189     m_mgr.getPtr(m_ptr, m_ptr.i);
 
  190     m_nodes = m_ptr.p->m_nodes;
 
  191     m_count = m_nodes.
count();
 
  195 template<
typename Ref>
 
  198 SafeCounter::init(Uint16 
block, Uint16 GSN, Uint32 senderData){
 
  201   signalDesc.m_gsn = GSN;
 
  202   signalDesc.m_block = 
block;
 
  203   signalDesc.m_errorCodeOffset = offsetof(Ref, errorCode) >> 2;
 
  204   signalDesc.m_senderRefOffset = offsetof(Ref, senderRef) >> 2;
 
  205   signalDesc.m_senderDataOffset = offsetof(Ref, senderData) >> 2;
 
  206   signalDesc.m_nodeFailErrorCode = Ref::NF_FakeErrorREF;
 
  207   assert(((Uint32)Ref::NF_FakeErrorREF) < 256);
 
  211     if(m_mgr.seize(ptr)){
 
  212       ptr.p->m_senderData = senderData;
 
  213       ptr.p->m_signalDesc = signalDesc;
 
  221     m_ptr.p->m_senderData = senderData;
 
  222     m_ptr.p->m_signalDesc = signalDesc;
 
  226   ErrorReporter::handleAssert(
"SafeCounter::init twice", __FILE__, __LINE__);  
 
  230 template<
typename Ref>
 
  235   if (init<Ref>(rg.m_block, GSN, senderData))
 
  237     m_nodes = rg.m_nodes;
 
  238     m_count = m_nodes.
count();
 
  240     if (unlikely(m_count == 0))
 
  242       ErrorReporter::handleAssert(
"SafeCounter::empty node list",
 
  250 template<
typename Ref>
 
  255   if (init<Ref>(rg.m_block, Ref::GSN, senderData))
 
  257     m_nodes = rg.m_nodes;
 
  258     m_count = m_nodes.
count();
 
  260     if (unlikely(m_count == 0))
 
  262       ErrorReporter::handleAssert(
"SafeCounter::empty node list",
 
  273   if(!m_nodes.
get(nodeId)){
 
  278   ErrorReporter::handleAssert(
"SafeCounter::set", __FILE__, __LINE__);
 
  283 SafeCounter::isWaitingFor(Uint32 nodeId)
 const {
 
  284   return m_nodes.
get(nodeId);
 
  289 SafeCounter::done()
 const {
 
  295 SafeCounter::clearWaitingFor(Uint32 nodeId) {
 
  296   if(m_count > 0 && m_nodes.
get(nodeId)){
 
  298     m_nodes.
clear(nodeId);
 
  299     return (m_count == 0);
 
  301   ErrorReporter::handleAssert(
"SafeCounter::clear", __FILE__, __LINE__);
 
  307 SafeCounter::clearWaitingFor(){
 
  314 SafeCounter::forceClearWaitingFor(Uint32 nodeId){
 
  315   if(isWaitingFor(nodeId)){
 
  316     return clearWaitingFor(nodeId);
 
  318   return (m_count == 0);