// write void PHYSICAL_CHANNEL_CLASS::Write( UMF_MESSAGE message) { // construct header unsigned char header[UMF_CHUNK_BYTES]; message->EncodeHeader(header); // write header to pipe unixPipeDevice->Write(header, UMF_CHUNK_BYTES); // write message data to pipe // NOTE: hardware demarshaller expects chunk pattern to start from most // significant chunk and end at least significant chunk, so we will // send chunks in reverse order message->StartReverseExtract(); while (message->CanReverseExtract()) { UMF_CHUNK chunk = message->ReverseExtractChunk(); unixPipeDevice->Write((unsigned char*)&chunk, sizeof(UMF_CHUNK)); } // de-allocate message delete message; }
// write void PHYSICAL_CHANNEL_CLASS::Write(UMF_MESSAGE message) { // construct header unsigned char header[UMF_CHUNK_BYTES]; message->EncodeHeader(header); msg_count_out++; //fprintf(errfd,"attempting to write msg %d of length %d: %x\n", msg_count_out,message->GetLength(),*header); //write header to pipe pcieDevice->Write((const char *)header, UMF_CHUNK_BYTES); // write message data to pipe // NOTE: hardware demarshaller expects chunk pattern to start from most // significant chunk and end at least significant chunk, so we will // send chunks in reverse order message->StartReverseExtract(); while (message->CanReverseExtract()) { UMF_CHUNK chunk = message->ReverseExtractChunk(); //fprintf(errfd,"attempting to write %x\n",chunk); pcieDevice->Write((const char*)&chunk, UMF_CHUNK_BYTES); } // de-allocate message delete message; //fflush(errfd); }
void * QA_PHYSICAL_CHANNEL_CLASS::WriterThread(void *argv) { void ** args = (void**) argv; QA_PHYSICAL_CHANNEL physicalChannel = (QA_PHYSICAL_CHANNEL) args[1]; tbb::concurrent_bounded_queue<UMF_MESSAGE> *incomingQ = &(physicalChannel->writeQ); QA_DEVICE_WRAPPER qaDevice = (QA_DEVICE_WRAPPER) args[0]; while (1) { UMF_MESSAGE message; incomingQ->pop(message); // Check to see if we're being torn down -- this is // done by passing a special message through the writeQ if (message == NULL) { if (!physicalChannel->uninitialized) { cerr << "QA_PHYSICAL_CHANNEL got an unexpected NULL value" << endl; } pthread_exit(0); } // The FPGA side detects NULLs inserted for alignment by looking at the // length field. Having a length of 0 would break the protocol. ASSERTX(message->GetLength() != 0); // construct header UMF_CHUNK header = 0; message->EncodeHeader((unsigned char *)&header); qaDevice->Write(&header, sizeof(header)); size_t n_bytes = message->ExtractBytesLeft(); // Round up to multiple of UMF_CHUNK size n_bytes = (n_bytes + sizeof(UMF_CHUNK) - 1) & ~(sizeof(UMF_CHUNK) - 1); qaDevice->Write(message->ExtractGetRawPtr(), n_bytes); message->ExtractUpdateRawPtr(n_bytes); // de-allocate message delete message; // Flush output channel if there isn't another message ready. if (incomingQ->empty()) { qaDevice->Flush(); } } }
// write void PHYSICAL_CHANNEL_CLASS::Write( UMF_MESSAGE message) { pthread_mutex_lock(&channelLock); // block until buffer has sufficient space CSR_INDEX h2fTailPlusOne = (h2fTail == CSR_H2F_BUF_END) ? CSR_H2F_BUF_START : (h2fTail + 1); while (h2fTailPlusOne == h2fHeadCache) { h2fHeadCache = pciExpressDevice->ReadCommonCSR(CSR_H2F_HEAD); } // construct header UMF_CHUNK header = message->EncodeHeader(); CSR_DATA csr_data = CSR_DATA(header); // write header to physical channel pciExpressDevice->WriteCommonCSR(h2fTail, csr_data); h2fTail = h2fTailPlusOne; h2fTailPlusOne = (h2fTail == CSR_H2F_BUF_END) ? CSR_H2F_BUF_START : (h2fTail + 1); // write message data to physical channel // NOTE: hardware demarshaller expects chunk pattern to start from most // significant chunk and end at least significant chunk, so we will // send chunks in reverse order message->StartReverseExtract(); while (message->CanReverseExtract()) { // this gets ugly - we need to block until space is available while (h2fTailPlusOne == h2fHeadCache) { h2fHeadCache = pciExpressDevice->ReadCommonCSR(CSR_H2F_HEAD); } // space is available, write UMF_CHUNK chunk = message->ReverseExtractChunk(); csr_data = CSR_DATA(chunk); pciExpressDevice->WriteCommonCSR(h2fTail, csr_data); h2fTail = h2fTailPlusOne; h2fTailPlusOne = (h2fTail == CSR_H2F_BUF_END) ? CSR_H2F_BUF_START : (h2fTail + 1); } // sync h2fTail pointer. It is OPTIONAL to do this immediately, but we will do it // since this is probably the response to a request the hardware might be blocked on pciExpressDevice->WriteSystemCSR(genIID() | (OP_UPDATE_H2FTAIL << 16) | (h2fTail << 8)); pthread_mutex_unlock(&channelLock); // de-allocate message delete message; }