// Regional Manager has a credit queue to send back flowcontrol credits?? void FLOWCONTROL_LI_CHANNEL_IN_CLASS::freeCredits(UINT32 serviceID) { if(SWITCH_DEBUG) { cout << "Channel " << serviceID << "Freeing credits: local: " << flowcontrolCredits << " regional: " << regionalFlowcontrol->GetRegionalCredits() << " returnThreshold: " << regionalReturnThreshold << endl; } if(((flowcontrolCredits > 0) && (regionalFlowcontrol->GetRegionalCredits() > regionalReturnThreshold)) || (flowcontrolCredits > regionalReturnThreshold / 2)) { if(SWITCH_DEBUG) { cout << "Channel " << serviceID << " sending back credits " << flowcontrolCredits << endl; } UMF_MESSAGE outMesg = factory->createUMFMessage(); outMesg->SetLength(sizeof(UMF_CHUNK)); outMesg->SetServiceID(flowcontrolChannelID); // Atomic read returns the old value, making this operation thread safe under idempotence. UINT32 creditsToReturn = flowcontrolCredits.fetch_and_store(0); UINT32 phyPvt = (serviceID * 2 * MULTIFPGA_FIFO_SIZES) | creditsToReturn; if(SWITCH_DEBUG) { cout << "Setting phy pvt to " << hex << phyPvt << dec <<endl; } outMesg->AppendChunk((UINT128) phyPvt); regionalFlowcontrol->FreeRegionalCredits(creditsToReturn); flowcontrolQ->push(outMesg); } }