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);