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