1
+ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
1
2
/*
2
3
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3
4
* University Research and Technology
14
15
* reserved.
15
16
* Copyright (c) 2017 Research Organization for Information Science
16
17
* and Technology (RIST). All rights reserved.
18
+ * Copyright (c) 2018-2021 Triad National Security, LLC. All rights
19
+ * reserved.
17
20
* $COPYRIGHT$
18
21
*
19
22
* Additional copyrights may follow
242
245
#include "ompi/win/win.h" /* ompi_win_t generated in [COPY|DELETE]_ATTR_CALLBACKS */
243
246
#include "ompi/mpi/fortran/base/fint_2_int.h"
244
247
248
+
245
249
/*
246
250
* Macros
247
251
*/
256
260
#define attr_datatype_f d_f_to_c_index
257
261
#define attr_win_f w_f_to_c_index
258
262
259
- #define CREATE_KEY (key ) opal_bitmap_find_and_set_first_unset_bit(key_bitmap, (key))
263
+ #define CREATE_KEY (key ) opal_bitmap_find_and_set_first_unset_bit(attr_subsys-> key_bitmap, (key))
260
264
261
- #define FREE_KEY (key ) opal_bitmap_clear_bit(key_bitmap, (key))
265
+ #define FREE_KEY (key ) opal_bitmap_clear_bit(attr_subsys-> key_bitmap, (key))
262
266
263
267
264
268
/* Not checking for NULL_DELETE_FN here, since according to the
@@ -406,13 +410,24 @@ typedef struct attribute_value_t {
406
410
int av_sequence ;
407
411
} attribute_value_t ;
408
412
413
+ /*
414
+ * struct to hold state of attr subsys
415
+ */
416
+
417
+ typedef struct attr_subsys_t {
418
+ opal_object_t super ;
419
+ opal_hash_table_t * keyval_hash ;
420
+ opal_bitmap_t * key_bitmap ;
421
+ } attr_subsys_t ;
409
422
410
423
/*
411
424
* Local functions
412
425
*/
413
426
static void attribute_value_construct (attribute_value_t * item );
414
427
static void ompi_attribute_keyval_construct (ompi_attribute_keyval_t * keyval );
415
428
static void ompi_attribute_keyval_destruct (ompi_attribute_keyval_t * keyval );
429
+ static void attr_subsys_construct (attr_subsys_t * subsys );
430
+ static void attr_subsys_destruct (attr_subsys_t * subsys );
416
431
static int set_value (ompi_attribute_type_t type , void * object ,
417
432
opal_hash_table_t * * attr_hash , int key ,
418
433
attribute_value_t * new_attr ,
@@ -425,6 +440,13 @@ static MPI_Aint translate_to_aint(attribute_value_t *val);
425
440
426
441
static int compare_attr_sequence (const void * attr1 , const void * attr2 );
427
442
443
+ /*
444
+ * attribute_subsys_t class
445
+ */
446
+ static OBJ_CLASS_INSTANCE (attr_subsys_t ,
447
+ opal_object_t ,
448
+ attr_subsys_construct ,
449
+ attr_subsys_destruct ) ;
428
450
429
451
/*
430
452
* attribute_value_t class
@@ -443,24 +465,31 @@ static OBJ_CLASS_INSTANCE(ompi_attribute_keyval_t,
443
465
ompi_attribute_keyval_construct ,
444
466
ompi_attribute_keyval_destruct ) ;
445
467
468
+ /*
469
+ * compatibility until sessions work is finished
470
+ */
471
+ static inline int ompi_mpi_instance_retain (void ) {
472
+ return OMPI_SUCCESS ;
473
+ }
474
+
475
+ static inline void ompi_mpi_instance_release (void ) {
476
+ }
446
477
447
478
/*
448
479
* Static variables
449
480
*/
450
481
451
- static opal_hash_table_t * keyval_hash ;
452
- static opal_bitmap_t * key_bitmap ;
453
- static int attr_sequence ;
482
+ static attr_subsys_t * attr_subsys = NULL ;
454
483
static unsigned int int_pos = 12345 ;
455
484
static unsigned int integer_pos = 12345 ;
485
+ static int attr_sequence ;
456
486
457
487
/*
458
488
* MPI attributes are *not* high performance, so just use a One Big Lock
459
489
* approach. However, this lock is released before a user provided callback is
460
490
* triggered and acquired right after, allowing for recursive behaviors.
461
491
*/
462
- static opal_mutex_t attribute_lock ;
463
-
492
+ static opal_mutex_t attribute_lock = OPAL_MUTEX_STATIC_INIT ;
464
493
465
494
/*
466
495
* attribute_value_t constructor function
@@ -507,33 +536,68 @@ ompi_attribute_keyval_destruct(ompi_attribute_keyval_t *keyval)
507
536
free (keyval -> bindings_extra_state );
508
537
}
509
538
510
- opal_hash_table_remove_value_uint32 (keyval_hash , keyval -> key );
539
+ opal_hash_table_remove_value_uint32 (attr_subsys -> keyval_hash , keyval -> key );
511
540
FREE_KEY (keyval -> key );
512
541
}
513
542
}
514
543
515
544
516
- /*
517
- * This will initialize the main list to store key- attribute
518
- * items. This will be called one time, during MPI_INIT().
519
- */
520
- int ompi_attr_init (void )
545
+ int ompi_attr_get_ref (void )
546
+ {
547
+ int ret = OMPI_SUCCESS ;
548
+
549
+ OPAL_THREAD_LOCK (& attribute_lock );
550
+
551
+ if (NULL == attr_subsys ) {
552
+ attr_subsys = OBJ_NEW (attr_subsys_t );
553
+ if (NULL == attr_subsys ) {
554
+ ret = OMPI_ERR_OUT_OF_RESOURCE ;
555
+ goto fn_exit ;
556
+ }
557
+ if ((NULL == attr_subsys -> keyval_hash ) || (NULL == attr_subsys -> key_bitmap )) {
558
+ OBJ_RELEASE (attr_subsys );
559
+ attr_subsys = NULL ;
560
+ ret = OMPI_ERR_OUT_OF_RESOURCE ;
561
+ goto fn_exit ;
562
+ }
563
+ } else {
564
+ OBJ_RETAIN (attr_subsys );
565
+ }
566
+
567
+ fn_exit :
568
+ OPAL_THREAD_UNLOCK (& attribute_lock );
569
+
570
+ return ret ;
571
+ }
572
+
573
+ int ompi_attr_put_ref (void )
574
+ {
575
+ if (NULL != attr_subsys ) {
576
+ OBJ_RELEASE (attr_subsys );
577
+ }
578
+ return OMPI_SUCCESS ;
579
+ }
580
+
581
+ static void attr_subsys_construct (attr_subsys_t * subsys )
521
582
{
522
583
int ret ;
523
584
void * bogus = (void * ) 1 ;
524
585
int * p = (int * ) & bogus ;
525
586
526
- keyval_hash = OBJ_NEW (opal_hash_table_t );
527
- if (NULL == keyval_hash ) {
528
- return OMPI_ERR_OUT_OF_RESOURCE ;
529
- }
530
- key_bitmap = OBJ_NEW (opal_bitmap_t );
587
+ subsys -> keyval_hash = OBJ_NEW (opal_hash_table_t );
588
+
589
+ subsys -> key_bitmap = OBJ_NEW (opal_bitmap_t );
590
+
531
591
/*
532
592
* Set the max size to OMPI_FORTRAN_HANDLE_MAX to enforce bound
533
593
*/
534
- opal_bitmap_set_max_size (key_bitmap , OMPI_FORTRAN_HANDLE_MAX );
535
- if (0 != opal_bitmap_init (key_bitmap , 32 )) {
536
- return OMPI_ERR_OUT_OF_RESOURCE ;
594
+ opal_bitmap_set_max_size (subsys -> key_bitmap ,
595
+ OMPI_FORTRAN_HANDLE_MAX );
596
+ ret = opal_bitmap_init (subsys -> key_bitmap , 32 );
597
+ assert (OPAL_SUCCESS == ret );
598
+
599
+ for (int i = 0 ; i < MPI_ATTR_PREDEFINED_KEY_MAX ; i ++ ) {
600
+ opal_bitmap_set_bit (subsys -> key_bitmap , i );
537
601
}
538
602
539
603
for (int_pos = 0 ; int_pos < (sizeof (void * ) / sizeof (int ));
@@ -550,31 +614,21 @@ int ompi_attr_init(void)
550
614
}
551
615
}
552
616
553
- OBJ_CONSTRUCT (& attribute_lock , opal_mutex_t );
554
-
555
- if (OMPI_SUCCESS != (ret = opal_hash_table_init (keyval_hash ,
556
- ATTR_TABLE_SIZE ))) {
557
- return ret ;
558
- }
559
- if (OMPI_SUCCESS != (ret = ompi_attr_create_predefined ())) {
560
- return ret ;
561
- }
617
+ ret = opal_hash_table_init (subsys -> keyval_hash , ATTR_TABLE_SIZE );
618
+ assert (OPAL_SUCCESS == ret );
562
619
563
- return OMPI_SUCCESS ;
620
+ attr_sequence = 0 ;
564
621
}
565
622
566
623
567
624
/*
568
- * Cleanup everything during MPI_Finalize().
625
+ * Cleanup everything when no more refs to the attr subsys
569
626
*/
570
- int ompi_attr_finalize ( void )
627
+ static void attr_subsys_destruct ( attr_subsys_t * subsys )
571
628
{
572
629
ompi_attr_free_predefined ();
573
- OBJ_DESTRUCT (& attribute_lock );
574
- OBJ_RELEASE (keyval_hash );
575
- OBJ_RELEASE (key_bitmap );
576
-
577
- return OMPI_SUCCESS ;
630
+ OBJ_RELEASE (subsys -> keyval_hash );
631
+ OBJ_RELEASE (subsys -> key_bitmap );
578
632
}
579
633
580
634
/*****************************************************************************/
@@ -609,10 +663,15 @@ static int ompi_attr_create_keyval_impl(ompi_attribute_type_t type,
609
663
610
664
/* Create a new unique key and fill the hash */
611
665
OPAL_THREAD_LOCK (& attribute_lock );
612
- ret = CREATE_KEY (key );
666
+ ret = MPI_SUCCESS ;
667
+ if (!(flags & OMPI_KEYVAL_PREDEFINED )) {
668
+ ret = CREATE_KEY (key );
669
+ }
670
+
613
671
if (OMPI_SUCCESS == ret ) {
614
672
keyval -> key = * key ;
615
- ret = opal_hash_table_set_value_uint32 (keyval_hash , * key , keyval );
673
+ ret = opal_hash_table_set_value_uint32 (attr_subsys -> keyval_hash ,
674
+ * key , keyval );
616
675
}
617
676
618
677
if (OMPI_SUCCESS != ret ) {
@@ -635,11 +694,22 @@ int ompi_attr_create_keyval(ompi_attribute_type_t type,
635
694
void * bindings_extra_state )
636
695
{
637
696
ompi_attribute_fortran_ptr_t es_tmp ;
697
+ int rc ;
698
+
699
+ rc = ompi_mpi_instance_retain ();
700
+ if (OPAL_UNLIKELY (OMPI_SUCCESS != rc )) {
701
+ return rc ;
702
+ }
638
703
639
704
es_tmp .c_ptr = extra_state ;
640
- return ompi_attr_create_keyval_impl (type , copy_attr_fn , delete_attr_fn ,
641
- key , & es_tmp , flags ,
642
- bindings_extra_state );
705
+ rc = ompi_attr_create_keyval_impl (type , copy_attr_fn , delete_attr_fn ,
706
+ key , & es_tmp , flags ,
707
+ bindings_extra_state );
708
+ if (OPAL_UNLIKELY (OMPI_SUCCESS != rc )) {
709
+ ompi_mpi_instance_release ();
710
+ }
711
+
712
+ return rc ;
643
713
}
644
714
645
715
int ompi_attr_create_keyval_fint (ompi_attribute_type_t type ,
@@ -651,6 +721,12 @@ int ompi_attr_create_keyval_fint(ompi_attribute_type_t type,
651
721
void * bindings_extra_state )
652
722
{
653
723
ompi_attribute_fortran_ptr_t es_tmp ;
724
+ int rc ;
725
+
726
+ rc = ompi_mpi_instance_retain ();
727
+ if (OPAL_UNLIKELY (OMPI_SUCCESS != rc )) {
728
+ return rc ;
729
+ }
654
730
655
731
es_tmp .f_integer = extra_state ;
656
732
#if SIZEOF_INT == OMPI_SIZEOF_FORTRAN_INTEGER
@@ -670,6 +746,12 @@ int ompi_attr_create_keyval_aint(ompi_attribute_type_t type,
670
746
void * bindings_extra_state )
671
747
{
672
748
ompi_attribute_fortran_ptr_t es_tmp ;
749
+ int rc ;
750
+
751
+ rc = ompi_mpi_instance_retain ();
752
+ if (OPAL_UNLIKELY (OMPI_SUCCESS != rc )) {
753
+ return rc ;
754
+ }
673
755
674
756
es_tmp .f_address = extra_state ;
675
757
return ompi_attr_create_keyval_impl (type , copy_attr_fn , delete_attr_fn ,
@@ -687,7 +769,7 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
687
769
688
770
/* Find the key-value pair */
689
771
OPAL_THREAD_LOCK (& attribute_lock );
690
- ret = opal_hash_table_get_value_uint32 (keyval_hash , * key ,
772
+ ret = opal_hash_table_get_value_uint32 (attr_subsys -> keyval_hash , * key ,
691
773
(void * * ) & keyval );
692
774
if ((OMPI_SUCCESS != ret ) || (NULL == keyval ) ||
693
775
(keyval -> attr_type != type ) ||
@@ -707,6 +789,9 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
707
789
opal_atomic_wmb ();
708
790
OPAL_THREAD_UNLOCK (& attribute_lock );
709
791
792
+ /* balance out retain in keyval_create */
793
+ ompi_mpi_instance_release ();
794
+
710
795
return MPI_SUCCESS ;
711
796
}
712
797
@@ -720,7 +805,7 @@ int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
720
805
opal_hash_table_t * * attr_hash ,
721
806
int key , void * attribute , bool predefined )
722
807
{
723
- int ret ;
808
+ int ret = MPI_SUCCESS ;
724
809
attribute_value_t * new_attr = OBJ_NEW (attribute_value_t );
725
810
if (NULL == new_attr ) {
726
811
return OMPI_ERR_OUT_OF_RESOURCE ;
@@ -942,7 +1027,7 @@ int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
942
1027
943
1028
/* Get the keyval in the main keyval hash - so that we know
944
1029
what the copy_attr_fn is */
945
- err = opal_hash_table_get_value_uint32 (keyval_hash , key ,
1030
+ err = opal_hash_table_get_value_uint32 (attr_subsys -> keyval_hash , key ,
946
1031
(void * * ) & hash_value );
947
1032
if (OMPI_SUCCESS != err ) {
948
1033
/* This should not happen! */
@@ -1037,7 +1122,7 @@ static int ompi_attr_delete_impl(ompi_attribute_type_t type, void *object,
1037
1122
attribute_value_t * attr ;
1038
1123
1039
1124
/* Check if the key is valid in the master keyval hash */
1040
- ret = opal_hash_table_get_value_uint32 (keyval_hash , key ,
1125
+ ret = opal_hash_table_get_value_uint32 (attr_subsys -> keyval_hash , key ,
1041
1126
(void * * ) & keyval );
1042
1127
1043
1128
if ((OMPI_SUCCESS != ret ) || (NULL == keyval ) ||
@@ -1053,7 +1138,7 @@ static int ompi_attr_delete_impl(ompi_attribute_type_t type, void *object,
1053
1138
goto exit ;
1054
1139
}
1055
1140
1056
- /* Check if the key is valid for the communicator/window/dtype. If
1141
+ /* Check if the key is valid for the communicator/window/dtype/instance . If
1057
1142
yes, then delete the attribute and key entry from the object's
1058
1143
hash */
1059
1144
ret = opal_hash_table_get_value_uint32 (attr_hash , key , (void * * ) & attr );
@@ -1198,7 +1283,7 @@ static int set_value(ompi_attribute_type_t type, void *object,
1198
1283
/* Note that this function can be invoked by ompi_attr_copy_all()
1199
1284
to set attributes on the new object (in addition to the
1200
1285
top-level MPI_* functions that set attributes). */
1201
- ret = opal_hash_table_get_value_uint32 (keyval_hash , key ,
1286
+ ret = opal_hash_table_get_value_uint32 (attr_subsys -> keyval_hash , key ,
1202
1287
(void * * ) & keyval );
1203
1288
1204
1289
/* If key not found */
@@ -1242,7 +1327,7 @@ static int set_value(ompi_attribute_type_t type, void *object,
1242
1327
had_old = true;
1243
1328
}
1244
1329
1245
- ret = opal_hash_table_get_value_uint32 (keyval_hash , key ,
1330
+ ret = opal_hash_table_get_value_uint32 (attr_subsys -> keyval_hash , key ,
1246
1331
(void * * ) & keyval );
1247
1332
if ((OMPI_SUCCESS != ret ) || (NULL == keyval )) {
1248
1333
/* Keyval has disappeared underneath us -- this shouldn't
@@ -1288,7 +1373,7 @@ static int get_value(opal_hash_table_t *attr_hash, int key,
1288
1373
with the key, then the call is valid and returns FALSE in the
1289
1374
flag argument */
1290
1375
* flag = 0 ;
1291
- ret = opal_hash_table_get_value_uint32 (keyval_hash , key ,
1376
+ ret = opal_hash_table_get_value_uint32 (attr_subsys -> keyval_hash , key ,
1292
1377
(void * * ) & keyval );
1293
1378
if (OMPI_ERR_NOT_FOUND == ret ) {
1294
1379
return MPI_KEYVAL_INVALID ;
0 commit comments