Skip to content

Commit b8de755

Browse files
committed
ompi/datatype: make datatype pack thread safe
This commit makes ompi_datatype_get_pack_description thread safe. The call is used by osc/pt2pt to send the packed description to remote peers. Before this commit if MPI_THREAD_MULTIPLE is enabled and the user uses MPI_Put, MPI_Get, etc we could hit a race where multiple threads attempt to store the packed description on the datatype. Since the code in question is not performance-critical the threading fix uses opal_atomic_* calls instead of bothering with OPAL_THREAD_*. Signed-off-by: Nathan Hjelm <[email protected]>
1 parent ae3df29 commit b8de755

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

ompi/datatype/ompi_datatype_args.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -484,17 +484,34 @@ int ompi_datatype_get_pack_description( ompi_datatype_t* datatype,
484484
void* recursive_buffer;
485485

486486
if( NULL == datatype->packed_description ) {
487+
void *packed_description;
488+
487489
if( ompi_datatype_is_predefined(datatype) ) {
488-
datatype->packed_description = malloc(2 * sizeof(int));
490+
packed_description = malloc(2 * sizeof(int));
489491
} else if( NULL == args ) {
490492
return OMPI_ERROR;
491493
} else {
492-
datatype->packed_description = malloc(args->total_pack_size);
494+
packed_description = malloc(args->total_pack_size);
493495
}
494-
recursive_buffer = datatype->packed_description;
496+
recursive_buffer = packed_description;
495497
__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);
498+
499+
if (opal_atomic_cmpset (&datatype->packed_description, NULL, packed_description)) {
500+
opal_atomic_wmb ();
501+
if( !ompi_datatype_is_predefined(datatype) ) {
502+
args->total_pack_size = (uintptr_t)((char*)recursive_buffer - (char*)datatype->packed_description);
503+
}
504+
} else {
505+
/* another thread beat us to it */
506+
free (packed_description);
507+
}
508+
}
509+
510+
if (!ompi_datatype_is_predefined(datatype)) {
511+
/* spin until the pack size is updated */
512+
while (0 == args->total_pack_size) {
513+
struct timespec interval = {.tv_sec = 0, .tv_nsec = 1000};
514+
nanosleep (&interval, NULL);
498515
}
499516
}
500517

0 commit comments

Comments
 (0)