Template class .. Porting C to C++

M

Michele

Slowly embracing C++ and as such I've got C code (see snippet below)
I'd like to essentially port to C++. The idea is to

1. Use a TEMPLATE class to handle the 'double' buffering scheme
outlined in the code. Perhaps an operator= approach would be ideal.
I've looked at benchmarks per these newsgroups on std::copy and
realize it's too slow when compared to memcopy.
2. Inside the template class, create a function that'll return the
'latest' double buffered copy of the the appropriate struct
3. Perhaps create a function to compare the two buffers.

Of course I'll leave the class to implement whatever else I could
dream of. The question. Could I garner assistance on an
implementation approach. Perhapts the LDS_MESSAGE_STRUCT version is a
good start.

Assume the LSD_MESSAGE_STRUCT is

typedef struct _LDS_MESSAGE_STRUCT
{
unsigned int x : 16;
unsinged int y : 16;
} LDS_MESSAGE_STRUCT ;


Just unsure which direction to run.

void Rx_SMML_Msg()
{
char buffer[PAYLOAD];
STATUS status;
int size, i;
LDS_HEADER_RECORD MessageID, Message_type;


// call Rx_Message() to process received messages
Rx_Message( (UCHAR*)buffer, &size, &MsgStatus );

// check status
if( MsgStatus != OK )
{
rx_error_count++; // increment error count
printf( "Rx_Message interrupt process error -- %d\n",
rx_error_count);
return;
}

MessageID = ((LDS_HEADER_RECORD *)buffer)->ID;

printf("\n\Received msg ==> MessageID = %x\n",MessageID );

// parse out message type - check error bit
if ( (MessageID & MSG_ID_ERROR_MASK) == 0 )
{
// Good message. Parse out message type from MessageID
Message_type = (((( MessageID >> 4 ) & MSG_ID_MASK ) <<3 )) | (
MessageID & MSG_ID_MASK );

switch( Message_type )
{
case LDS_Control_Message__Control:
if( lds_system_control_message_ready ) // check if not
emptied
{
lds_system_control_message_in_use++;

printf( "LDS_System_Control error ==> buffer use -- %d\n",
lds_system_control_message_in_use);
}
else
{
printf( "LDS_System_Control Message loaded !!!\n");

// start double buffering scheme.

i = lds_system_control_message_index ^ 1;
memcpy( &lds_system_control_message, buffer,
sizeof(LDS_MESSAGE_STRUCT) );
lds_system_control_message_ready = TRUE;
// toggle index 0/1
lds_system_control_message_index ^= 1;
}
break;

case RDS_Message__System_Control:
if( rds_system_control_message_ready ) // check if not
emptied
{
rds_system_control_message_in_use++;

printf( "RDS_System_Control error ==> buffer use -- %d\n",
rds_system_control_message_in_use);
}
else
{
printf( "RDS_System_Control Message loaded !!!\n");

// start double buffering scheme.

i = rds_system_control_message_index ^ 1;
memcpy( &rds_system_control_message, buffer,
sizeof(RDS_MESSAGE_STRUCT) );
rds_system_control_message_ready = TRUE;
// toggle index 0/1
rds_system_control_message_index ^= 1;
}
break;

// LOTS more like the two case statement above

default:// unknown message
printf("UNKNOWN MESSAGE RCV'D !!!\n");
break; // add an error
}
}
else//message error bit set
{
switch( MessageID )
{
case LDS_System_Control_Err:
lds_system_control_message_error++;
printf( "LDS_System_Control_Msg_Err_Bit -- %d\n",
lds_system_control_message_error);
break;
case RDS_System_Control_Err:
rds_system_control_message_error++;
printf( "RDS_System_Control_Msg_Err_Bit -- %d\n",
rds_system_control_message_error);
break;

default:
printf( "Message_Err of some sort -- %d\n");
break; // add an error
}
}
}

return;
}
 
J

Joshua Lehrer

Slowly embracing C++ and as such I've got C code (see snippet below)
I'd like to essentially port to C++. The idea is to

1. Use a TEMPLATE class to handle the 'double' buffering scheme
outlined in the code. Perhaps an operator= approach would be ideal.
I've looked at benchmarks per these newsgroups on std::copy and
realize it's too slow when compared to memcopy.

And memcpy is too dangerous when compared to std::copy.

The solution we selected on our system was to specialize the
implementation of std::copy when it could determine, at compile time,
that it was safe to call memcpy instead of inlining the code itself.
We did the same thing with std::fill and memset. Memset/memcpy=evil.

our copy uses memcpy when both iterators are pointers, both pointer's
non-cv qualified value_types are the same, and the non-cv qualified
value_type is a builtin type.

-joshua lehrer
factset research systems
NYSE:FDS
 
B

Balog Pal

And memcpy is too dangerous when compared to std::copy.

Could you elaborate this? How is copy more or less dangerous when applied
to raw storage as presented here?
We did the same thing with std::fill and memset. Memset/memcpy=evil.

Because?

Paul
 
G

Glen Low

The solution we selected on our system was to specialize the
implementation of std::copy when it could determine, at compile time,
that it was safe to call memcpy instead of inlining the code itself.
We did the same thing with std::fill and memset. Memset/memcpy=evil.

our copy uses memcpy when both iterators are pointers, both pointer's
non-cv qualified value_types are the same, and the non-cv qualified
value_type is a builtin type.

Hmm? Most good Standard C++ Library implementations already do this
e.g. libstdc++ for gcc. That way you get the best of both worlds
through std::copy -- (1) the correct code when it's not optimizable,
and (2) fast code through its use of memcpy when it is optimizable.

In theory you could expand that last constraint to types with trivial
copy constructors. (Actually we could get more general than that,
since some user declared copy constructors are in fact nothing more
than memcpy in disguise.)

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top