Index: runtime/src/dllexports =================================================================== --- runtime/src/dllexports +++ runtime/src/dllexports @@ -493,6 +493,13 @@ omp_is_initial_device 869 %endif # OMP_40 +# OpenMP 41 + +%ifdef OMP_41 + omp_init_lock_with_hint 870 + omp_init_nest_lock_with_hint 871 +%endif # OMP_41 + %ifndef stub # Ordinals between 900 and 999 are reserved Index: runtime/src/include/40/omp.h.var =================================================================== --- runtime/src/include/40/omp.h.var +++ runtime/src/include/40/omp.h.var @@ -85,22 +85,6 @@ extern void __KAI_KMPC_CONVENTION omp_destroy_nest_lock (omp_nest_lock_t *); extern int __KAI_KMPC_CONVENTION omp_test_nest_lock (omp_nest_lock_t *); - /* lock hint type for dynamic user lock */ - typedef enum kmp_lock_hint_t { - kmp_lock_hint_none = 0, - kmp_lock_hint_uncontended, - kmp_lock_hint_contended, - kmp_lock_hint_nonspeculative, - kmp_lock_hint_speculative, - kmp_lock_hint_hle, - kmp_lock_hint_rtm, - kmp_lock_hint_adaptive - } kmp_lock_hint_t; - - /* hinted lock initializers */ - extern void __KAI_KMPC_CONVENTION kmp_init_lock_hinted(omp_lock_t *, kmp_lock_hint_t); - extern void __KAI_KMPC_CONVENTION kmp_init_nest_lock_hinted(omp_nest_lock_t *, kmp_lock_hint_t); - /* time API functions */ extern double __KAI_KMPC_CONVENTION omp_get_wtime (void); extern double __KAI_KMPC_CONVENTION omp_get_wtick (void); Index: runtime/src/include/40/omp_lib.h.var =================================================================== --- runtime/src/include/40/omp_lib.h.var +++ runtime/src/include/40/omp_lib.h.var @@ -28,7 +28,6 @@ integer, parameter :: kmp_pointer_kind = int_ptr_kind() integer, parameter :: kmp_size_t_kind = int_ptr_kind() integer, parameter :: kmp_affinity_mask_kind = int_ptr_kind() - integer, parameter :: kmp_lock_hint_kind = omp_integer_kind integer (kind=omp_integer_kind), parameter :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@ integer (kind=omp_integer_kind), parameter :: kmp_version_major = @LIBOMP_VERSION_MAJOR@ @@ -48,15 +47,6 @@ integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_close = 3 integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_spread = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_none = 0 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_uncontended = 1 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_contended = 2 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_nonspeculative = 3 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_speculative = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 5 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 6 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 7 - interface ! *** @@ -428,18 +418,6 @@ subroutine kmp_set_warnings_off() bind(c) end subroutine kmp_set_warnings_off - subroutine kmp_init_lock_hinted(lockvar, lockhint) bind(c) - import - integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_lock_hinted - - subroutine kmp_init_nest_lock_hinted(lockvar, lockhint) bind(c) - import - integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_nest_lock_hinted - end interface !DIR$ IF DEFINED (__INTEL_OFFLOAD) @@ -508,8 +486,6 @@ !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_free !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_warnings_on !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_warnings_off -!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_init_lock_hinted -!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_init_nest_lock_hinted !DIR$ IF(__INTEL_COMPILER.GE.1400) !$omp declare target(omp_set_num_threads ) @@ -577,8 +553,6 @@ !$omp declare target(kmp_free ) !$omp declare target(kmp_set_warnings_on ) !$omp declare target(kmp_set_warnings_off ) -!$omp declare target(kmp_init_lock_hinted ) -!$omp declare target(kmp_init_nest_lock_hinted ) !DIR$ ENDIF !DIR$ ENDIF Index: runtime/src/include/40/omp_lib.f.var =================================================================== --- runtime/src/include/40/omp_lib.f.var +++ runtime/src/include/40/omp_lib.f.var @@ -31,7 +31,6 @@ integer, parameter :: kmp_size_t_kind = int_ptr_kind() integer, parameter :: kmp_affinity_mask_kind = int_ptr_kind() integer, parameter :: kmp_cancel_kind = omp_integer_kind - integer, parameter :: kmp_lock_hint_kind = omp_integer_kind end module omp_lib_kinds @@ -61,15 +60,6 @@ integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3 integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_none = 0 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_uncontended = 1 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_contended = 2 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_nonspeculative = 3 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_speculative = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 5 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 6 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 7 - interface ! *** @@ -447,18 +437,6 @@ logical (kind=omp_logical_kind) kmp_get_cancellation_status end function kmp_get_cancellation_status - subroutine kmp_init_lock_hinted(lockvar, lockhint) - use omp_lib_kinds - integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind) lockhint - end subroutine kmp_init_lock_hinted - - subroutine kmp_init_nest_lock_hinted(lockvar, lockhint) - use omp_lib_kinds - integer (kind=omp_nest_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind) lockhint - end subroutine kmp_init_nest_lock_hinted - end interface !dec$ if defined(_WIN32) @@ -544,9 +522,6 @@ !dec$ attributes alias:'KMP_GET_CANCELLATION_STATUS' :: kmp_get_cancellation_status -!dec$ attributes alias:'KMP_INIT_LOCK_HINTED'::kmp_init_lock_hinted -!dec$ attributes alias:'KMP_INIT_NEST_LOCK_HINTED'::kmp_init_nest_lock_hinted - !dec$ else !*** @@ -623,9 +598,6 @@ !dec$ attributes alias:'_KMP_GET_CANCELLATION_STATUS' :: kmp_get_cancellation_status -!dec$ attributes alias:'_KMP_INIT_LOCK_HINTED'::kmp_init_lock_hinted -!dec$ attributes alias:'_KMP_INIT_NEST_LOCK_HINTED'::kmp_init_nest_lock_hinted - !dec$ endif !dec$ endif @@ -704,9 +676,6 @@ !dec$ attributes alias:'kmp_set_warnings_off_'::kmp_set_warnings_off !dec$ attributes alias:'kmp_get_cancellation_status_'::kmp_get_cancellation_status -!dec$ attributes alias:'kmp_init_lock_hinted_'::kmp_init_lock_hinted -!dec$ attributes alias:'kmp_init_nest_lock_hinted_'::kmp_init_nest_lock_hinted - !dec$ endif !dec$ if defined(__APPLE__) @@ -783,9 +752,6 @@ !dec$ attributes alias:'_kmp_get_cancellation_status_'::kmp_get_cancellation_status -!dec$ attributes alias:'_kmp_init_lock_hinted_'::kmp_init_lock_hinted -!dec$ attributes alias:'_kmp_init_nest_lock_hinted_'::kmp_init_nest_lock_hinted - !dec$ endif end module omp_lib Index: runtime/src/include/40/omp_lib.f90.var =================================================================== --- runtime/src/include/40/omp_lib.f90.var +++ runtime/src/include/40/omp_lib.f90.var @@ -27,7 +27,6 @@ integer, parameter :: kmp_size_t_kind = c_size_t integer, parameter :: kmp_affinity_mask_kind = c_intptr_t integer, parameter :: kmp_cancel_kind = omp_integer_kind - integer, parameter :: kmp_lock_hint_kind = omp_integer_kind end module omp_lib_kinds @@ -59,15 +58,6 @@ integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3 integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_none = 0 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_uncontended = 1 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_contended = 2 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_nonspeculative = 3 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_speculative = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 5 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 6 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 7 - interface ! *** @@ -453,18 +443,6 @@ logical (kind=omp_logical_kind) kmp_get_cancellation_status end function kmp_get_cancellation_status - subroutine kmp_init_lock_hinted(lockvar, lockhint) bind(c) - use omp_lib_kinds - integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_lock_hinted - - subroutine kmp_init_nest_lock_hinted(lockvar, lockhint) bind(c) - use omp_lib_kinds - integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_nest_lock_hinted - end interface end module omp_lib Index: runtime/src/include/41/omp.h.var =================================================================== --- runtime/src/include/41/omp.h.var +++ runtime/src/include/41/omp.h.var @@ -86,20 +86,20 @@ extern int __KAI_KMPC_CONVENTION omp_test_nest_lock (omp_nest_lock_t *); /* lock hint type for dynamic user lock */ - typedef enum kmp_lock_hint_t { - kmp_lock_hint_none = 0, - kmp_lock_hint_uncontended, - kmp_lock_hint_contended, - kmp_lock_hint_nonspeculative, - kmp_lock_hint_speculative, - kmp_lock_hint_hle, - kmp_lock_hint_rtm, - kmp_lock_hint_adaptive - } kmp_lock_hint_t; + typedef enum omp_lock_hint_t { + omp_lock_hint_none = 0, + omp_lock_hint_uncontended = 1, + omp_lock_hint_contended = (1<<1 ), + omp_lock_hint_nonspeculative = (1<<2 ), + omp_lock_hint_speculative = (1<<3 ), + kmp_lock_hint_hle = (1<<16), + kmp_lock_hint_rtm = (1<<17), + kmp_lock_hint_adaptive = (1<<18) + } omp_lock_hint_t; /* hinted lock initializers */ - extern void __KAI_KMPC_CONVENTION kmp_init_lock_hinted(omp_lock_t *, kmp_lock_hint_t); - extern void __KAI_KMPC_CONVENTION kmp_init_nest_lock_hinted(omp_nest_lock_t *, kmp_lock_hint_t); + extern void __KAI_KMPC_CONVENTION omp_init_lock_with_hint(omp_lock_t *, omp_lock_hint_t); + extern void __KAI_KMPC_CONVENTION omp_init_nest_lock_with_hint(omp_nest_lock_t *, omp_lock_hint_t); /* time API functions */ extern double __KAI_KMPC_CONVENTION omp_get_wtime (void); Index: runtime/src/include/41/omp_lib.h.var =================================================================== --- runtime/src/include/41/omp_lib.h.var +++ runtime/src/include/41/omp_lib.h.var @@ -28,7 +28,7 @@ integer, parameter :: kmp_pointer_kind = int_ptr_kind() integer, parameter :: kmp_size_t_kind = int_ptr_kind() integer, parameter :: kmp_affinity_mask_kind = int_ptr_kind() - integer, parameter :: kmp_lock_hint_kind = omp_integer_kind + integer, parameter :: omp_lock_hint_kind = omp_integer_kind integer (kind=omp_integer_kind), parameter :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@ integer (kind=omp_integer_kind), parameter :: kmp_version_major = @LIBOMP_VERSION_MAJOR@ @@ -48,14 +48,14 @@ integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_close = 3 integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_spread = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_none = 0 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_uncontended = 1 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_contended = 2 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_nonspeculative = 3 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_speculative = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 5 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 6 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 7 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = 0 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = 1 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = 2 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = 4 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = 8 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144 interface @@ -428,17 +428,17 @@ subroutine kmp_set_warnings_off() bind(c) end subroutine kmp_set_warnings_off - subroutine kmp_init_lock_hinted(lockvar, lockhint) bind(c) + subroutine omp_init_lock_with_hint(lockvar, lockhint) bind(c) import integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_lock_hinted + integer (kind=omp_lock_hint_kind), value :: lockhint + end subroutine omp_init_lock_with_hint - subroutine kmp_init_nest_lock_hinted(lockvar, lockhint) bind(c) + subroutine omp_init_nest_lock_with_hint(lockvar, lockhint) bind(c) import integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_nest_lock_hinted + integer (kind=omp_lock_hint_kind), value :: lockhint + end subroutine omp_init_nest_lock_with_hint end interface @@ -508,8 +508,8 @@ !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_free !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_warnings_on !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_warnings_off -!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_init_lock_hinted -!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_init_nest_lock_hinted +!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_lock_with_hint +!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_nest_lock_with_hint !DIR$ IF(__INTEL_COMPILER.GE.1400) !$omp declare target(omp_set_num_threads ) @@ -577,8 +577,8 @@ !$omp declare target(kmp_free ) !$omp declare target(kmp_set_warnings_on ) !$omp declare target(kmp_set_warnings_off ) -!$omp declare target(kmp_init_lock_hinted ) -!$omp declare target(kmp_init_nest_lock_hinted ) +!$omp declare target(omp_init_lock_with_hint ) +!$omp declare target(omp_init_nest_lock_with_hint ) !DIR$ ENDIF !DIR$ ENDIF Index: runtime/src/include/41/omp_lib.f.var =================================================================== --- runtime/src/include/41/omp_lib.f.var +++ runtime/src/include/41/omp_lib.f.var @@ -31,7 +31,7 @@ integer, parameter :: kmp_size_t_kind = int_ptr_kind() integer, parameter :: kmp_affinity_mask_kind = int_ptr_kind() integer, parameter :: kmp_cancel_kind = omp_integer_kind - integer, parameter :: kmp_lock_hint_kind = omp_integer_kind + integer, parameter :: omp_lock_hint_kind = omp_integer_kind end module omp_lib_kinds @@ -61,14 +61,14 @@ integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3 integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_none = 0 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_uncontended = 1 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_contended = 2 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_nonspeculative = 3 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_speculative = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 5 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 6 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 7 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = 0 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = 1 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = 2 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = 4 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = 8 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144 interface @@ -447,17 +447,17 @@ logical (kind=omp_logical_kind) kmp_get_cancellation_status end function kmp_get_cancellation_status - subroutine kmp_init_lock_hinted(lockvar, lockhint) + subroutine kmp_init_lock_with_hint(lockvar, lockhint) use omp_lib_kinds integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind) lockhint - end subroutine kmp_init_lock_hinted + integer (kind=omp_lock_hint_kind) lockhint + end subroutine kmp_init_lock_with_hint - subroutine kmp_init_nest_lock_hinted(lockvar, lockhint) + subroutine kmp_init_nest_lock_with_hint(lockvar, lockhint) use omp_lib_kinds integer (kind=omp_nest_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind) lockhint - end subroutine kmp_init_nest_lock_hinted + integer (kind=omp_lock_hint_kind) lockhint + end subroutine kmp_init_nest_lock_with_hint end interface @@ -505,11 +505,13 @@ !dec$ attributes alias:'OMP_IS_INITIAL_DEVICE' :: omp_is_initial_device !dec$ attributes alias:'omp_init_lock' :: omp_init_lock +!dec$ attributes alias:'omp_init_lock_with_hint' :: omp_init_lock_with_hint !dec$ attributes alias:'omp_destroy_lock' :: omp_destroy_lock !dec$ attributes alias:'omp_set_lock' :: omp_set_lock !dec$ attributes alias:'omp_unset_lock' :: omp_unset_lock !dec$ attributes alias:'omp_test_lock' :: omp_test_lock !dec$ attributes alias:'omp_init_nest_lock' :: omp_init_nest_lock +!dec$ attributes alias:'omp_init_nest_lock_with_hint' :: omp_init_nest_lock_with_hint !dec$ attributes alias:'omp_destroy_nest_lock' :: omp_destroy_nest_lock !dec$ attributes alias:'omp_set_nest_lock' :: omp_set_nest_lock !dec$ attributes alias:'omp_unset_nest_lock' :: omp_unset_nest_lock @@ -544,9 +546,6 @@ !dec$ attributes alias:'KMP_GET_CANCELLATION_STATUS' :: kmp_get_cancellation_status -!dec$ attributes alias:'KMP_INIT_LOCK_HINTED'::kmp_init_lock_hinted -!dec$ attributes alias:'KMP_INIT_NEST_LOCK_HINTED'::kmp_init_nest_lock_hinted - !dec$ else !*** @@ -584,11 +583,13 @@ !dec$ attributes alias:'_OMP_IS_INITIAL_DEVICE' :: omp_is_initial_device !dec$ attributes alias:'_omp_init_lock' :: omp_init_lock +!dec$ attributes alias:'_omp_init_lock_with_hint' :: omp_init_lock_with_hint !dec$ attributes alias:'_omp_destroy_lock' :: omp_destroy_lock !dec$ attributes alias:'_omp_set_lock' :: omp_set_lock !dec$ attributes alias:'_omp_unset_lock' :: omp_unset_lock !dec$ attributes alias:'_omp_test_lock' :: omp_test_lock !dec$ attributes alias:'_omp_init_nest_lock' :: omp_init_nest_lock +!dec$ attributes alias:'_omp_init_nest_lock_with_hint' :: omp_init_nest_lock_with_hint !dec$ attributes alias:'_omp_destroy_nest_lock' :: omp_destroy_nest_lock !dec$ attributes alias:'_omp_set_nest_lock' :: omp_set_nest_lock !dec$ attributes alias:'_omp_unset_nest_lock' :: omp_unset_nest_lock @@ -623,9 +624,6 @@ !dec$ attributes alias:'_KMP_GET_CANCELLATION_STATUS' :: kmp_get_cancellation_status -!dec$ attributes alias:'_KMP_INIT_LOCK_HINTED'::kmp_init_lock_hinted -!dec$ attributes alias:'_KMP_INIT_NEST_LOCK_HINTED'::kmp_init_nest_lock_hinted - !dec$ endif !dec$ endif @@ -666,11 +664,13 @@ !dec$ attributes alias:'omp_is_initial_device_'::omp_is_initial_device !dec$ attributes alias:'omp_init_lock_'::omp_init_lock +!dec$ attributes alias:'omp_init_lock_with_hint_'::omp_init_lock_with_hint !dec$ attributes alias:'omp_destroy_lock_'::omp_destroy_lock !dec$ attributes alias:'omp_set_lock_'::omp_set_lock !dec$ attributes alias:'omp_unset_lock_'::omp_unset_lock !dec$ attributes alias:'omp_test_lock_'::omp_test_lock !dec$ attributes alias:'omp_init_nest_lock_'::omp_init_nest_lock +!dec$ attributes alias:'omp_init_nest_lock_with_hint_'::omp_init_nest_lock_with_hint !dec$ attributes alias:'omp_destroy_nest_lock_'::omp_destroy_nest_lock !dec$ attributes alias:'omp_set_nest_lock_'::omp_set_nest_lock !dec$ attributes alias:'omp_unset_nest_lock_'::omp_unset_nest_lock @@ -704,9 +704,6 @@ !dec$ attributes alias:'kmp_set_warnings_off_'::kmp_set_warnings_off !dec$ attributes alias:'kmp_get_cancellation_status_'::kmp_get_cancellation_status -!dec$ attributes alias:'kmp_init_lock_hinted_'::kmp_init_lock_hinted -!dec$ attributes alias:'kmp_init_nest_lock_hinted_'::kmp_init_nest_lock_hinted - !dec$ endif !dec$ if defined(__APPLE__) @@ -744,11 +741,13 @@ !dec$ attributes alias:'_omp_is_initial_device_'::omp_is_initial_device !dec$ attributes alias:'_omp_init_lock_'::omp_init_lock +!dec$ attributes alias:'_omp_init_lock_with_hint_'::omp_init_lock_with_hint !dec$ attributes alias:'_omp_destroy_lock_'::omp_destroy_lock !dec$ attributes alias:'_omp_set_lock_'::omp_set_lock !dec$ attributes alias:'_omp_unset_lock_'::omp_unset_lock !dec$ attributes alias:'_omp_test_lock_'::omp_test_lock !dec$ attributes alias:'_omp_init_nest_lock_'::omp_init_nest_lock +!dec$ attributes alias:'_omp_init_nest_lock_with_hint_'::omp_init_nest_lock_with_hint !dec$ attributes alias:'_omp_destroy_nest_lock_'::omp_destroy_nest_lock !dec$ attributes alias:'_omp_set_nest_lock_'::omp_set_nest_lock !dec$ attributes alias:'_omp_unset_nest_lock_'::omp_unset_nest_lock @@ -783,9 +782,6 @@ !dec$ attributes alias:'_kmp_get_cancellation_status_'::kmp_get_cancellation_status -!dec$ attributes alias:'_kmp_init_lock_hinted_'::kmp_init_lock_hinted -!dec$ attributes alias:'_kmp_init_nest_lock_hinted_'::kmp_init_nest_lock_hinted - !dec$ endif end module omp_lib Index: runtime/src/include/41/omp_lib.f90.var =================================================================== --- runtime/src/include/41/omp_lib.f90.var +++ runtime/src/include/41/omp_lib.f90.var @@ -27,7 +27,7 @@ integer, parameter :: kmp_size_t_kind = c_size_t integer, parameter :: kmp_affinity_mask_kind = c_intptr_t integer, parameter :: kmp_cancel_kind = omp_integer_kind - integer, parameter :: kmp_lock_hint_kind = omp_integer_kind + integer, parameter :: omp_lock_hint_kind = omp_integer_kind end module omp_lib_kinds @@ -59,14 +59,14 @@ integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3 integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_none = 0 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_uncontended = 1 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_contended = 2 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_nonspeculative = 3 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_speculative = 4 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 5 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 6 - integer (kind=kmp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 7 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = 0 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = 1 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = 2 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = 4 + integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = 8 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072 + integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144 interface @@ -453,17 +453,17 @@ logical (kind=omp_logical_kind) kmp_get_cancellation_status end function kmp_get_cancellation_status - subroutine kmp_init_lock_hinted(lockvar, lockhint) bind(c) + subroutine omp_init_lock_with_hint(lockvar, lockhint) bind(c) use omp_lib_kinds integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_lock_hinted + integer (kind=omp_lock_hint_kind), value :: lockhint + end subroutine omp_init_lock_with_hint - subroutine kmp_init_nest_lock_hinted(lockvar, lockhint) bind(c) + subroutine omp_init_nest_lock_with_hint(lockvar, lockhint) bind(c) use omp_lib_kinds integer (kind=omp_lock_kind) lockvar - integer (kind=kmp_lock_hint_kind), value :: lockhint - end subroutine kmp_init_nest_lock_hinted + integer (kind=omp_lock_hint_kind), value :: lockhint + end subroutine omp_init_nest_lock_with_hint end interface Index: runtime/src/kmp.h =================================================================== --- runtime/src/kmp.h +++ runtime/src/kmp.h @@ -3330,6 +3330,10 @@ KMP_EXPORT void __kmpc_critical ( ident_t *, kmp_int32 global_tid, kmp_critical_name * ); KMP_EXPORT void __kmpc_end_critical ( ident_t *, kmp_int32 global_tid, kmp_critical_name * ); +#if OMP_41_ENABLED +KMP_EXPORT void __kmpc_critical_with_hint ( ident_t *, kmp_int32 global_tid, kmp_critical_name *, uintptr_t hint ); +#endif + KMP_EXPORT kmp_int32 __kmpc_barrier_master ( ident_t *, kmp_int32 global_tid ); KMP_EXPORT void __kmpc_end_barrier_master ( ident_t *, kmp_int32 global_tid ); @@ -3437,6 +3441,11 @@ KMP_EXPORT int __kmpc_test_lock( ident_t *loc, kmp_int32 gtid, void **user_lock ); KMP_EXPORT int __kmpc_test_nest_lock( ident_t *loc, kmp_int32 gtid, void **user_lock ); +#if OMP_41_ENABLED +KMP_EXPORT void __kmpc_init_lock_with_hint( ident_t *loc, kmp_int32 gtid, void **user_lock, uintptr_t hint ); +KMP_EXPORT void __kmpc_init_nest_lock_with_hint( ident_t *loc, kmp_int32 gtid, void **user_lock, uintptr_t hint ); +#endif + /* ------------------------------------------------------------------------ */ /* Index: runtime/src/kmp_csupport.c =================================================================== --- runtime/src/kmp_csupport.c +++ runtime/src/kmp_csupport.c @@ -1108,19 +1108,121 @@ This function blocks until the executing thread can enter the critical section. */ void -__kmpc_critical( ident_t * loc, kmp_int32 global_tid, kmp_critical_name * crit ) { +__kmpc_critical( ident_t * loc, kmp_int32 global_tid, kmp_critical_name * crit ) +{ +#if KMP_USE_DYNAMIC_LOCK + __kmpc_critical_with_hint(loc, global_tid, crit, omp_lock_hint_none); +#else KMP_COUNT_BLOCK(OMP_CRITICAL); - kmp_user_lock_p lck; KC_TRACE( 10, ("__kmpc_critical: called T#%d\n", global_tid ) ); + //TODO: add THR_OVHD_STATE + + KMP_CHECK_USER_LOCK_INIT(); + + if ( ( __kmp_user_lock_kind == lk_tas ) + && ( sizeof( lck->tas.lk.poll ) <= OMP_CRITICAL_SIZE ) ) { + lck = (kmp_user_lock_p)crit; + } +#if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) + else if ( ( __kmp_user_lock_kind == lk_futex ) + && ( sizeof( lck->futex.lk.poll ) <= OMP_CRITICAL_SIZE ) ) { + lck = (kmp_user_lock_p)crit; + } +#endif + else { // ticket, queuing or drdpa + lck = __kmp_get_critical_section_ptr( crit, loc, global_tid ); + } + + if ( __kmp_env_consistency_check ) + __kmp_push_sync( global_tid, ct_critical, loc, lck ); + + /* since the critical directive binds to all threads, not just + * the current team we have to check this even if we are in a + * serialized team */ + /* also, even if we are the uber thread, we still have to conduct the lock, + * as we have to contend with sibling threads */ + +#if USE_ITT_BUILD + __kmp_itt_critical_acquiring( lck ); +#endif /* USE_ITT_BUILD */ + // Value of 'crit' should be good for using as a critical_id of the critical section directive. + __kmp_acquire_user_lock_with_checks( lck, global_tid ); + +#if USE_ITT_BUILD + __kmp_itt_critical_acquired( lck ); +#endif /* USE_ITT_BUILD */ + + KA_TRACE( 15, ("__kmpc_critical: done T#%d\n", global_tid )); +#endif // KMP_USE_DYNAMIC_LOCK +} + #if KMP_USE_DYNAMIC_LOCK +// Converts the given hint to an internal lock implementation +static __forceinline kmp_dyna_lockseq_t +__kmp_map_hint_to_lock(uintptr_t hint) +{ +#if KMP_USE_TSX +# define KMP_TSX_LOCK(seq) lockseq_##seq +#else +# define KMP_TSX_LOCK(seq) __kmp_user_lock_seq +#endif + // Hints that do not require further logic + if (hint & kmp_lock_hint_hle) + return KMP_TSX_LOCK(hle); + if (hint & kmp_lock_hint_rtm) + return (__kmp_cpuinfo.rtm)? KMP_TSX_LOCK(rtm): __kmp_user_lock_seq; + if (hint & kmp_lock_hint_adaptive) + return (__kmp_cpuinfo.rtm)? KMP_TSX_LOCK(adaptive): __kmp_user_lock_seq; + + // Rule out conflicting hints first by returning the default lock + if ((hint & omp_lock_hint_contended) && (hint & omp_lock_hint_uncontended)) + return __kmp_user_lock_seq; + if ((hint & omp_lock_hint_speculative) && (hint & omp_lock_hint_nonspeculative)) + return __kmp_user_lock_seq; + + // Do not even consider speculation when it appears to be contended + if (hint & omp_lock_hint_contended) + return lockseq_queuing; + + // Uncontended lock without speculation + if ((hint & omp_lock_hint_uncontended) && !(hint & omp_lock_hint_speculative)) + return lockseq_tas; + + // HLE lock for speculation + if (hint & omp_lock_hint_speculative) + return KMP_TSX_LOCK(hle); + + return __kmp_user_lock_seq; +} + +/*! +@ingroup WORK_SHARING +@param loc source location information. +@param global_tid global thread number. +@param crit identity of the critical section. This could be a pointer to a lock associated with the critical section, +or some other suitably unique value. +@param hint the lock hint. + +Enter code protected by a `critical` construct with a hint. The hint value is used to suggest a lock implementation. +This function blocks until the executing thread can enter the critical section unless the hint suggests use of +speculative execution and the hardware supports it. +*/ +void +__kmpc_critical_with_hint( ident_t * loc, kmp_int32 global_tid, kmp_critical_name * crit, uintptr_t hint ) +{ + KMP_COUNT_BLOCK(OMP_CRITICAL); + kmp_user_lock_p lck; + + KC_TRACE( 10, ("__kmpc_critical: called T#%d\n", global_tid ) ); + kmp_dyna_lock_t *lk = (kmp_dyna_lock_t *)crit; // Check if it is initialized. if (*lk == 0) { - kmp_dyna_lockseq_t lckseq = __kmp_user_lock_seq; + kmp_dyna_lockseq_t lckseq = __kmp_map_hint_to_lock(hint); if (KMP_IS_D_LOCK(lckseq)) { KMP_COMPARE_AND_STORE_ACQ32((volatile kmp_int32 *)crit, 0, KMP_GET_D_TAG(lckseq)); } else { @@ -1132,7 +1234,7 @@ if (KMP_EXTRACT_D_TAG(lk) != 0) { lck = (kmp_user_lock_p)lk; if (__kmp_env_consistency_check) { - __kmp_push_sync(global_tid, ct_critical, loc, lck, __kmp_user_lock_seq); + __kmp_push_sync(global_tid, ct_critical, loc, lck, __kmp_map_hint_to_lock(hint)); } # if USE_ITT_BUILD __kmp_itt_critical_acquiring(lck); @@ -1153,7 +1255,7 @@ kmp_indirect_lock_t *ilk = *((kmp_indirect_lock_t **)lk); lck = ilk->lock; if (__kmp_env_consistency_check) { - __kmp_push_sync(global_tid, ct_critical, loc, lck, __kmp_user_lock_seq); + __kmp_push_sync(global_tid, ct_critical, loc, lck, __kmp_map_hint_to_lock(hint)); } # if USE_ITT_BUILD __kmp_itt_critical_acquiring(lck); @@ -1161,49 +1263,14 @@ KMP_I_LOCK_FUNC(ilk, set)(lck, global_tid); } -#else // KMP_USE_DYNAMIC_LOCK - - //TODO: add THR_OVHD_STATE - - KMP_CHECK_USER_LOCK_INIT(); - - if ( ( __kmp_user_lock_kind == lk_tas ) - && ( sizeof( lck->tas.lk.poll ) <= OMP_CRITICAL_SIZE ) ) { - lck = (kmp_user_lock_p)crit; - } -#if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) - else if ( ( __kmp_user_lock_kind == lk_futex ) - && ( sizeof( lck->futex.lk.poll ) <= OMP_CRITICAL_SIZE ) ) { - lck = (kmp_user_lock_p)crit; - } -#endif - else { // ticket, queuing or drdpa - lck = __kmp_get_critical_section_ptr( crit, loc, global_tid ); - } - - if ( __kmp_env_consistency_check ) - __kmp_push_sync( global_tid, ct_critical, loc, lck ); - - /* since the critical directive binds to all threads, not just - * the current team we have to check this even if we are in a - * serialized team */ - /* also, even if we are the uber thread, we still have to conduct the lock, - * as we have to contend with sibling threads */ - -#if USE_ITT_BUILD - __kmp_itt_critical_acquiring( lck ); -#endif /* USE_ITT_BUILD */ - // Value of 'crit' should be good for using as a critical_id of the critical section directive. - __kmp_acquire_user_lock_with_checks( lck, global_tid ); - -#endif // KMP_USE_DYNAMIC_LOCK - #if USE_ITT_BUILD __kmp_itt_critical_acquired( lck ); #endif /* USE_ITT_BUILD */ KA_TRACE( 15, ("__kmpc_critical: done T#%d\n", global_tid )); -} // __kmpc_critical +} // __kmpc_critical_with_hint + +#endif // KMP_USE_DYNAMIC_LOCK /*! @ingroup WORK_SHARING @@ -1748,6 +1815,89 @@ * into with_checks routines */ +#if KMP_USE_DYNAMIC_LOCK + +// internal lock initializer +static __forceinline void +__kmp_init_lock_with_hint(ident_t *loc, void **lock, kmp_dyna_lockseq_t seq) +{ + if (KMP_IS_D_LOCK(seq)) { + KMP_INIT_D_LOCK(lock, seq); +#if USE_ITT_BUILD + __kmp_itt_lock_creating((kmp_user_lock_p)lock, NULL); +#endif + } else { + KMP_INIT_I_LOCK(lock, seq); +#if USE_ITT_BUILD + kmp_indirect_lock_t *ilk = KMP_LOOKUP_I_LOCK(lock); + __kmp_itt_lock_creating(ilk->lock, loc); +#endif + } +} + +// internal nest lock initializer +static __forceinline void +__kmp_init_nest_lock_with_hint(ident_t *loc, void **lock, kmp_dyna_lockseq_t seq) +{ +#if KMP_USE_TSX + // Don't have nested lock implementation for speculative locks + if (seq == lockseq_hle || seq == lockseq_rtm || seq == lockseq_adaptive) + seq = __kmp_user_lock_seq; +#endif + switch (seq) { + case lockseq_tas: + seq = lockseq_nested_tas; + break; +#if KMP_USE_FUTEX + case lockseq_futex: + seq = lockseq_nested_futex; + break; +#endif + case lockseq_ticket: + seq = lockseq_nested_ticket; + break; + case lockseq_queuing: + seq = lockseq_nested_queuing; + break; + case lockseq_drdpa: + seq = lockseq_nested_drdpa; + break; + default: + seq = lockseq_nested_queuing; + } + KMP_INIT_I_LOCK(lock, seq); +#if USE_ITT_BUILD + kmp_indirect_lock_t *ilk = KMP_LOOKUP_I_LOCK(lock); + __kmp_itt_lock_creating(ilk->lock, loc); +#endif +} + +/* initialize the lock with a hint */ +void +__kmpc_init_lock_with_hint(ident_t *loc, kmp_int32 gtid, void **user_lock, uintptr_t hint) +{ + KMP_DEBUG_ASSERT(__kmp_init_serial); + if (__kmp_env_consistency_check && user_lock == NULL) { + KMP_FATAL(LockIsUninitialized, "omp_init_lock_with_hint"); + } + + __kmp_init_lock_with_hint(loc, user_lock, __kmp_map_hint_to_lock(hint)); +} + +/* initialize the lock with a hint */ +void +__kmpc_init_nest_lock_with_hint(ident_t *loc, kmp_int32 gtid, void **user_lock, uintptr_t hint) +{ + KMP_DEBUG_ASSERT(__kmp_init_serial); + if (__kmp_env_consistency_check && user_lock == NULL) { + KMP_FATAL(LockIsUninitialized, "omp_init_nest_lock_with_hint"); + } + + __kmp_init_nest_lock_with_hint(loc, user_lock, __kmp_map_hint_to_lock(hint)); +} + +#endif // KMP_USE_DYNAMIC_LOCK + /* initialize the lock */ void __kmpc_init_lock( ident_t * loc, kmp_int32 gtid, void ** user_lock ) { @@ -1756,19 +1906,7 @@ if (__kmp_env_consistency_check && user_lock == NULL) { KMP_FATAL(LockIsUninitialized, "omp_init_lock"); } - if (KMP_IS_D_LOCK(__kmp_user_lock_seq)) { - KMP_INIT_D_LOCK(user_lock, __kmp_user_lock_seq); -# if USE_ITT_BUILD - __kmp_itt_lock_creating((kmp_user_lock_p)user_lock, NULL); -# endif - } else { - KMP_INIT_I_LOCK(user_lock, __kmp_user_lock_seq); - kmp_indirect_lock_t *ilk = KMP_LOOKUP_I_LOCK(user_lock); - KMP_SET_I_LOCK_LOCATION(ilk, loc); -# if USE_ITT_BUILD - __kmp_itt_lock_creating(ilk->lock, loc); -# endif - } + __kmp_init_lock_with_hint(loc, user_lock, __kmp_user_lock_seq); #else // KMP_USE_DYNAMIC_LOCK @@ -1823,26 +1961,7 @@ if (__kmp_env_consistency_check && user_lock == NULL) { KMP_FATAL(LockIsUninitialized, "omp_init_nest_lock"); } - // Invoke init function after converting to nested version. - kmp_dyna_lockseq_t nested_seq; - switch (__kmp_user_lock_seq) { - case lockseq_tas: nested_seq = lockseq_nested_tas; break; -#if KMP_USE_FUTEX - case lockseq_futex: nested_seq = lockseq_nested_futex; break; -#endif - case lockseq_ticket: nested_seq = lockseq_nested_ticket; break; - case lockseq_queuing: nested_seq = lockseq_nested_queuing; break; - case lockseq_drdpa: nested_seq = lockseq_nested_drdpa; break; - default: nested_seq = lockseq_nested_queuing; break; - // Use nested queuing lock for lock kinds without "nested" implementation. - } - KMP_INIT_I_LOCK(user_lock, nested_seq); - // All nested locks are indirect locks. - kmp_indirect_lock_t *ilk = KMP_LOOKUP_I_LOCK(user_lock); - KMP_SET_I_LOCK_LOCATION(ilk, loc); -# if USE_ITT_BUILD - __kmp_itt_lock_creating(ilk->lock, loc); -# endif + __kmp_init_nest_lock_with_hint(loc, user_lock, __kmp_user_lock_seq); #else // KMP_USE_DYNAMIC_LOCK Index: runtime/src/kmp_ftn_entry.h =================================================================== --- runtime/src/kmp_ftn_entry.h +++ runtime/src/kmp_ftn_entry.h @@ -812,22 +812,22 @@ #if KMP_USE_DYNAMIC_LOCK void FTN_STDCALL -FTN_INIT_LOCK_HINTED( void **user_lock, int KMP_DEREF hint ) +FTN_INIT_LOCK_WITH_HINT( void **user_lock, uintptr_t KMP_DEREF hint ) { #ifdef KMP_STUB *((kmp_stub_lock_t *)user_lock) = UNLOCKED; #else - __kmp_init_lock_hinted( user_lock, KMP_DEREF hint ); + __kmpc_init_lock_with_hint( NULL, __kmp_entry_gtid(), user_lock, KMP_DEREF hint ); #endif } void FTN_STDCALL -FTN_INIT_NEST_LOCK_HINTED( void **user_lock, int KMP_DEREF hint ) +FTN_INIT_NEST_LOCK_WITH_HINT( void **user_lock, uintptr_t KMP_DEREF hint ) { #ifdef KMP_STUB *((kmp_stub_lock_t *)user_lock) = UNLOCKED; #else - __kmp_init_nest_lock_hinted( user_lock, KMP_DEREF hint ); + __kmpc_init_nest_lock_with_hint( NULL, __kmp_entry_gtid(), user_lock, KMP_DEREF hint ); #endif } #endif Index: runtime/src/kmp_ftn_os.h =================================================================== --- runtime/src/kmp_ftn_os.h +++ runtime/src/kmp_ftn_os.h @@ -80,8 +80,8 @@ #endif #define FTN_INIT_LOCK omp_init_lock #if KMP_USE_DYNAMIC_LOCK - #define FTN_INIT_LOCK_HINTED kmp_init_lock_hinted - #define FTN_INIT_NEST_LOCK_HINTED kmp_init_nest_lock_hinted + #define FTN_INIT_LOCK_WITH_HINT omp_init_lock_with_hint + #define FTN_INIT_NEST_LOCK_WITH_HINT omp_init_nest_lock_with_hint #endif #define FTN_DESTROY_LOCK omp_destroy_lock #define FTN_SET_LOCK omp_set_lock @@ -176,8 +176,8 @@ #endif #define FTN_INIT_LOCK omp_init_lock_ #if KMP_USE_DYNAMIC_LOCK - #define FTN_INIT_LOCK_HINTED kmp_init_lock_hinted_ - #define FTN_INIT_NEST_LOCK_HINTED kmp_init_nest_lock_hinted_ + #define FTN_INIT_LOCK_WITH_HINT omp_init_lock_with_hint_ + #define FTN_INIT_NEST_LOCK_WITH_HINT omp_init_nest_lock_with_hint_ #endif #define FTN_DESTROY_LOCK omp_destroy_lock_ #define FTN_SET_LOCK omp_set_lock_ @@ -273,8 +273,8 @@ #endif #define FTN_INIT_LOCK OMP_INIT_LOCK #if KMP_USE_DYNAMIC_LOCK - #define FTN_INIT_LOCK_HINTED KMP_INIT_LOCK_HINTED - #define FTN_INIT_NEST_LOCK_HINTED KMP_INIT_NEST_LOCK_HINTED + #define FTN_INIT_LOCK_WITH_HINT OMP_INIT_LOCK_WITH_HINT + #define FTN_INIT_NEST_LOCK_WITH_HINT OMP_INIT_NEST_LOCK_WITH_HINT #endif #define FTN_DESTROY_LOCK OMP_DESTROY_LOCK #define FTN_SET_LOCK OMP_SET_LOCK @@ -370,8 +370,8 @@ #endif #define FTN_INIT_LOCK OMP_INIT_LOCK_ #if KMP_USE_DYNAMIC_LOCK - #define FTN_INIT_LOCK_HINTED KMP_INIT_LOCK_HINTED_ - #define FTN_INIT_NEST_LOCK_HINTED KMP_INIT_NEST_LOCK_HINTED_ + #define FTN_INIT_LOCK_WITH_HINT OMP_INIT_LOCK_WITH_HINT_ + #define FTN_INIT_NEST_LOCK_WITH_HINT OMP_INIT_NEST_LOCK_WITH_HINT_ #endif #define FTN_DESTROY_LOCK OMP_DESTROY_LOCK_ #define FTN_SET_LOCK OMP_SET_LOCK_ Index: runtime/src/kmp_lock.h =================================================================== --- runtime/src/kmp_lock.h +++ runtime/src/kmp_lock.h @@ -1034,6 +1034,39 @@ #if KMP_USE_DYNAMIC_LOCK +// +// KMP_USE_DYNAMIC_LOCK enables dynamic dispatch of lock functions without breaking the current +// compatibility. Essential functionality of this new code is dynamic dispatch, but it also +// implements (or enables implementation of) hinted user lock and critical section which will be +// part of OMP 4.1 soon. +// +// Lock type can be decided at creation time (i.e., lock initialization), and subsequent lock +// function call on the created lock object requires type extraction and call through jump table +// using the extracted type. This type information is stored in two different ways depending on +// the size of the lock object, and we differentiate lock types by this size requirement - direct +// and indirect locks. +// +// Direct locks: +// A direct lock object fits into the space created by the compiler for an omp_lock_t object, and +// TAS/Futex lock falls into this category. We use low one byte of the lock object as the storage +// for the lock type, and appropriate bit operation is required to access the data meaningful to +// the lock algorithms. Also, to differentiate direct lock from indirect lock, 1 is written to LSB +// of the lock object. The newly introduced "hle" lock is also a direct lock. +// +// Indirect locks: +// An indirect lock object requires more space than the compiler-generated space, and it should be +// allocated from heap. Depending on the size of the compiler-generated space for the lock (i.e., +// size of omp_lock_t), this omp_lock_t object stores either the address of the heap-allocated +// indirect lock (void * fits in the object) or an index to the indirect lock table entry that +// holds the address. Ticket/Queuing/DRDPA/Adaptive lock falls into this category, and the newly +// introduced "rtm" lock is also an indirect lock which was implemented on top of the Queuing lock. +// When the omp_lock_t object holds an index (not lock address), 0 is written to LSB to +// differentiate the lock from a direct lock, and the remaining part is the actual index to the +// indirect lock table. +// + +#include // for uintptr_t + // Shortcuts #define KMP_USE_FUTEX (KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64)) #define KMP_USE_INLINED_TAS (KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM)) && 1 @@ -1158,10 +1191,6 @@ // Returns lock value after removing (shifting) lock tag. #define KMP_LOCK_STRIP(v) ((v)>>KMP_LOCK_SHIFT) -// Internal entries for hinted lock initializers. -extern void __kmp_init_lock_hinted(void **, int); -extern void __kmp_init_nest_lock_hinted(void **, int); - // Initializes global states and data structures for managing dynamic user locks. extern void __kmp_init_dynamic_user_locks(); Index: runtime/src/kmp_lock.cpp =================================================================== --- runtime/src/kmp_lock.cpp +++ runtime/src/kmp_lock.cpp @@ -3010,20 +3010,6 @@ #if KMP_USE_DYNAMIC_LOCK -// Definitions of lock hints - can't include omp.h because of other name clashes. -# ifndef __OMP_H -typedef enum kmp_lock_hint_t { - kmp_lock_hint_none = 0, - kmp_lock_hint_uncontended, - kmp_lock_hint_contended, - kmp_lock_hint_nonspeculative, - kmp_lock_hint_speculative, - kmp_lock_hint_hle, - kmp_lock_hint_rtm, - kmp_lock_hint_adaptive -} kmp_lock_hint_t; -# endif - // Direct lock initializers. It simply writes a tag to the low 8 bits of the lock word. static void __kmp_init_direct_lock(kmp_dyna_lock_t *lck, kmp_dyna_lockseq_t seq) { @@ -3358,7 +3344,7 @@ } if (OMP_LOCK_T_SIZE < sizeof(void *)) { kmp_lock_index_t idx = KMP_EXTRACT_I_INDEX(user_lock); - if (idx < 0 || idx >= __kmp_i_lock_table.size) { + if (idx >= __kmp_i_lock_table.size) { KMP_FATAL(LockIsUninitialized, func); } lck = KMP_GET_I_LOCK(idx); @@ -3462,58 +3448,6 @@ kmp_dyna_lockseq_t __kmp_user_lock_seq = lockseq_queuing; -// Initialize a hinted lock. -void -__kmp_init_lock_hinted(void **lock, int hint) -{ - kmp_dyna_lockseq_t seq; - switch (hint) { - case kmp_lock_hint_uncontended: - seq = lockseq_tas; - break; - case kmp_lock_hint_speculative: -#if KMP_USE_TSX - seq = lockseq_hle; -#else - seq = lockseq_tas; -#endif - break; - case kmp_lock_hint_adaptive: -#if KMP_USE_ADAPTIVE_LOCKS - seq = lockseq_adaptive; -#else - seq = lockseq_queuing; -#endif - break; -#if KMP_USE_TSX - case kmp_lock_hint_hle: - seq = lockseq_hle; - break; - case kmp_lock_hint_rtm: - seq = lockseq_rtm; - break; -#endif - // Defaults to queuing locks. - case kmp_lock_hint_contended: - case kmp_lock_hint_nonspeculative: - default: - seq = lockseq_queuing; - break; - } - if (KMP_IS_D_LOCK(seq)) { - KMP_INIT_D_LOCK(lock, seq); -#if USE_ITT_BUILD - __kmp_itt_lock_creating((kmp_user_lock_p)lock, NULL); -#endif - } else { - KMP_INIT_I_LOCK(lock, seq); -#if USE_ITT_BUILD - kmp_indirect_lock_t *ilk = KMP_LOOKUP_I_LOCK(lock); - __kmp_itt_lock_creating(ilk->lock, NULL); -#endif - } -} - // This is used only in kmp_error.c when consistency checking is on. kmp_int32 __kmp_get_user_lock_owner(kmp_user_lock_p lck, kmp_uint32 seq) @@ -3544,29 +3478,6 @@ } } -// The value initialized from KMP_LOCK_KIND needs to be translated to its -// nested version. -void -__kmp_init_nest_lock_hinted(void **lock, int hint) -{ - kmp_dyna_lockseq_t seq; - switch (hint) { - case kmp_lock_hint_uncontended: - seq = lockseq_nested_tas; - break; - // Defaults to queuing locks. - case kmp_lock_hint_contended: - case kmp_lock_hint_nonspeculative: - default: - seq = lockseq_nested_queuing; - } - KMP_INIT_I_LOCK(lock, seq); -#if USE_ITT_BUILD - kmp_indirect_lock_t *ilk = KMP_LOOKUP_I_LOCK(lock); - __kmp_itt_lock_creating(ilk->lock, NULL); -#endif -} - // Initializes data for dynamic user locks. void __kmp_init_dynamic_user_locks() Index: runtime/src/kmp_os.h =================================================================== --- runtime/src/kmp_os.h +++ runtime/src/kmp_os.h @@ -689,16 +689,17 @@ #endif // Enable dynamic user lock -#ifndef KMP_USE_DYNAMIC_LOCK -# define KMP_USE_DYNAMIC_LOCK 0 +#if OMP_41_ENABLED +# define KMP_USE_DYNAMIC_LOCK 1 #endif // Enable TSX if dynamic user lock is turned on #if KMP_USE_DYNAMIC_LOCK # define KMP_USE_TSX (KMP_ARCH_X86 || KMP_ARCH_X86_64) -# ifndef KMP_USE_ADAPTIVE_LOCKS -# define KMP_USE_ADAPTIVE_LOCKS KMP_USE_TSX +# ifdef KMP_USE_ADAPTIVE_LOCKS +# undef KMP_USE_ADAPTIVE_LOCKS # endif +# define KMP_USE_ADAPTIVE_LOCKS KMP_USE_TSX #endif // Warning levels