// 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);
    }
}
void ROUTE_THROUGH_LI_CHANNEL_OUT_CLASS::push(UMF_MESSAGE &outMesg) 
{

    // Software expects encoding in terms of bytes while the credit scheme speaks in terms of chunks 
    UINT32 messageLengthBytes = outMesg->GetLength(); 
    UINT32 messageLengthChunks = 1 + ((outMesg->GetLength()) / sizeof(UMF_CHUNK));  // Each chunk takes a header plus one bit for encoding?


    if (DEBUG_CHANNELIO) 
    {
        debugLog << endl << "****Outbound Channel "<< this->name << " Sends message " << endl;               
        debugLog << endl << "Base Message length "<< dec << (UINT32) (outMesg->GetLength()) << endl;  
        debugLog << "UMF_CHUNK (bytes) " << sizeof(UMF_CHUNK) << endl;
        debugLog << "Message Length (bytes) "<< dec << messageLengthBytes << endl;
        debugLog << "Message Credits (chunks) "<< dec << messageLengthChunks << endl;
        debugLog << "Channel ID "<< dec << this->channelID << endl;
    }

    // For now we will allow the system to deadlock here. What is really needed is an 
    // means of back pressure all the way to the incoming route through. 
    // TODO: Fix this deadlock with better backpressure cooperation among threads

    acquireCredits(messageLengthChunks);

    // Recode message for the outbound link and send
    {
        outMesg->SetServiceID(this->channelID);
        outputQ->push(outMesg);
    }

    if(DEBUG_CHANNELIO) 
    {
        debugLog << endl << "****Outbound Route-through Channel "<< this->name << " message complete" << endl;            
    }
}
示例#3
0
// accept a delivered message from channelio
void
RRR_SERVER_MONITOR_CLASS::DeliverMessage(
    UMF_MESSAGE message)
{
    // record channelID for backwards compatibility
    int channelID = message->GetChannelID();
    int serviceID = message->GetServiceID();

    // validate serviceID
    if (isServerRegistered(serviceID) == false)
    {
        fprintf(stderr, "software server: invalid serviceID: %u\n", serviceID);
        parent->CallbackExit(1);
    }

    // call service and obtain result
    UMF_MESSAGE result = ServerMap[serviceID]->Request(message);

    // see if we need to respond
    if (result)
    {
        // set serviceID
        result->SetServiceID(serviceID);

        // send to channelio... send on original virtual channel (BC)
        channelio->Write(channelID, result);
    }
}