Skip to content

Commit 243d973

Browse files
committed
Merge pull request #1316 from hjelmn/datatype_pack_threads
ompi/datatype: make datatype pack thread safe
2 parents 0fe4818 + b921831 commit 243d973

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

ompi/datatype/ompi_datatype_args.c

+38-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Copyright (c) 2004-2006 The Regents of the University of California.
1212
* All rights reserved.
1313
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
14-
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights
14+
* Copyright (c) 2013-2016 Los Alamos National Security, LLC. All rights
1515
* reserved.
1616
* Copyright (c) 2015 Research Organization for Information Science
1717
* and Technology (RIST). All rights reserved.
@@ -481,39 +481,63 @@ int ompi_datatype_get_pack_description( ompi_datatype_t* datatype,
481481
{
482482
ompi_datatype_args_t* args = (ompi_datatype_args_t*)datatype->args;
483483
int next_index = OMPI_DATATYPE_MAX_PREDEFINED;
484+
void *packed_description = datatype->packed_description;
484485
void* recursive_buffer;
485486

486-
if( NULL == datatype->packed_description ) {
487-
if( ompi_datatype_is_predefined(datatype) ) {
488-
datatype->packed_description = malloc(2 * sizeof(int));
489-
} else if( NULL == args ) {
490-
return OMPI_ERROR;
487+
if (NULL == packed_description) {
488+
if (opal_atomic_cmpset (&datatype->packed_description, NULL, (void *) 1)) {
489+
if( ompi_datatype_is_predefined(datatype) ) {
490+
packed_description = malloc(2 * sizeof(int));
491+
} else if( NULL == args ) {
492+
return OMPI_ERROR;
493+
} else {
494+
packed_description = malloc(args->total_pack_size);
495+
}
496+
recursive_buffer = packed_description;
497+
__ompi_datatype_pack_description( datatype, &recursive_buffer, &next_index );
498+
499+
if (!ompi_datatype_is_predefined(datatype)) {
500+
args->total_pack_size = (uintptr_t)((char*)recursive_buffer - (char *) packed_description);
501+
}
502+
503+
opal_atomic_wmb ();
504+
datatype->packed_description = packed_description;
491505
} else {
492-
datatype->packed_description = malloc(args->total_pack_size);
506+
/* another thread beat us to it */
507+
packed_description = datatype->packed_description;
493508
}
494-
recursive_buffer = datatype->packed_description;
495-
__ompi_datatype_pack_description( datatype, &recursive_buffer, &next_index );
496-
if( !ompi_datatype_is_predefined(datatype) ) {
497-
args->total_pack_size = (uintptr_t)((char*)recursive_buffer - (char*)datatype->packed_description);
509+
}
510+
511+
if ((void *) 1 == packed_description) {
512+
struct timespec interval = {.tv_sec = 0, .tv_nsec = 1000};
513+
514+
/* wait until the packed description is updated */
515+
while ((void *) 1 == datatype->packed_description) {
516+
nanosleep (&interval, NULL);
498517
}
518+
519+
packed_description = datatype->packed_description;
499520
}
500521

501-
*packed_buffer = (const void*)datatype->packed_description;
522+
*packed_buffer = (const void *) packed_description;
502523
return OMPI_SUCCESS;
503524
}
504525

505526
size_t ompi_datatype_pack_description_length( ompi_datatype_t* datatype )
506527
{
528+
void *packed_description = datatype->packed_description;
529+
507530
if( ompi_datatype_is_predefined(datatype) ) {
508531
return 2 * sizeof(int);
509532
}
510-
if( NULL == datatype->packed_description ) {
533+
if( NULL == packed_description || (void *) 1 == packed_description) {
511534
const void* buf;
512535
int rc;
513536

514537
rc = ompi_datatype_get_pack_description(datatype, &buf);
515-
if( OMPI_SUCCESS != rc )
538+
if( OMPI_SUCCESS != rc ) {
516539
return 0;
540+
}
517541
}
518542
assert( NULL != (ompi_datatype_args_t*)datatype->args );
519543
assert( NULL != (ompi_datatype_args_t*)datatype->packed_description );

0 commit comments

Comments
 (0)