Ejemplo n.º 1
0
bool SCI_Transporter::doSend() { 
#ifdef DEBUG_TRANSPORTER  
  NDB_TICKS startSec=0, stopSec=0; 
  Uint32 startMicro=0, stopMicro=0, totalMicro=0; 
#endif
  sci_error_t             err; 
  Uint32 retry=0; 
 
  const char * const sendPtr = (char*)m_sendBuffer.m_buffer;
  const Uint32 sizeToSend    = 4 * m_sendBuffer.m_dataSize; //Convert to number of bytes
  
  if (sizeToSend > 0){
#ifdef DEBUG_TRANSPORTER 
    if(sizeToSend < 1024 ) 
      i1024++; 
    if(sizeToSend > 1024 && sizeToSend < 2048 ) 
      i10242048++; 
    if(sizeToSend==2048) 
      i2048++; 
    if(sizeToSend>2048 && sizeToSend < 4096) 
      i20484096++; 
    if(sizeToSend==4096) 
      i4096++; 
    if(sizeToSend==4097) 
      i4097++; 
#endif
      
  tryagain:
    retry++;
    if (retry > 3) { 
      DBUG_PRINT("error", ("SCI Transfer failed"));
      report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
      return false; 
    } 
    Uint32 * insertPtr = (Uint32 *) 
      (m_TargetSegm[m_ActiveAdapterId].writer)->getWritePtr(sizeToSend); 
    
    if(insertPtr != 0) {	   
      
      const Uint32 remoteOffset=(Uint32) 
	((char*)insertPtr -  
	 (char*)(m_TargetSegm[m_ActiveAdapterId].mappedMemory)); 
      
      SCIMemCpy(m_TargetSegm[m_ActiveAdapterId].sequence, 
		(void*)sendPtr, 
		m_TargetSegm[m_ActiveAdapterId].rhm[m_ActiveAdapterId].map, 
		remoteOffset, 
		sizeToSend, 
		SCI_FLAG_ERROR_CHECK, 
		&err);   
      
      if (err != SCI_ERR_OK) { 
        if (err == SCI_ERR_OUT_OF_RANGE ||
            err == SCI_ERR_SIZE_ALIGNMENT ||
            err == SCI_ERR_OFFSET_ALIGNMENT) { 
          DBUG_PRINT("error", ("Data transfer error = %d", err));
          report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
	  return false; 
        } 
        if(err == SCI_ERR_TRANSFER_FAILED) { 
	  if(getLinkStatus(m_ActiveAdapterId))
	    goto tryagain; 
          if (m_adapters == 1) {
            DBUG_PRINT("error", ("SCI Transfer failed"));
            report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
	    return false; 
          }
	  m_failCounter++; 
	  Uint32 temp=m_ActiveAdapterId;	    	     
	  if (getLinkStatus(m_StandbyAdapterId)) { 
	    failoverShmWriter();		 
	    SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0); 
	    m_ActiveAdapterId=m_StandbyAdapterId; 
	    m_StandbyAdapterId=temp; 
            DBUG_PRINT("error", ("Swapping from adapter %u to %u",
                       m_StandbyAdapterId, m_ActiveAdapterId));
	  } else {
	    report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
            DBUG_PRINT("error", ("SCI Transfer failed")); 
	  }
        }
      } else { 
	SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer);
	writer->updateWritePtr(sizeToSend); 
	
	Uint32 sendLimit = writer->getBufferSize();
	sendLimit -= writer->getWriteIndex();
	
	m_sendBuffer.m_dataSize = 0;
	m_sendBuffer.m_forceSendLimit = sendLimit;
      } 
    } else { 
      /** 
       * If we end up here, the SCI segment is full.  
       */ 
      DBUG_PRINT("error", ("the segment is full for some reason")); 
      return false; 
    } //if  
  } 
  return true; 
} // doSend() 
Ejemplo n.º 2
0
bool SCI_Transporter::doSend() { 
#ifdef DEBUG_TRANSPORTER  
  NDB_TICKS startSec=0, stopSec=0; 
  Uint32 startMicro=0, stopMicro=0, totalMicro=0; 
#endif
  sci_error_t             err; 
  Uint32 retry=0; 
 
  if (!fetch_send_iovec_data())
    return false;

  Uint32 used = m_send_iovec_used;
  if (used == 0)
    return true;                                // Nothing to send

#ifdef DEBUG_TRANSPORTER 
  Uint32 sizeToSend = 0;
  for (Uint32 i = 0; i < used; i++)
    sizeToSend += m_send_iovec[i].iov_len;

  if(sizeToSend < 1024 )
    i1024++;
  if(sizeToSend > 1024 && sizeToSend < 2048 )
    i10242048++;
  if(sizeToSend==2048)
    i2048++;
  if(sizeToSend>2048 && sizeToSend < 4096)
    i20484096++;
  if(sizeToSend==4096)
    i4096++;
  if(sizeToSend==4097)
    i4097++;
#endif
      
  bool status = true;
  Uint32 curr = 0;
  Uint32 total = 0;
  while (curr < used)
  {
  tryagain:
    if (retry > 3) { 
      DBUG_PRINT("error", ("SCI Transfer failed"));
      report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
      status = false;
      break;
    } 
    Uint32 segSize = m_send_iovec[curr].iov_len;
    Uint32 * insertPtr = (Uint32 *) 
      (m_TargetSegm[m_ActiveAdapterId].writer)->getWritePtr(segSize);
    
    if(insertPtr != 0) {	   
      
      const Uint32 remoteOffset=(Uint32) 
	((char*)insertPtr -  
	 (char*)(m_TargetSegm[m_ActiveAdapterId].mappedMemory)); 
      
      SCIMemCpy(m_TargetSegm[m_ActiveAdapterId].sequence, 
		(void*)m_send_iovec[curr].iov_base,
		m_TargetSegm[m_ActiveAdapterId].rhm[m_ActiveAdapterId].map, 
		remoteOffset, 
		segSize,
		SCI_FLAG_ERROR_CHECK, 
		&err);   
      
      if (err != SCI_ERR_OK) { 
        if (err == SCI_ERR_OUT_OF_RANGE ||
            err == SCI_ERR_SIZE_ALIGNMENT ||
            err == SCI_ERR_OFFSET_ALIGNMENT) { 
          DBUG_PRINT("error", ("Data transfer error = %d", err));
          report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
          status = false;
          break;
        } 
        if(err == SCI_ERR_TRANSFER_FAILED) { 
	  if(getLinkStatus(m_ActiveAdapterId))
          {
            retry++;
	    goto tryagain; 
          }
          if (m_adapters == 1) {
            DBUG_PRINT("error", ("SCI Transfer failed"));
            report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
            status = false;
            break;
          }
	  m_failCounter++; 
	  Uint32 temp=m_ActiveAdapterId;	    	     
	  if (getLinkStatus(m_StandbyAdapterId)) { 
	    failoverShmWriter();		 
	    SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0); 
	    m_ActiveAdapterId=m_StandbyAdapterId; 
	    m_StandbyAdapterId=temp; 
            DBUG_PRINT("error", ("Swapping from adapter %u to %u",
                       m_StandbyAdapterId, m_ActiveAdapterId));
	  } else {
	    report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
            DBUG_PRINT("error", ("SCI Transfer failed")); 
	  }
        }
        break;
      } else { 
	SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer);
	writer->updateWritePtr(segSize);
	
        curr++;
        total += segSize;
      } 
    } else { 
      /** 
       * If we end up here, the SCI segment is full. As long as we manage to
       * send _something_, that is ok.
       */ 
      if (curr == 0)
      {
        DBUG_PRINT("error", ("the segment is full for some reason"));
        status = false;
      }
      break;
    } //if  
  } 

  if (total > 0)
    iovec_data_sent(total);

  return status;
} // doSend()