From 3460631fe085a663dcc17ba49688e79a7d3eae6e Mon Sep 17 00:00:00 2001 From: George Bosilca Date: Fri, 18 Nov 2011 04:28:14 +0000 Subject: [PATCH] Fix an issue with the datatype engine where if the left over from the previous pack was larger than the allowed space in the pack buffer bad things happened. Thanks to Yuki MATSUMOTO and Takahiro Kawashima for the bug report and the patch. This commit was SVN r25488. --- opal/datatype/opal_datatype_pack.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/opal/datatype/opal_datatype_pack.c b/opal/datatype/opal_datatype_pack.c index 63ddfbb57b..e572019bc5 100644 --- a/opal/datatype/opal_datatype_pack.c +++ b/opal/datatype/opal_datatype_pack.c @@ -3,7 +3,7 @@ * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. - * Copyright (c) 2004-2009 The University of Tennessee and The University + * Copyright (c) 2004-2011 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart, @@ -194,7 +194,9 @@ opal_pack_homogeneous_contig_with_gaps_function( opal_convertor_t* pConv, packed_buffer = (unsigned char *) iov[iov_count].iov_base; done = pConv->bConverted - i * pData->size; /* partial data from last pack */ - if( done != 0 ) { /* still some data to copy from the last time */ + /* data left from last round and enough space in the buffer */ + if( (done + max_allowed) >= pData->size ) { + /* copy the partial left-over from the previous round */ done = pData->size - done; OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, done, pConv->pBaseBuf, pData, pConv->count ); MEMCPY_CSUM( packed_buffer, user_memory, done, pConv ); @@ -202,18 +204,20 @@ opal_pack_homogeneous_contig_with_gaps_function( opal_convertor_t* pConv, max_allowed -= done; total_bytes_converted += done; user_memory += (extent - pData->size + done); + + /* copy entire types */ + counter = (uint32_t)(max_allowed / pData->size); + if( counter > pConv->count ) counter = pConv->count; + for( i = 0; i < counter; i++ ) { + OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, pData->size, pConv->pBaseBuf, pData, pConv->count ); + MEMCPY_CSUM( packed_buffer, user_memory, pData->size, pConv ); + packed_buffer+= pData->size; + user_memory += extent; + } + done = (counter * pData->size); + max_allowed -= done; + total_bytes_converted += done; } - counter = (uint32_t)(max_allowed / pData->size); - if( counter > pConv->count ) counter = pConv->count; - for( i = 0; i < counter; i++ ) { - OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, pData->size, pConv->pBaseBuf, pData, pConv->count ); - MEMCPY_CSUM( packed_buffer, user_memory, pData->size, pConv ); - packed_buffer+= pData->size; - user_memory += extent; - } - done = (counter * pData->size); - max_allowed -= done; - total_bytes_converted += done; /* If there is anything pending ... */ if( 0 != max_allowed ) { done = max_allowed;