optimized protocol transfer
This commit is contained in:
+56
-56
@@ -183,93 +183,93 @@ inline unsigned comBuf::fillFromWire ( wireRecvAdapter & wire )
|
||||
inline bool comBuf::push ( const epicsInt8 value )
|
||||
{
|
||||
unsigned index = this->nextWriteIndex;
|
||||
unsigned available = sizeof ( this->buf ) - index;
|
||||
if ( sizeof ( value ) > available ) {
|
||||
return false;
|
||||
unsigned nextIndex = index + sizeof ( value );
|
||||
if ( nextIndex <= sizeof ( this->buf ) ) {
|
||||
this->buf[ index ] = static_cast < epicsUInt8 > ( value );
|
||||
this->nextWriteIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
this->buf[ index ] = static_cast < epicsUInt8 > ( value );
|
||||
this->nextWriteIndex = index + sizeof ( value );
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool comBuf::push ( const epicsUInt8 value )
|
||||
{
|
||||
unsigned index = this->nextWriteIndex;
|
||||
unsigned available = sizeof ( this->buf ) - index;
|
||||
if ( sizeof ( value ) > available ) {
|
||||
return false;
|
||||
unsigned nextIndex = index + sizeof ( value );
|
||||
if ( nextIndex <= sizeof ( this->buf ) ) {
|
||||
this->buf[ index ] = value;
|
||||
this->nextWriteIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
this->buf[ index ] = value;
|
||||
this->nextWriteIndex = index + sizeof ( value );
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool comBuf::push ( const epicsInt16 value )
|
||||
{
|
||||
unsigned index = this->nextWriteIndex;
|
||||
unsigned available = sizeof ( this->buf ) - index;
|
||||
if ( sizeof ( value ) > available ) {
|
||||
return false;
|
||||
unsigned nextIndex = index + sizeof ( value );
|
||||
if ( nextIndex <= sizeof ( this->buf ) ) {
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = index + sizeof ( value );
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool comBuf::push ( const epicsUInt16 value )
|
||||
{
|
||||
unsigned index = this->nextWriteIndex;
|
||||
unsigned available = sizeof ( this->buf ) - index;
|
||||
if ( sizeof ( value ) > available ) {
|
||||
return false;
|
||||
unsigned nextIndex = index + sizeof ( value );
|
||||
if ( nextIndex <= sizeof ( this->buf ) ) {
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = index + sizeof ( value );
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool comBuf::push ( const epicsInt32 value )
|
||||
{
|
||||
unsigned index = this->nextWriteIndex;
|
||||
unsigned available = sizeof ( this->buf ) - index;
|
||||
if ( sizeof ( value ) > available ) {
|
||||
return false;
|
||||
unsigned nextIndex = index + sizeof ( value );
|
||||
if ( nextIndex <= sizeof ( this->buf ) ) {
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 24u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 16u );
|
||||
this->buf[ index + 2u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 3u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 24u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 16u );
|
||||
this->buf[ index + 2u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 3u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = index + sizeof ( value );
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool comBuf::push ( const epicsUInt32 value )
|
||||
{
|
||||
unsigned index = this->nextWriteIndex;
|
||||
unsigned available = sizeof ( this->buf ) - index;
|
||||
if ( sizeof ( value ) > available ) {
|
||||
return false;
|
||||
unsigned nextIndex = index + sizeof ( value );
|
||||
if ( nextIndex <= sizeof ( this->buf ) ) {
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 24u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 16u );
|
||||
this->buf[ index + 2u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 3u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
this->buf[ index + 0u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 24u );
|
||||
this->buf[ index + 1u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 16u );
|
||||
this->buf[ index + 2u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 8u );
|
||||
this->buf[ index + 3u ] =
|
||||
static_cast < epicsUInt8 > ( value >> 0u );
|
||||
this->nextWriteIndex = index + sizeof ( value );
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool comBuf::push ( const epicsFloat32 & value )
|
||||
|
||||
+40
-4
@@ -198,8 +198,6 @@ epicsUInt16 comQueRecv::popUInt16 ()
|
||||
comBuf::throwInsufficentBytesException ();
|
||||
}
|
||||
// try first for all in one buffer efficent version
|
||||
// (double check here avoids slow C++ exception)
|
||||
// (hopefully optimizer removes inside check)
|
||||
epicsUInt16 tmp;
|
||||
comBuf::popStatus status = pComBuf->pop ( tmp );
|
||||
if ( status.success ) {
|
||||
@@ -219,8 +217,6 @@ epicsUInt32 comQueRecv::popUInt32 ()
|
||||
comBuf::throwInsufficentBytesException ();
|
||||
}
|
||||
// try first for all in one buffer efficent version
|
||||
// (double check here avoids slow C++ exception)
|
||||
// (hopefully optimizer removes inside check)
|
||||
epicsUInt32 tmp;
|
||||
comBuf::popStatus status = pComBuf->pop ( tmp );
|
||||
if ( status.success ) {
|
||||
@@ -232,3 +228,43 @@ epicsUInt32 comQueRecv::popUInt32 ()
|
||||
}
|
||||
return this->multiBufferPopUInt32 ();
|
||||
}
|
||||
|
||||
bool comQueRecv::popOldMsgHeader ( caHdrLargeArray & msg )
|
||||
{
|
||||
// try first for all in one buffer efficent version
|
||||
comBuf * pComBuf = this->bufs.first ();
|
||||
if ( ! pComBuf ) {
|
||||
return false;
|
||||
}
|
||||
unsigned avail = pComBuf->occupiedBytes ();
|
||||
if ( avail >= sizeof ( caHdr ) ) {
|
||||
pComBuf->pop ( msg.m_cmmd );
|
||||
ca_uint16_t smallPostsize;
|
||||
pComBuf->pop ( smallPostsize );
|
||||
msg.m_postsize = smallPostsize;
|
||||
pComBuf->pop ( msg.m_dataType );
|
||||
ca_uint16_t smallCount;
|
||||
pComBuf->pop ( smallCount );
|
||||
msg.m_count = smallCount;
|
||||
pComBuf->pop ( msg.m_cid );
|
||||
pComBuf->pop ( msg.m_available );
|
||||
this->nBytesPending -= sizeof ( caHdr );
|
||||
if ( avail == sizeof ( caHdr ) ) {
|
||||
this->removeAndDestroyBuf ( *pComBuf );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if ( this->occupiedBytes () >= sizeof ( caHdr ) ) {
|
||||
msg.m_cmmd = this->popUInt16 ();
|
||||
msg.m_postsize = this->popUInt16 ();
|
||||
msg.m_dataType = this->popUInt16 ();
|
||||
msg.m_count = this->popUInt16 ();
|
||||
msg.m_cid = this->popUInt32 ();
|
||||
msg.m_available = this->popUInt32 ();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
unsigned removeBytes ( unsigned nBytes );
|
||||
void pushLastComBufReceived ( comBuf & );
|
||||
void clear ();
|
||||
bool popOldMsgHeader ( struct caHdrLargeArray & );
|
||||
epicsInt8 popInt8 ();
|
||||
epicsUInt8 popUInt8 ();
|
||||
epicsInt16 popInt16 ();
|
||||
|
||||
+108
-16
@@ -120,6 +120,78 @@ void comQueSend::clearUncommitted ()
|
||||
}
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_string ( const void * pValue )
|
||||
{
|
||||
this->push ( * static_cast <const dbr_string_t *> ( pValue ) );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_short ( const void * pValue )
|
||||
{
|
||||
this->push ( * static_cast <const dbr_short_t *> ( pValue ) );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_float ( const void * pValue )
|
||||
{
|
||||
this->push ( * static_cast <const dbr_float_t *> ( pValue ) );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_char ( const void * pValue )
|
||||
{
|
||||
this->push ( * static_cast <const dbr_char_t *> ( pValue ) );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_long ( const void * pValue )
|
||||
{
|
||||
this->push ( * static_cast <const dbr_long_t *> ( pValue ) );
|
||||
}
|
||||
|
||||
void comQueSend::copy_dbr_double ( const void * pValue )
|
||||
{
|
||||
this->push ( * static_cast <const dbr_double_t *> ( pValue ) );
|
||||
}
|
||||
|
||||
const comQueSend::copyScalarFunc_t comQueSend::dbrCopyScalar [39] = {
|
||||
&comQueSend::copy_dbr_string,
|
||||
&comQueSend::copy_dbr_short,
|
||||
&comQueSend::copy_dbr_float,
|
||||
&comQueSend::copy_dbr_short, // DBR_ENUM
|
||||
&comQueSend::copy_dbr_char,
|
||||
&comQueSend::copy_dbr_long,
|
||||
&comQueSend::copy_dbr_double,
|
||||
0, // DBR_STS_SHORT
|
||||
0, // DBR_STS_FLOAT
|
||||
0, // DBR_STS_ENUM
|
||||
0, // DBR_STS_CHAR
|
||||
0, // DBR_STS_LONG
|
||||
0, // DBR_STS_DOUBLE
|
||||
0, // DBR_TIME_STRING
|
||||
0, // DBR_TIME_INT
|
||||
0, // DBR_TIME_SHORT
|
||||
0, // DBR_TIME_FLOAT
|
||||
0, // DBR_TIME_ENUM
|
||||
0, // DBR_TIME_CHAR
|
||||
0, // DBR_TIME_LONG
|
||||
0, // DBR_TIME_DOUBLE
|
||||
0, // DBR_GR_STRING
|
||||
0, // DBR_GR_SHORT
|
||||
0, // DBR_GR_FLOAT
|
||||
0, // DBR_GR_ENUM
|
||||
0, // DBR_GR_CHAR
|
||||
0, // DBR_GR_LONG
|
||||
0, // DBR_GR_DOUBLE
|
||||
0, // DBR_CTRL_STRING
|
||||
0, // DBR_CTRL_SHORT
|
||||
0, // DBR_CTRL_FLOAT
|
||||
0, // DBR_CTRL_ENUM
|
||||
0, // DBR_CTRL_CHAR
|
||||
0, // DBR_CTRL_LONG
|
||||
0, // DBR_CTRL_DOUBLE
|
||||
&comQueSend::copy_dbr_short, // DBR_PUT_ACKT
|
||||
&comQueSend::copy_dbr_short, // DBR_PUT_ACKS
|
||||
0, // DBR_STSACK_STRING
|
||||
0 // DBR_CLASS_NAME
|
||||
};
|
||||
|
||||
void comQueSend::copy_dbr_string ( const void *pValue, unsigned nElem )
|
||||
{
|
||||
this->push ( static_cast <const dbr_string_t *> ( pValue ), nElem );
|
||||
@@ -150,7 +222,7 @@ void comQueSend::copy_dbr_double ( const void *pValue, unsigned nElem )
|
||||
this->push ( static_cast <const dbr_double_t *> ( pValue ), nElem );
|
||||
}
|
||||
|
||||
const comQueSend::copyFunc_t comQueSend::dbrCopyVector [39] = {
|
||||
const comQueSend::copyVectorFunc_t comQueSend::dbrCopyVector [39] = {
|
||||
&comQueSend::copy_dbr_string,
|
||||
&comQueSend::copy_dbr_short,
|
||||
&comQueSend::copy_dbr_float,
|
||||
@@ -218,23 +290,34 @@ void comQueSend::insertRequestHeader (
|
||||
ca_uint32_t requestDependent, bool v49Ok )
|
||||
{
|
||||
this->beginMsg ();
|
||||
|
||||
if ( payloadSize < 0xffff && nElem < 0xffff ) {
|
||||
this->pushUInt16 ( request );
|
||||
this->pushUInt16 ( static_cast < ca_uint16_t > ( payloadSize ) );
|
||||
this->pushUInt16 ( dataType );
|
||||
this->pushUInt16 ( static_cast < ca_uint16_t > ( nElem ) );
|
||||
this->pushUInt32 ( cid );
|
||||
this->pushUInt32 ( requestDependent );
|
||||
comBuf * pComBuf = this->bufs.last ();
|
||||
if ( !pComBuf || pComBuf->unoccupiedBytes() < 16u ) {
|
||||
pComBuf = newComBuf ();
|
||||
this->pushComBuf ( *pComBuf );
|
||||
}
|
||||
pComBuf->push ( request );
|
||||
pComBuf->push ( static_cast < ca_uint16_t > ( payloadSize ) );
|
||||
pComBuf->push ( dataType );
|
||||
pComBuf->push ( static_cast < ca_uint16_t > ( nElem ) );
|
||||
pComBuf->push ( cid );
|
||||
pComBuf->push ( requestDependent );
|
||||
}
|
||||
else if ( v49Ok ) {
|
||||
this->pushUInt16 ( request );
|
||||
this->pushUInt16 ( 0xffff );
|
||||
this->pushUInt16 ( dataType );
|
||||
this->pushUInt16 ( 0u );
|
||||
this->pushUInt32 ( cid );
|
||||
this->pushUInt32 ( requestDependent );
|
||||
this->pushUInt32 ( payloadSize );
|
||||
this->pushUInt32 ( nElem );
|
||||
comBuf * pComBuf = this->bufs.last ();
|
||||
if ( !pComBuf || pComBuf->unoccupiedBytes() < 24u ) {
|
||||
pComBuf = newComBuf ();
|
||||
this->pushComBuf ( *pComBuf );
|
||||
}
|
||||
pComBuf->push ( request );
|
||||
pComBuf->push ( 0xffff );
|
||||
pComBuf->push ( dataType );
|
||||
pComBuf->push ( 0u );
|
||||
pComBuf->push ( cid );
|
||||
pComBuf->push ( requestDependent );
|
||||
pComBuf->push ( payloadSize );
|
||||
pComBuf->push ( nElem );
|
||||
}
|
||||
else {
|
||||
throw cacChannel::outOfBounds ();
|
||||
@@ -246,7 +329,7 @@ void comQueSend::insertRequestWithPayLoad (
|
||||
ca_uint32_t cid, ca_uint32_t requestDependent, const void * pPayload,
|
||||
bool v49Ok )
|
||||
{
|
||||
if ( ! this->dbr_type_ok ( dataType ) ) {
|
||||
if ( dataType >= comQueSendCopyDispatchSize ) {
|
||||
throw cacChannel::badType();
|
||||
}
|
||||
ca_uint32_t size;
|
||||
@@ -281,7 +364,16 @@ void comQueSend::insertRequestWithPayLoad (
|
||||
if ( stringOptim ) {
|
||||
this->pushString ( static_cast < const char * > ( pPayload ), size );
|
||||
}
|
||||
else if ( nElem == 1u ) {
|
||||
if ( ! this->dbrCopyScalar [dataType] ) {
|
||||
throw cacChannel::badType();
|
||||
}
|
||||
( this->*dbrCopyScalar [dataType] ) ( pPayload );
|
||||
}
|
||||
else {
|
||||
if ( ! this->dbrCopyVector [dataType] ) {
|
||||
throw cacChannel::badType();
|
||||
}
|
||||
( this->*dbrCopyVector [dataType] ) ( pPayload, nElem );
|
||||
}
|
||||
// set pad bytes to nill
|
||||
|
||||
+13
-15
@@ -49,7 +49,6 @@ public:
|
||||
unsigned occupiedBytes () const;
|
||||
bool flushEarlyThreshold ( unsigned nBytesThisMsg ) const;
|
||||
bool flushBlockThreshold ( unsigned nBytesThisMsg ) const;
|
||||
bool dbr_type_ok ( unsigned type );
|
||||
void pushUInt16 ( const ca_uint16_t value );
|
||||
void pushUInt32 ( const ca_uint32_t value );
|
||||
void pushFloat32 ( const ca_float32_t value );
|
||||
@@ -69,16 +68,26 @@ private:
|
||||
tsDLIter < comBuf > pFirstUncommited;
|
||||
wireSendAdapter & wire;
|
||||
unsigned nBytesPending;
|
||||
typedef void ( comQueSend::*copyFunc_t ) (
|
||||
const void *pValue, unsigned nElem );
|
||||
static const copyFunc_t dbrCopyVector [comQueSendCopyDispatchSize];
|
||||
|
||||
typedef void ( comQueSend::*copyScalarFunc_t ) ( const void * pValue );
|
||||
static const copyScalarFunc_t dbrCopyScalar [comQueSendCopyDispatchSize];
|
||||
void copy_dbr_string ( const void * pValue );
|
||||
void copy_dbr_short ( const void * pValue );
|
||||
void copy_dbr_float ( const void * pValue );
|
||||
void copy_dbr_char ( const void * pValue );
|
||||
void copy_dbr_long ( const void * pValue );
|
||||
void copy_dbr_double ( const void * pValue );
|
||||
|
||||
typedef void ( comQueSend::*copyVectorFunc_t ) (
|
||||
const void *pValue, unsigned nElem );
|
||||
static const copyVectorFunc_t dbrCopyVector [comQueSendCopyDispatchSize];
|
||||
void copy_dbr_string ( const void *pValue, unsigned nElem );
|
||||
void copy_dbr_short ( const void *pValue, unsigned nElem );
|
||||
void copy_dbr_float ( const void *pValue, unsigned nElem );
|
||||
void copy_dbr_char ( const void *pValue, unsigned nElem );
|
||||
void copy_dbr_long ( const void *pValue, unsigned nElem );
|
||||
void copy_dbr_double ( const void *pValue, unsigned nElem );
|
||||
|
||||
void pushComBuf ( comBuf & );
|
||||
comBuf * newComBuf ();
|
||||
void clearUncommitted ();
|
||||
@@ -128,17 +137,6 @@ private:
|
||||
|
||||
extern const char cacNillBytes[];
|
||||
|
||||
inline bool comQueSend::dbr_type_ok ( unsigned type )
|
||||
{
|
||||
if ( type >= comQueSendCopyDispatchSize ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! this->dbrCopyVector [type] ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void comQueSend::pushUInt16 ( const ca_uint16_t value )
|
||||
{
|
||||
this->push ( value );
|
||||
|
||||
+6
-10
@@ -751,21 +751,17 @@ bool tcpiiu::processIncoming (
|
||||
|
||||
if ( ! this->msgHeaderAvailable ) {
|
||||
if ( ! this->oldMsgHeaderAvailable ) {
|
||||
if ( nBytes < sizeof ( caHdr ) ) {
|
||||
this->oldMsgHeaderAvailable =
|
||||
this->recvQue.popOldMsgHeader ( this->curMsg );
|
||||
if ( ! this->oldMsgHeaderAvailable ) {
|
||||
this->flushIfRecvProcessRequested ();
|
||||
return true;
|
||||
}
|
||||
this->curMsg.m_cmmd = this->recvQue.popUInt16 ();
|
||||
this->curMsg.m_postsize = this->recvQue.popUInt16 ();
|
||||
this->curMsg.m_dataType = this->recvQue.popUInt16 ();
|
||||
this->curMsg.m_count = this->recvQue.popUInt16 ();
|
||||
this->curMsg.m_cid = this->recvQue.popUInt32 ();
|
||||
this->curMsg.m_available = this->recvQue.popUInt32 ();
|
||||
this->oldMsgHeaderAvailable = true;
|
||||
}
|
||||
}
|
||||
if ( this->curMsg.m_postsize == 0xffff ) {
|
||||
static const unsigned annexSize =
|
||||
sizeof ( this->curMsg.m_postsize ) + sizeof ( this->curMsg.m_count );
|
||||
sizeof ( this->curMsg.m_postsize ) +
|
||||
sizeof ( this->curMsg.m_count );
|
||||
if ( this->recvQue.occupiedBytes () < annexSize ) {
|
||||
this->flushIfRecvProcessRequested ();
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user