This source file includes following definitions.
- attribute_value_construct
- ompi_attribute_keyval_construct
- ompi_attribute_keyval_destruct
- ompi_attr_init
- ompi_attr_finalize
- ompi_attr_create_keyval_impl
- ompi_attr_create_keyval
- ompi_attr_create_keyval_fint
- ompi_attr_create_keyval_aint
- ompi_attr_free_keyval
- ompi_attr_set_c
- ompi_attr_set_int
- ompi_attr_set_fint
- ompi_attr_set_aint
- ompi_attr_get_c
- ompi_attr_get_fint
- ompi_attr_get_aint
- ompi_attr_copy_all
- ompi_attr_delete_impl
- ompi_attr_delete
- ompi_attr_delete_all
- set_value
- get_value
- translate_to_c
- translate_to_fint
- translate_to_aint
- compare_attr_sequence
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 #include "ompi_config.h"
233
234 #include "opal/class/opal_bitmap.h"
235 #include "opal/threads/mutex.h"
236 #include "opal/sys/atomic.h"
237
238 #include "ompi/attribute/attribute.h"
239 #include "ompi/constants.h"
240 #include "ompi/datatype/ompi_datatype.h"
241 #include "ompi/communicator/communicator.h"
242 #include "ompi/win/win.h"
243 #include "ompi/mpi/fortran/base/fint_2_int.h"
244
245
246
247
248
249 #define ATTR_TABLE_SIZE 10
250
251
252
253
254 #define MPI_DATATYPE_NULL_COPY_FN MPI_TYPE_NULL_COPY_FN
255 #define attr_communicator_f c_f_to_c_index
256 #define attr_datatype_f d_f_to_c_index
257 #define attr_win_f w_f_to_c_index
258
259 #define CREATE_KEY(key) opal_bitmap_find_and_set_first_unset_bit(key_bitmap, (key))
260
261 #define FREE_KEY(key) opal_bitmap_clear_bit(key_bitmap, (key))
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 #define DELETE_ATTR_CALLBACKS(type, attribute, keyval_obj, object, err) \
287 do { \
288 OPAL_THREAD_UNLOCK(&attribute_lock); \
289 if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \
290 MPI_Fint f_key = OMPI_INT_2_FINT(key); \
291 MPI_Fint f_err; \
292 MPI_Fint attr_##type##_f; \
293 attr_##type##_f = OMPI_INT_2_FINT(((ompi_##type##_t *)keyval_obj)->attr_##type##_f); \
294 \
295 if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77_INT)) { \
296 MPI_Fint attr_val = translate_to_fint(attribute); \
297 (*((keyval_obj->delete_attr_fn).attr_fint_delete_fn)) \
298 (&attr_##type##_f, \
299 &f_key, &attr_val, &keyval_obj->extra_state.f_integer, &f_err); \
300 if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
301 err = OMPI_FINT_2_INT(f_err); \
302 } \
303 } \
304 \
305 else { \
306 MPI_Aint attr_val = translate_to_aint(attribute); \
307 (*((keyval_obj->delete_attr_fn).attr_aint_delete_fn)) \
308 (&attr_##type##_f, \
309 &f_key, (int*)&attr_val, &keyval_obj->extra_state.f_address, &f_err); \
310 if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
311 err = OMPI_FINT_2_INT(f_err); \
312 } \
313 } \
314 } \
315 \
316 else { \
317 void *attr_val = translate_to_c(attribute); \
318 err = (*((keyval_obj->delete_attr_fn).attr_##type##_delete_fn)) \
319 ((ompi_##type##_t *)object, \
320 key, attr_val, \
321 keyval_obj->extra_state.c_ptr); \
322 } \
323 OPAL_THREAD_LOCK(&attribute_lock); \
324 } while (0)
325
326
327
328
329 #define COPY_ATTR_CALLBACKS(type, old_object, keyval_obj, in_attr, new_object, out_attr, err) \
330 do { \
331 OPAL_THREAD_UNLOCK(&attribute_lock); \
332 if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \
333 MPI_Fint f_key = OMPI_INT_2_FINT(key); \
334 MPI_Fint f_err; \
335 ompi_fortran_logical_t f_flag; \
336 \
337 if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77_INT)) { \
338 MPI_Fint in, out; \
339 MPI_Fint attr_##type##_f; \
340 in = translate_to_fint(in_attr); \
341 attr_##type##_f = OMPI_INT_2_FINT(((ompi_##type##_t *)old_object)->attr_##type##_f); \
342 (*((keyval_obj->copy_attr_fn).attr_fint_copy_fn)) \
343 (&attr_##type##_f, \
344 &f_key, &keyval_obj->extra_state.f_integer, \
345 &in, &out, &f_flag, &f_err); \
346 if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
347 err = OMPI_FINT_2_INT(f_err); \
348 } else { \
349 out_attr->av_value = (void*) 0; \
350 *out_attr->av_fint_pointer = out; \
351 flag = OMPI_LOGICAL_2_INT(f_flag); \
352 } \
353 } \
354 \
355 else { \
356 MPI_Aint in, out; \
357 MPI_Fint attr_##type##_f; \
358 in = translate_to_aint(in_attr); \
359 attr_##type##_f = OMPI_INT_2_FINT(((ompi_##type##_t *)old_object)->attr_##type##_f); \
360 (*((keyval_obj->copy_attr_fn).attr_aint_copy_fn)) \
361 (&attr_##type##_f, \
362 &f_key, &keyval_obj->extra_state.f_address, &in, &out, \
363 &f_flag, &f_err); \
364 if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
365 err = OMPI_FINT_2_INT(f_err); \
366 } else { \
367 out_attr->av_value = (void *) out; \
368 flag = OMPI_LOGICAL_2_INT(f_flag); \
369 } \
370 } \
371 } \
372 \
373 else { \
374 void *in, *out; \
375 in = translate_to_c(in_attr); \
376 if ((err = (*((keyval_obj->copy_attr_fn).attr_##type##_copy_fn)) \
377 ((ompi_##type##_t *)old_object, key, keyval_obj->extra_state.c_ptr, \
378 in, &out, &flag, (ompi_##type##_t *)(new_object))) == MPI_SUCCESS) { \
379 out_attr->av_value = out; \
380 } \
381 } \
382 OPAL_THREAD_LOCK(&attribute_lock); \
383 } while (0)
384
385
386
387
388 typedef enum ompi_attribute_translate_t {
389 OMPI_ATTRIBUTE_C,
390 OMPI_ATTRIBUTE_INT,
391 OMPI_ATTRIBUTE_FINT,
392 OMPI_ATTRIBUTE_AINT
393 } ompi_attribute_translate_t;
394
395
396
397
398 typedef struct attribute_value_t {
399 opal_object_t super;
400 int av_key;
401 void *av_value;
402 int *av_int_pointer;
403 MPI_Fint *av_fint_pointer;
404 MPI_Aint *av_aint_pointer;
405 int av_set_from;
406 int av_sequence;
407 } attribute_value_t;
408
409
410
411
412
413 static void attribute_value_construct(attribute_value_t *item);
414 static void ompi_attribute_keyval_construct(ompi_attribute_keyval_t *keyval);
415 static void ompi_attribute_keyval_destruct(ompi_attribute_keyval_t *keyval);
416 static int set_value(ompi_attribute_type_t type, void *object,
417 opal_hash_table_t **attr_hash, int key,
418 attribute_value_t *new_attr,
419 bool predefined);
420 static int get_value(opal_hash_table_t *attr_hash, int key,
421 attribute_value_t **attribute, int *flag);
422 static void *translate_to_c(attribute_value_t *val);
423 static MPI_Fint translate_to_fint(attribute_value_t *val);
424 static MPI_Aint translate_to_aint(attribute_value_t *val);
425
426 static int compare_attr_sequence(const void *attr1, const void *attr2);
427
428
429
430
431
432 static OBJ_CLASS_INSTANCE(attribute_value_t,
433 opal_object_t,
434 attribute_value_construct,
435 NULL);
436
437
438
439
440
441 static OBJ_CLASS_INSTANCE(ompi_attribute_keyval_t,
442 opal_object_t,
443 ompi_attribute_keyval_construct,
444 ompi_attribute_keyval_destruct);
445
446
447
448
449
450
451 static opal_hash_table_t *keyval_hash;
452 static opal_bitmap_t *key_bitmap;
453 static int attr_sequence;
454 static unsigned int int_pos = 12345;
455 static unsigned int integer_pos = 12345;
456
457
458
459
460
461
462 static opal_mutex_t attribute_lock;
463
464
465
466
467
468 static void attribute_value_construct(attribute_value_t *item)
469 {
470 item->av_key = MPI_KEYVAL_INVALID;
471 item->av_aint_pointer = (MPI_Aint*) &item->av_value;
472 item->av_int_pointer = (int *)&item->av_value + int_pos;
473 item->av_fint_pointer = (MPI_Fint *)&item->av_value + integer_pos;
474 item->av_set_from = 0;
475 item->av_sequence = -1;
476 }
477
478
479
480
481
482 static void
483 ompi_attribute_keyval_construct(ompi_attribute_keyval_t *keyval)
484 {
485 keyval->attr_type = UNUSED_ATTR;
486 keyval->attr_flag = 0;
487 keyval->copy_attr_fn.attr_communicator_copy_fn = NULL;
488 keyval->delete_attr_fn.attr_communicator_copy_fn = NULL;
489 keyval->extra_state.c_ptr = NULL;
490 keyval->bindings_extra_state = NULL;
491
492
493
494
495
496
497 keyval->key = -1;
498 }
499
500
501 static void
502 ompi_attribute_keyval_destruct(ompi_attribute_keyval_t *keyval)
503 {
504 if (-1 != keyval->key) {
505
506 if (NULL != keyval->bindings_extra_state) {
507 free(keyval->bindings_extra_state);
508 }
509
510 opal_hash_table_remove_value_uint32(keyval_hash, keyval->key);
511 FREE_KEY(keyval->key);
512 }
513 }
514
515
516
517
518
519
520 int ompi_attr_init(void)
521 {
522 int ret;
523 void *bogus = (void*) 1;
524 int *p = (int *) &bogus;
525
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);
531
532
533
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;
537 }
538
539 for (int_pos = 0; int_pos < (sizeof(void*) / sizeof(int));
540 ++int_pos) {
541 if (p[int_pos] == 1) {
542 break;
543 }
544 }
545
546 for (integer_pos = 0; integer_pos < (sizeof(void*) / sizeof(MPI_Fint));
547 ++integer_pos) {
548 if (p[integer_pos] == 1) {
549 break;
550 }
551 }
552
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 }
562
563 return OMPI_SUCCESS;
564 }
565
566
567
568
569
570 int ompi_attr_finalize(void)
571 {
572 ompi_attr_free_predefined();
573 OBJ_DESTRUCT(&attribute_lock);
574 OBJ_RELEASE(keyval_hash);
575 OBJ_RELEASE(key_bitmap);
576
577 return OMPI_SUCCESS;
578 }
579
580
581
582 static int ompi_attr_create_keyval_impl(ompi_attribute_type_t type,
583 ompi_attribute_fn_ptr_union_t copy_attr_fn,
584 ompi_attribute_fn_ptr_union_t delete_attr_fn,
585 int *key,
586 ompi_attribute_fortran_ptr_t *extra_state,
587 int flags,
588 void *bindings_extra_state)
589 {
590 ompi_attribute_keyval_t *keyval;
591 int ret;
592
593
594 keyval = OBJ_NEW(ompi_attribute_keyval_t);
595 if (NULL == keyval) {
596 return OMPI_ERR_OUT_OF_RESOURCE;
597 }
598
599
600
601
602 keyval->copy_attr_fn = copy_attr_fn;
603 keyval->delete_attr_fn = delete_attr_fn;
604 keyval->extra_state = *extra_state;
605 keyval->attr_type = type;
606 keyval->attr_flag = flags;
607 keyval->key = -1;
608 keyval->bindings_extra_state = bindings_extra_state;
609
610
611 OPAL_THREAD_LOCK(&attribute_lock);
612 ret = CREATE_KEY(key);
613 if (OMPI_SUCCESS == ret) {
614 keyval->key = *key;
615 ret = opal_hash_table_set_value_uint32(keyval_hash, *key, keyval);
616 }
617
618 if (OMPI_SUCCESS != ret) {
619 OBJ_RELEASE(keyval);
620 } else {
621 ret = MPI_SUCCESS;
622 }
623
624 opal_atomic_wmb();
625 OPAL_THREAD_UNLOCK(&attribute_lock);
626 return ret;
627 }
628
629 int ompi_attr_create_keyval(ompi_attribute_type_t type,
630 ompi_attribute_fn_ptr_union_t copy_attr_fn,
631 ompi_attribute_fn_ptr_union_t delete_attr_fn,
632 int *key,
633 void *extra_state,
634 int flags,
635 void *bindings_extra_state)
636 {
637 ompi_attribute_fortran_ptr_t es_tmp;
638
639 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);
643 }
644
645 int ompi_attr_create_keyval_fint(ompi_attribute_type_t type,
646 ompi_attribute_fn_ptr_union_t copy_attr_fn,
647 ompi_attribute_fn_ptr_union_t delete_attr_fn,
648 int *key,
649 MPI_Fint extra_state,
650 int flags,
651 void *bindings_extra_state)
652 {
653 ompi_attribute_fortran_ptr_t es_tmp;
654
655 es_tmp.f_integer = extra_state;
656 #if SIZEOF_INT == OMPI_SIZEOF_FORTRAN_INTEGER
657 flags |= OMPI_KEYVAL_F77_INT;
658 #endif
659 return ompi_attr_create_keyval_impl(type, copy_attr_fn, delete_attr_fn,
660 key, &es_tmp, flags,
661 bindings_extra_state);
662 }
663
664 int ompi_attr_create_keyval_aint(ompi_attribute_type_t type,
665 ompi_attribute_fn_ptr_union_t copy_attr_fn,
666 ompi_attribute_fn_ptr_union_t delete_attr_fn,
667 int *key,
668 MPI_Aint extra_state,
669 int flags,
670 void *bindings_extra_state)
671 {
672 ompi_attribute_fortran_ptr_t es_tmp;
673
674 es_tmp.f_address = extra_state;
675 return ompi_attr_create_keyval_impl(type, copy_attr_fn, delete_attr_fn,
676 key, &es_tmp, flags,
677 bindings_extra_state);
678 }
679
680
681
682 int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
683 bool predefined)
684 {
685 int ret;
686 ompi_attribute_keyval_t *keyval;
687
688
689 OPAL_THREAD_LOCK(&attribute_lock);
690 ret = opal_hash_table_get_value_uint32(keyval_hash, *key,
691 (void **) &keyval);
692 if ((OMPI_SUCCESS != ret) || (NULL == keyval) ||
693 (keyval->attr_type != type) ||
694 ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
695 OPAL_THREAD_UNLOCK(&attribute_lock);
696 return OMPI_ERR_BAD_PARAM;
697 }
698
699
700 *key = MPI_KEYVAL_INVALID;
701
702
703
704
705 OBJ_RELEASE(keyval);
706
707 opal_atomic_wmb();
708 OPAL_THREAD_UNLOCK(&attribute_lock);
709
710 return MPI_SUCCESS;
711 }
712
713
714
715
716
717
718
719 int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
720 opal_hash_table_t **attr_hash,
721 int key, void *attribute, bool predefined)
722 {
723 int ret;
724 attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
725 if (NULL == new_attr) {
726 return OMPI_ERR_OUT_OF_RESOURCE;
727 }
728
729 OPAL_THREAD_LOCK(&attribute_lock);
730
731 new_attr->av_value = attribute;
732 new_attr->av_set_from = OMPI_ATTRIBUTE_C;
733 ret = set_value(type, object, attr_hash, key, new_attr, predefined);
734 if (OMPI_SUCCESS != ret) {
735 OBJ_RELEASE(new_attr);
736 }
737
738 opal_atomic_wmb();
739 OPAL_THREAD_UNLOCK(&attribute_lock);
740
741 return ret;
742 }
743
744
745
746
747
748
749 int ompi_attr_set_int(ompi_attribute_type_t type, void *object,
750 opal_hash_table_t **attr_hash,
751 int key, int attribute, bool predefined)
752 {
753 int ret;
754 attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
755 if (NULL == new_attr) {
756 return OMPI_ERR_OUT_OF_RESOURCE;
757 }
758
759 OPAL_THREAD_LOCK(&attribute_lock);
760
761 new_attr->av_value = (void *) 0;
762 *new_attr->av_int_pointer = attribute;
763 new_attr->av_set_from = OMPI_ATTRIBUTE_INT;
764 ret = set_value(type, object, attr_hash, key, new_attr, predefined);
765 if (OMPI_SUCCESS != ret) {
766 OBJ_RELEASE(new_attr);
767 }
768
769 opal_atomic_wmb();
770 OPAL_THREAD_UNLOCK(&attribute_lock);
771
772 return ret;
773 }
774
775
776
777
778
779
780 int ompi_attr_set_fint(ompi_attribute_type_t type, void *object,
781 opal_hash_table_t **attr_hash,
782 int key, MPI_Fint attribute,
783 bool predefined)
784 {
785 int ret;
786 attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
787 if (NULL == new_attr) {
788 return OMPI_ERR_OUT_OF_RESOURCE;
789 }
790
791 OPAL_THREAD_LOCK(&attribute_lock);
792
793 new_attr->av_value = (void *) 0;
794 *new_attr->av_fint_pointer = attribute;
795 new_attr->av_set_from = OMPI_ATTRIBUTE_FINT;
796 ret = set_value(type, object, attr_hash, key, new_attr, predefined);
797 if (OMPI_SUCCESS != ret) {
798 OBJ_RELEASE(new_attr);
799 }
800
801 opal_atomic_wmb();
802 OPAL_THREAD_UNLOCK(&attribute_lock);
803
804 return ret;
805 }
806
807
808
809
810
811
812 int ompi_attr_set_aint(ompi_attribute_type_t type, void *object,
813 opal_hash_table_t **attr_hash,
814 int key, MPI_Aint attribute,
815 bool predefined)
816 {
817 int ret;
818 attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
819 if (NULL == new_attr) {
820 return OMPI_ERR_OUT_OF_RESOURCE;
821 }
822
823 OPAL_THREAD_LOCK(&attribute_lock);
824
825 new_attr->av_value = (void *) attribute;
826 new_attr->av_set_from = OMPI_ATTRIBUTE_AINT;
827 ret = set_value(type, object, attr_hash, key, new_attr, predefined);
828 if (OMPI_SUCCESS != ret) {
829 OBJ_RELEASE(new_attr);
830 }
831
832 opal_atomic_wmb();
833 OPAL_THREAD_UNLOCK(&attribute_lock);
834
835 return ret;
836 }
837
838
839
840
841
842
843
844 int ompi_attr_get_c(opal_hash_table_t *attr_hash, int key,
845 void **attribute, int *flag)
846 {
847 attribute_value_t *val = NULL;
848 int ret;
849
850 OPAL_THREAD_LOCK(&attribute_lock);
851
852 ret = get_value(attr_hash, key, &val, flag);
853 if (MPI_SUCCESS == ret && 1 == *flag) {
854 *attribute = translate_to_c(val);
855 }
856
857 opal_atomic_wmb();
858 OPAL_THREAD_UNLOCK(&attribute_lock);
859 return ret;
860 }
861
862
863
864
865
866
867 int ompi_attr_get_fint(opal_hash_table_t *attr_hash, int key,
868 MPI_Fint *attribute, int *flag)
869 {
870 attribute_value_t *val = NULL;
871 int ret;
872
873 OPAL_THREAD_LOCK(&attribute_lock);
874
875 ret = get_value(attr_hash, key, &val, flag);
876 if (MPI_SUCCESS == ret && 1 == *flag) {
877 *attribute = translate_to_fint(val);
878 }
879
880 opal_atomic_wmb();
881 OPAL_THREAD_UNLOCK(&attribute_lock);
882 return ret;
883 }
884
885
886
887
888
889
890 int ompi_attr_get_aint(opal_hash_table_t *attr_hash, int key,
891 MPI_Aint *attribute, int *flag)
892 {
893 attribute_value_t *val = NULL;
894 int ret;
895
896 OPAL_THREAD_LOCK(&attribute_lock);
897
898 ret = get_value(attr_hash, key, &val, flag);
899 if (MPI_SUCCESS == ret && 1 == *flag) {
900 *attribute = translate_to_aint(val);
901 }
902
903 opal_atomic_wmb();
904 OPAL_THREAD_UNLOCK(&attribute_lock);
905 return ret;
906 }
907
908
909
910
911
912
913
914
915 int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
916 void *new_object, opal_hash_table_t *oldattr_hash,
917 opal_hash_table_t *newattr_hash)
918 {
919 int ret;
920 int err;
921 uint32_t key;
922 int flag;
923 void *node, *in_node;
924 attribute_value_t *old_attr, *new_attr;
925 ompi_attribute_keyval_t *hash_value;
926
927
928 if (NULL == oldattr_hash) {
929 return MPI_SUCCESS;
930 }
931
932 OPAL_THREAD_LOCK(&attribute_lock);
933
934
935 ret = opal_hash_table_get_first_key_uint32(oldattr_hash, &key,
936 (void **) &old_attr,
937 &node);
938
939
940 while (OMPI_SUCCESS == ret) {
941 in_node = node;
942
943
944
945 err = opal_hash_table_get_value_uint32(keyval_hash, key,
946 (void **) &hash_value);
947 if (OMPI_SUCCESS != err) {
948
949 ret = MPI_ERR_INTERN;
950 goto out;
951 }
952
953 err = 0;
954 new_attr = OBJ_NEW(attribute_value_t);
955 switch (type) {
956 case COMM_ATTR:
957
958 COPY_ATTR_CALLBACKS(communicator, old_object, hash_value,
959 old_attr, new_object, new_attr, err);
960 break;
961
962 case TYPE_ATTR:
963
964 COPY_ATTR_CALLBACKS(datatype, old_object, hash_value,
965 old_attr, new_object, new_attr, err);
966 break;
967
968 case WIN_ATTR:
969
970 COPY_ATTR_CALLBACKS(win, old_object, hash_value,
971 old_attr, new_object, new_attr, err);
972 break;
973
974 default:
975
976 assert(0);
977 break;
978 }
979
980 if (0 != err) {
981 ret = err;
982 goto out;
983 }
984
985
986
987
988
989
990
991 if (1 == flag) {
992 if (0 != (hash_value->attr_flag & OMPI_KEYVAL_F77)) {
993 if (0 != (hash_value->attr_flag & OMPI_KEYVAL_F77_INT)) {
994 new_attr->av_set_from = OMPI_ATTRIBUTE_FINT;
995 } else {
996 new_attr->av_set_from = OMPI_ATTRIBUTE_AINT;
997 }
998 } else {
999 new_attr->av_set_from = OMPI_ATTRIBUTE_C;
1000 }
1001 ret = set_value(type, new_object, &newattr_hash, key,
1002 new_attr, true);
1003 if (MPI_SUCCESS != ret) {
1004 goto out;
1005 }
1006 } else {
1007 OBJ_RELEASE(new_attr);
1008 }
1009
1010 ret = opal_hash_table_get_next_key_uint32(oldattr_hash, &key,
1011 (void **) &old_attr,
1012 in_node, &node);
1013 }
1014 ret = MPI_SUCCESS;
1015
1016 out:
1017
1018 opal_atomic_wmb();
1019 OPAL_THREAD_UNLOCK(&attribute_lock);
1020 return ret;
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030 static int ompi_attr_delete_impl(ompi_attribute_type_t type, void *object,
1031 opal_hash_table_t *attr_hash, int key,
1032 bool predefined)
1033 {
1034 ompi_attribute_keyval_t *keyval;
1035 int ret = OMPI_SUCCESS;
1036 attribute_value_t *attr;
1037
1038
1039 ret = opal_hash_table_get_value_uint32(keyval_hash, key,
1040 (void **) &keyval);
1041
1042 if ((OMPI_SUCCESS != ret) || (NULL == keyval) ||
1043 (keyval->attr_type!= type) ||
1044 ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
1045 ret = OMPI_ERR_BAD_PARAM;
1046 goto exit;
1047 }
1048
1049
1050 if (NULL == attr_hash) {
1051 ret = OMPI_ERR_BAD_PARAM;
1052 goto exit;
1053 }
1054
1055
1056
1057
1058 ret = opal_hash_table_get_value_uint32(attr_hash, key, (void**) &attr);
1059 if (OMPI_SUCCESS == ret) {
1060 switch (type) {
1061 case COMM_ATTR:
1062 DELETE_ATTR_CALLBACKS(communicator, attr, keyval, object, ret);
1063 break;
1064
1065 case WIN_ATTR:
1066 DELETE_ATTR_CALLBACKS(win, attr, keyval, object, ret);
1067 break;
1068
1069 case TYPE_ATTR:
1070 DELETE_ATTR_CALLBACKS(datatype, attr, keyval, object, ret);
1071 break;
1072
1073 default:
1074
1075 assert(0);
1076 break;
1077 }
1078 if (MPI_SUCCESS != ret) {
1079 goto exit;
1080 }
1081
1082
1083
1084 (void) opal_hash_table_remove_value_uint32(attr_hash, key);
1085 OBJ_RELEASE(attr);
1086 }
1087
1088 exit:
1089
1090
1091
1092
1093
1094 if (OMPI_SUCCESS == ret) {
1095 OBJ_RELEASE(keyval);
1096 }
1097
1098 return ret;
1099 }
1100
1101
1102
1103
1104 int ompi_attr_delete(ompi_attribute_type_t type, void *object,
1105 opal_hash_table_t *attr_hash, int key,
1106 bool predefined)
1107 {
1108 int ret;
1109
1110 OPAL_THREAD_LOCK(&attribute_lock);
1111 ret = ompi_attr_delete_impl(type, object, attr_hash, key, predefined);
1112 opal_atomic_wmb();
1113 OPAL_THREAD_UNLOCK(&attribute_lock);
1114 return ret;
1115 }
1116
1117
1118
1119
1120 int ompi_attr_delete_all(ompi_attribute_type_t type, void *object,
1121 opal_hash_table_t *attr_hash)
1122 {
1123 int ret, i, num_attrs;
1124 uint32_t key;
1125 void *node, *in_node, *attr;
1126 attribute_value_t **attrs;
1127
1128
1129
1130 if (NULL == attr_hash) {
1131 return MPI_SUCCESS;
1132 }
1133
1134 OPAL_THREAD_LOCK(&attribute_lock);
1135
1136
1137 num_attrs = opal_hash_table_get_size(attr_hash);
1138 if (0 == num_attrs) {
1139 OPAL_THREAD_UNLOCK(&attribute_lock);
1140 return MPI_SUCCESS;
1141 }
1142
1143 attrs = malloc(sizeof(attribute_value_t *) * num_attrs);
1144 if (NULL == attrs) {
1145 OPAL_THREAD_UNLOCK(&attribute_lock);
1146 return OMPI_ERR_OUT_OF_RESOURCE;
1147 }
1148
1149 ret = opal_hash_table_get_first_key_uint32(attr_hash, &key, &attr, &node);
1150 for (i = 0; OMPI_SUCCESS == ret; i++) {
1151 attrs[i] = attr;
1152 in_node = node;
1153 ret = opal_hash_table_get_next_key_uint32(attr_hash, &key, &attr,
1154 in_node, &node);
1155 }
1156
1157
1158 qsort(attrs, num_attrs, sizeof(attribute_value_t *), compare_attr_sequence);
1159
1160
1161
1162
1163
1164
1165 for (i = num_attrs - 1; i >= 0; i--) {
1166 ret = ompi_attr_delete_impl(type, object, attr_hash,
1167 attrs[i]->av_key, true);
1168 if (OMPI_SUCCESS != ret) {
1169 break;
1170 }
1171 }
1172
1173
1174
1175 free(attrs);
1176 opal_atomic_wmb();
1177 OPAL_THREAD_UNLOCK(&attribute_lock);
1178 return ret;
1179 }
1180
1181
1182
1183
1184
1185
1186
1187 static int set_value(ompi_attribute_type_t type, void *object,
1188 opal_hash_table_t **attr_hash, int key,
1189 attribute_value_t *new_attr,
1190 bool predefined)
1191 {
1192 ompi_attribute_keyval_t *keyval;
1193 int ret;
1194 attribute_value_t *old_attr;
1195 bool had_old = false;
1196
1197
1198
1199
1200 ret = opal_hash_table_get_value_uint32(keyval_hash, key,
1201 (void **) &keyval);
1202
1203
1204 if ((OMPI_SUCCESS != ret ) || (NULL == keyval) ||
1205 (keyval->attr_type != type) ||
1206 ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
1207 return OMPI_ERR_BAD_PARAM;
1208 }
1209
1210
1211 if (NULL == *attr_hash) {
1212 ompi_attr_hash_init(attr_hash);
1213 }
1214
1215
1216
1217 ret = opal_hash_table_get_value_uint32(*attr_hash, key, (void**) &old_attr);
1218 if (OMPI_SUCCESS == ret) {
1219 switch (type) {
1220 case COMM_ATTR:
1221 DELETE_ATTR_CALLBACKS(communicator, old_attr, keyval, object, ret);
1222 break;
1223
1224 case WIN_ATTR:
1225 DELETE_ATTR_CALLBACKS(win, old_attr, keyval, object, ret);
1226 break;
1227
1228 case TYPE_ATTR:
1229 DELETE_ATTR_CALLBACKS(datatype, old_attr, keyval, object, ret);
1230 break;
1231
1232 default:
1233
1234 assert(0);
1235 break;
1236 }
1237 if (MPI_SUCCESS != ret) {
1238 return ret;
1239 }
1240 OBJ_RELEASE(old_attr);
1241 had_old = true;
1242 }
1243
1244 ret = opal_hash_table_get_value_uint32(keyval_hash, key,
1245 (void **) &keyval);
1246 if ((OMPI_SUCCESS != ret ) || (NULL == keyval)) {
1247
1248
1249 assert(0);
1250 return OMPI_ERR_BAD_PARAM;
1251 }
1252
1253 new_attr->av_key = key;
1254 new_attr->av_sequence = attr_sequence++;
1255
1256 ret = opal_hash_table_set_value_uint32(*attr_hash, key, new_attr);
1257
1258
1259
1260 if (OMPI_SUCCESS == ret && !had_old) {
1261 OBJ_RETAIN(keyval);
1262 }
1263
1264 return ret;
1265 }
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 static int get_value(opal_hash_table_t *attr_hash, int key,
1278 attribute_value_t **attribute, int *flag)
1279 {
1280 int ret;
1281 void *attr;
1282 ompi_attribute_keyval_t *keyval;
1283
1284
1285
1286
1287
1288
1289 *flag = 0;
1290 ret = opal_hash_table_get_value_uint32(keyval_hash, key,
1291 (void**) &keyval);
1292 if (OMPI_ERR_NOT_FOUND == ret) {
1293 return MPI_KEYVAL_INVALID;
1294 }
1295
1296
1297
1298 if (NULL == attr_hash) {
1299 return OMPI_SUCCESS;
1300 }
1301
1302 ret = opal_hash_table_get_value_uint32(attr_hash, key, &attr);
1303 if (OMPI_SUCCESS == ret) {
1304 *attribute = (attribute_value_t*)attr;
1305 *flag = 1;
1306 }
1307
1308 return OMPI_SUCCESS;
1309 }
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320 static void *translate_to_c(attribute_value_t *val)
1321 {
1322 switch (val->av_set_from) {
1323 case OMPI_ATTRIBUTE_C:
1324
1325
1326 return val->av_value;
1327
1328 case OMPI_ATTRIBUTE_INT:
1329
1330 return (void *) val->av_int_pointer;
1331
1332 case OMPI_ATTRIBUTE_FINT:
1333
1334 return (void *) val->av_fint_pointer;
1335
1336 case OMPI_ATTRIBUTE_AINT:
1337
1338 return (void *) val->av_aint_pointer;
1339
1340 default:
1341
1342 return NULL;
1343 }
1344 }
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354 static MPI_Fint translate_to_fint(attribute_value_t *val)
1355 {
1356 switch (val->av_set_from) {
1357 case OMPI_ATTRIBUTE_C:
1358
1359 return (MPI_Fint)*val->av_int_pointer;
1360
1361 case OMPI_ATTRIBUTE_INT:
1362
1363 return (MPI_Fint)*val->av_int_pointer;
1364
1365 case OMPI_ATTRIBUTE_FINT:
1366
1367
1368 return *val->av_fint_pointer;
1369
1370 case OMPI_ATTRIBUTE_AINT:
1371
1372 return (MPI_Fint)*val->av_fint_pointer;
1373
1374 default:
1375
1376 return 0;
1377 }
1378 }
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388 static MPI_Aint translate_to_aint(attribute_value_t *val)
1389 {
1390 switch (val->av_set_from) {
1391 case OMPI_ATTRIBUTE_C:
1392
1393 return (MPI_Aint) val->av_value;
1394
1395 case OMPI_ATTRIBUTE_INT:
1396
1397 return (MPI_Aint) *val->av_int_pointer;
1398
1399 case OMPI_ATTRIBUTE_FINT:
1400
1401 return (MPI_Aint) *val->av_fint_pointer;
1402
1403 case OMPI_ATTRIBUTE_AINT:
1404
1405
1406 return (MPI_Aint) val->av_value;
1407
1408 default:
1409
1410 return 0;
1411 }
1412 }
1413
1414
1415
1416
1417 static int compare_attr_sequence(const void *attr1, const void *attr2)
1418 {
1419 return (*(attribute_value_t **)attr1)->av_sequence -
1420 (*(attribute_value_t **)attr2)->av_sequence;
1421 }