20 #include "kmp_debug.h" 33 #define KMP_PAD(type, sz) \ 34 (sizeof(type) + (sz - ((sizeof(type) - 1) % (sz)) - 1)) 35 #define KMP_GTID_DNE (-2) 54 #if KMP_OS_LINUX && defined(KMP_GOMP_COMPAT) 55 #define OMP_LOCK_T_SIZE sizeof(int) 56 #define OMP_NEST_LOCK_T_SIZE sizeof(void *) 58 #define OMP_LOCK_T_SIZE sizeof(void *) 59 #define OMP_NEST_LOCK_T_SIZE sizeof(void *) 65 #define OMP_CRITICAL_SIZE sizeof(void *) 66 #define INTEL_CRITICAL_SIZE 32 69 typedef kmp_uint32 kmp_lock_flags_t;
71 #define kmp_lf_critical_section 1 74 typedef kmp_uint32 kmp_lock_index_t;
78 struct kmp_lock_pool {
79 union kmp_user_lock *next;
80 kmp_lock_index_t index;
83 typedef struct kmp_lock_pool kmp_lock_pool_t;
85 extern void __kmp_validate_locks(
void);
122 struct kmp_base_tas_lock {
124 std::atomic<kmp_int32> poll;
125 kmp_int32 depth_locked;
128 typedef struct kmp_base_tas_lock kmp_base_tas_lock_t;
131 kmp_base_tas_lock_t lk;
132 kmp_lock_pool_t pool;
136 typedef union kmp_tas_lock kmp_tas_lock_t;
140 #define KMP_TAS_LOCK_INITIALIZER(lock) \ 142 { ATOMIC_VAR_INIT(KMP_LOCK_FREE(tas)), 0 } \ 145 extern int __kmp_acquire_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid);
146 extern int __kmp_test_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid);
147 extern int __kmp_release_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid);
148 extern void __kmp_init_tas_lock(kmp_tas_lock_t *lck);
149 extern void __kmp_destroy_tas_lock(kmp_tas_lock_t *lck);
151 extern int __kmp_acquire_nested_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid);
152 extern int __kmp_test_nested_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid);
153 extern int __kmp_release_nested_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid);
154 extern void __kmp_init_nested_tas_lock(kmp_tas_lock_t *lck);
155 extern void __kmp_destroy_nested_tas_lock(kmp_tas_lock_t *lck);
157 #define KMP_LOCK_RELEASED 1 158 #define KMP_LOCK_STILL_HELD 0 159 #define KMP_LOCK_ACQUIRED_FIRST 1 160 #define KMP_LOCK_ACQUIRED_NEXT 0 161 #ifndef KMP_USE_FUTEX 162 #define KMP_USE_FUTEX \ 163 (KMP_OS_LINUX && !KMP_OS_CNK && \ 164 (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64)) 179 struct kmp_base_futex_lock {
180 volatile kmp_int32 poll;
183 kmp_int32 depth_locked;
186 typedef struct kmp_base_futex_lock kmp_base_futex_lock_t;
188 union kmp_futex_lock {
189 kmp_base_futex_lock_t lk;
190 kmp_lock_pool_t pool;
195 typedef union kmp_futex_lock kmp_futex_lock_t;
199 #define KMP_FUTEX_LOCK_INITIALIZER(lock) \ 201 { KMP_LOCK_FREE(futex), 0 } \ 204 extern int __kmp_acquire_futex_lock(kmp_futex_lock_t *lck, kmp_int32 gtid);
205 extern int __kmp_test_futex_lock(kmp_futex_lock_t *lck, kmp_int32 gtid);
206 extern int __kmp_release_futex_lock(kmp_futex_lock_t *lck, kmp_int32 gtid);
207 extern void __kmp_init_futex_lock(kmp_futex_lock_t *lck);
208 extern void __kmp_destroy_futex_lock(kmp_futex_lock_t *lck);
210 extern int __kmp_acquire_nested_futex_lock(kmp_futex_lock_t *lck,
212 extern int __kmp_test_nested_futex_lock(kmp_futex_lock_t *lck, kmp_int32 gtid);
213 extern int __kmp_release_nested_futex_lock(kmp_futex_lock_t *lck,
215 extern void __kmp_init_nested_futex_lock(kmp_futex_lock_t *lck);
216 extern void __kmp_destroy_nested_futex_lock(kmp_futex_lock_t *lck);
218 #endif // KMP_USE_FUTEX 229 struct kmp_base_ticket_lock {
231 std::atomic_bool initialized;
232 volatile union kmp_ticket_lock *
self;
236 std::atomic_uint now_serving;
237 std::atomic_int owner_id;
238 std::atomic_int depth_locked;
239 kmp_lock_flags_t flags;
242 struct kmp_base_ticket_lock {
244 std::atomic<bool> initialized;
245 volatile union kmp_ticket_lock *
self;
247 std::atomic<unsigned>
249 std::atomic<unsigned>
251 std::atomic<int> owner_id;
252 std::atomic<int> depth_locked;
253 kmp_lock_flags_t flags;
259 struct kmp_base_ticket_lock;
261 #endif // !__cplusplus 263 typedef struct kmp_base_ticket_lock kmp_base_ticket_lock_t;
265 union KMP_ALIGN_CACHE kmp_ticket_lock {
266 kmp_base_ticket_lock_t
268 kmp_lock_pool_t pool;
270 char lk_pad[KMP_PAD(kmp_base_ticket_lock_t, CACHE_LINE)];
273 typedef union kmp_ticket_lock kmp_ticket_lock_t;
278 #define KMP_TICKET_LOCK_INITIALIZER(lock) \ 281 ATOMIC_VAR_INIT(true) \ 282 , &(lock), NULL, ATOMIC_VAR_INIT(0U), ATOMIC_VAR_INIT(0U), \ 283 ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(-1) \ 287 extern int __kmp_acquire_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid);
288 extern int __kmp_test_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid);
289 extern int __kmp_test_ticket_lock_with_cheks(kmp_ticket_lock_t *lck,
291 extern int __kmp_release_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid);
292 extern void __kmp_init_ticket_lock(kmp_ticket_lock_t *lck);
293 extern void __kmp_destroy_ticket_lock(kmp_ticket_lock_t *lck);
295 extern int __kmp_acquire_nested_ticket_lock(kmp_ticket_lock_t *lck,
297 extern int __kmp_test_nested_ticket_lock(kmp_ticket_lock_t *lck,
299 extern int __kmp_release_nested_ticket_lock(kmp_ticket_lock_t *lck,
301 extern void __kmp_init_nested_ticket_lock(kmp_ticket_lock_t *lck);
302 extern void __kmp_destroy_nested_ticket_lock(kmp_ticket_lock_t *lck);
307 #if KMP_USE_ADAPTIVE_LOCKS 309 struct kmp_adaptive_lock_info;
311 typedef struct kmp_adaptive_lock_info kmp_adaptive_lock_info_t;
313 #if KMP_DEBUG_ADAPTIVE_LOCKS 315 struct kmp_adaptive_lock_statistics {
317 kmp_adaptive_lock_info_t *next;
318 kmp_adaptive_lock_info_t *prev;
321 kmp_uint32 successfulSpeculations;
322 kmp_uint32 hardFailedSpeculations;
323 kmp_uint32 softFailedSpeculations;
324 kmp_uint32 nonSpeculativeAcquires;
325 kmp_uint32 nonSpeculativeAcquireAttempts;
326 kmp_uint32 lemmingYields;
329 typedef struct kmp_adaptive_lock_statistics kmp_adaptive_lock_statistics_t;
331 extern void __kmp_print_speculative_stats();
332 extern void __kmp_init_speculative_stats();
334 #endif // KMP_DEBUG_ADAPTIVE_LOCKS 336 struct kmp_adaptive_lock_info {
341 kmp_uint32
volatile badness;
342 kmp_uint32
volatile acquire_attempts;
344 kmp_uint32 max_badness;
345 kmp_uint32 max_soft_retries;
347 #if KMP_DEBUG_ADAPTIVE_LOCKS 348 kmp_adaptive_lock_statistics_t
volatile stats;
352 #endif // KMP_USE_ADAPTIVE_LOCKS 354 struct kmp_base_queuing_lock {
357 volatile union kmp_queuing_lock
375 volatile kmp_int32 owner_id;
376 kmp_int32 depth_locked;
378 kmp_lock_flags_t flags;
381 typedef struct kmp_base_queuing_lock kmp_base_queuing_lock_t;
383 KMP_BUILD_ASSERT(offsetof(kmp_base_queuing_lock_t, tail_id) % 8 == 0);
385 union KMP_ALIGN_CACHE kmp_queuing_lock {
386 kmp_base_queuing_lock_t
388 kmp_lock_pool_t pool;
390 char lk_pad[KMP_PAD(kmp_base_queuing_lock_t, CACHE_LINE)];
393 typedef union kmp_queuing_lock kmp_queuing_lock_t;
395 extern int __kmp_acquire_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid);
396 extern int __kmp_test_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid);
397 extern int __kmp_release_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid);
398 extern void __kmp_init_queuing_lock(kmp_queuing_lock_t *lck);
399 extern void __kmp_destroy_queuing_lock(kmp_queuing_lock_t *lck);
401 extern int __kmp_acquire_nested_queuing_lock(kmp_queuing_lock_t *lck,
403 extern int __kmp_test_nested_queuing_lock(kmp_queuing_lock_t *lck,
405 extern int __kmp_release_nested_queuing_lock(kmp_queuing_lock_t *lck,
407 extern void __kmp_init_nested_queuing_lock(kmp_queuing_lock_t *lck);
408 extern void __kmp_destroy_nested_queuing_lock(kmp_queuing_lock_t *lck);
410 #if KMP_USE_ADAPTIVE_LOCKS 414 struct kmp_base_adaptive_lock {
415 kmp_base_queuing_lock qlk;
416 KMP_ALIGN(CACHE_LINE)
417 kmp_adaptive_lock_info_t
421 typedef struct kmp_base_adaptive_lock kmp_base_adaptive_lock_t;
423 union KMP_ALIGN_CACHE kmp_adaptive_lock {
424 kmp_base_adaptive_lock_t lk;
425 kmp_lock_pool_t pool;
427 char lk_pad[KMP_PAD(kmp_base_adaptive_lock_t, CACHE_LINE)];
429 typedef union kmp_adaptive_lock kmp_adaptive_lock_t;
431 #define GET_QLK_PTR(l) ((kmp_queuing_lock_t *)&(l)->lk.qlk) 433 #endif // KMP_USE_ADAPTIVE_LOCKS 437 struct kmp_base_drdpa_lock {
446 volatile union kmp_drdpa_lock
449 std::atomic<std::atomic<kmp_uint64> *> polls;
450 std::atomic<kmp_uint64> mask;
451 kmp_uint64 cleanup_ticket;
452 std::atomic<kmp_uint64> *old_polls;
453 kmp_uint32 num_polls;
459 std::atomic<kmp_uint64> next_ticket;
474 kmp_uint64 now_serving;
475 volatile kmp_uint32 owner_id;
476 kmp_int32 depth_locked;
477 kmp_lock_flags_t flags;
480 typedef struct kmp_base_drdpa_lock kmp_base_drdpa_lock_t;
482 union KMP_ALIGN_CACHE kmp_drdpa_lock {
483 kmp_base_drdpa_lock_t
485 kmp_lock_pool_t pool;
487 char lk_pad[KMP_PAD(kmp_base_drdpa_lock_t, CACHE_LINE)];
490 typedef union kmp_drdpa_lock kmp_drdpa_lock_t;
492 extern int __kmp_acquire_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid);
493 extern int __kmp_test_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid);
494 extern int __kmp_release_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid);
495 extern void __kmp_init_drdpa_lock(kmp_drdpa_lock_t *lck);
496 extern void __kmp_destroy_drdpa_lock(kmp_drdpa_lock_t *lck);
498 extern int __kmp_acquire_nested_drdpa_lock(kmp_drdpa_lock_t *lck,
500 extern int __kmp_test_nested_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid);
501 extern int __kmp_release_nested_drdpa_lock(kmp_drdpa_lock_t *lck,
503 extern void __kmp_init_nested_drdpa_lock(kmp_drdpa_lock_t *lck);
504 extern void __kmp_destroy_nested_drdpa_lock(kmp_drdpa_lock_t *lck);
518 typedef kmp_ticket_lock_t kmp_bootstrap_lock_t;
520 #define KMP_BOOTSTRAP_LOCK_INITIALIZER(lock) KMP_TICKET_LOCK_INITIALIZER((lock)) 521 #define KMP_BOOTSTRAP_LOCK_INIT(lock) \ 522 kmp_bootstrap_lock_t lock = KMP_TICKET_LOCK_INITIALIZER(lock) 524 static inline int __kmp_acquire_bootstrap_lock(kmp_bootstrap_lock_t *lck) {
525 return __kmp_acquire_ticket_lock(lck, KMP_GTID_DNE);
528 static inline int __kmp_test_bootstrap_lock(kmp_bootstrap_lock_t *lck) {
529 return __kmp_test_ticket_lock(lck, KMP_GTID_DNE);
532 static inline void __kmp_release_bootstrap_lock(kmp_bootstrap_lock_t *lck) {
533 __kmp_release_ticket_lock(lck, KMP_GTID_DNE);
536 static inline void __kmp_init_bootstrap_lock(kmp_bootstrap_lock_t *lck) {
537 __kmp_init_ticket_lock(lck);
540 static inline void __kmp_destroy_bootstrap_lock(kmp_bootstrap_lock_t *lck) {
541 __kmp_destroy_ticket_lock(lck);
552 typedef kmp_ticket_lock_t kmp_lock_t;
554 #define KMP_LOCK_INIT(lock) kmp_lock_t lock = KMP_TICKET_LOCK_INITIALIZER(lock) 556 static inline int __kmp_acquire_lock(kmp_lock_t *lck, kmp_int32 gtid) {
557 return __kmp_acquire_ticket_lock(lck, gtid);
560 static inline int __kmp_test_lock(kmp_lock_t *lck, kmp_int32 gtid) {
561 return __kmp_test_ticket_lock(lck, gtid);
564 static inline void __kmp_release_lock(kmp_lock_t *lck, kmp_int32 gtid) {
565 __kmp_release_ticket_lock(lck, gtid);
568 static inline void __kmp_init_lock(kmp_lock_t *lck) {
569 __kmp_init_ticket_lock(lck);
572 static inline void __kmp_destroy_lock(kmp_lock_t *lck) {
573 __kmp_destroy_ticket_lock(lck);
589 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX 596 #if KMP_USE_ADAPTIVE_LOCKS 598 #endif // KMP_USE_ADAPTIVE_LOCKS 601 typedef enum kmp_lock_kind kmp_lock_kind_t;
603 extern kmp_lock_kind_t __kmp_user_lock_kind;
605 union kmp_user_lock {
608 kmp_futex_lock_t futex;
610 kmp_ticket_lock_t ticket;
611 kmp_queuing_lock_t queuing;
612 kmp_drdpa_lock_t drdpa;
613 #if KMP_USE_ADAPTIVE_LOCKS 614 kmp_adaptive_lock_t adaptive;
615 #endif // KMP_USE_ADAPTIVE_LOCKS 616 kmp_lock_pool_t pool;
619 typedef union kmp_user_lock *kmp_user_lock_p;
621 #if !KMP_USE_DYNAMIC_LOCK 623 extern size_t __kmp_base_user_lock_size;
624 extern size_t __kmp_user_lock_size;
626 extern kmp_int32 (*__kmp_get_user_lock_owner_)(kmp_user_lock_p lck);
628 static inline kmp_int32 __kmp_get_user_lock_owner(kmp_user_lock_p lck) {
629 KMP_DEBUG_ASSERT(__kmp_get_user_lock_owner_ != NULL);
630 return (*__kmp_get_user_lock_owner_)(lck);
633 extern int (*__kmp_acquire_user_lock_with_checks_)(kmp_user_lock_p lck,
636 #if KMP_OS_LINUX && \ 637 (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) 639 #define __kmp_acquire_user_lock_with_checks(lck, gtid) \ 640 if (__kmp_user_lock_kind == lk_tas) { \ 641 if (__kmp_env_consistency_check) { \ 642 char const *const func = "omp_set_lock"; \ 643 if ((sizeof(kmp_tas_lock_t) <= OMP_LOCK_T_SIZE) && \ 644 lck->tas.lk.depth_locked != -1) { \ 645 KMP_FATAL(LockNestableUsedAsSimple, func); \ 647 if ((gtid >= 0) && (lck->tas.lk.poll - 1 == gtid)) { \ 648 KMP_FATAL(LockIsAlreadyOwned, func); \ 651 if (lck->tas.lk.poll != 0 || \ 652 !__kmp_compare_and_store_acq(&lck->tas.lk.poll, 0, gtid + 1)) { \ 654 KMP_FSYNC_PREPARE(lck); \ 655 KMP_INIT_YIELD(spins); \ 656 if (TCR_4(__kmp_nth) > \ 657 (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc)) { \ 660 KMP_YIELD_SPIN(spins); \ 662 while (lck->tas.lk.poll != 0 || \ 663 !__kmp_compare_and_store_acq(&lck->tas.lk.poll, 0, gtid + 1)) { \ 664 if (TCR_4(__kmp_nth) > \ 665 (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc)) { \ 668 KMP_YIELD_SPIN(spins); \ 672 KMP_FSYNC_ACQUIRED(lck); \ 674 KMP_DEBUG_ASSERT(__kmp_acquire_user_lock_with_checks_ != NULL); \ 675 (*__kmp_acquire_user_lock_with_checks_)(lck, gtid); \ 679 static inline int __kmp_acquire_user_lock_with_checks(kmp_user_lock_p lck,
681 KMP_DEBUG_ASSERT(__kmp_acquire_user_lock_with_checks_ != NULL);
682 return (*__kmp_acquire_user_lock_with_checks_)(lck, gtid);
686 extern int (*__kmp_test_user_lock_with_checks_)(kmp_user_lock_p lck,
689 #if KMP_OS_LINUX && \ 690 (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) 692 #include "kmp_i18n.h" 693 extern int __kmp_env_consistency_check;
694 static inline int __kmp_test_user_lock_with_checks(kmp_user_lock_p lck,
696 if (__kmp_user_lock_kind == lk_tas) {
697 if (__kmp_env_consistency_check) {
698 char const *
const func =
"omp_test_lock";
699 if ((
sizeof(kmp_tas_lock_t) <= OMP_LOCK_T_SIZE) &&
700 lck->tas.lk.depth_locked != -1) {
701 KMP_FATAL(LockNestableUsedAsSimple, func);
704 return ((lck->tas.lk.poll == 0) &&
705 __kmp_compare_and_store_acq(&lck->tas.lk.poll, 0, gtid + 1));
707 KMP_DEBUG_ASSERT(__kmp_test_user_lock_with_checks_ != NULL);
708 return (*__kmp_test_user_lock_with_checks_)(lck, gtid);
712 static inline int __kmp_test_user_lock_with_checks(kmp_user_lock_p lck,
714 KMP_DEBUG_ASSERT(__kmp_test_user_lock_with_checks_ != NULL);
715 return (*__kmp_test_user_lock_with_checks_)(lck, gtid);
719 extern int (*__kmp_release_user_lock_with_checks_)(kmp_user_lock_p lck,
722 static inline void __kmp_release_user_lock_with_checks(kmp_user_lock_p lck,
724 KMP_DEBUG_ASSERT(__kmp_release_user_lock_with_checks_ != NULL);
725 (*__kmp_release_user_lock_with_checks_)(lck, gtid);
728 extern void (*__kmp_init_user_lock_with_checks_)(kmp_user_lock_p lck);
730 static inline void __kmp_init_user_lock_with_checks(kmp_user_lock_p lck) {
731 KMP_DEBUG_ASSERT(__kmp_init_user_lock_with_checks_ != NULL);
732 (*__kmp_init_user_lock_with_checks_)(lck);
737 extern void (*__kmp_destroy_user_lock_)(kmp_user_lock_p lck);
739 static inline void __kmp_destroy_user_lock(kmp_user_lock_p lck) {
740 KMP_DEBUG_ASSERT(__kmp_destroy_user_lock_ != NULL);
741 (*__kmp_destroy_user_lock_)(lck);
744 extern void (*__kmp_destroy_user_lock_with_checks_)(kmp_user_lock_p lck);
746 static inline void __kmp_destroy_user_lock_with_checks(kmp_user_lock_p lck) {
747 KMP_DEBUG_ASSERT(__kmp_destroy_user_lock_with_checks_ != NULL);
748 (*__kmp_destroy_user_lock_with_checks_)(lck);
751 extern int (*__kmp_acquire_nested_user_lock_with_checks_)(kmp_user_lock_p lck,
754 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64) 756 #define __kmp_acquire_nested_user_lock_with_checks(lck, gtid, depth) \ 757 if (__kmp_user_lock_kind == lk_tas) { \ 758 if (__kmp_env_consistency_check) { \ 759 char const *const func = "omp_set_nest_lock"; \ 760 if ((sizeof(kmp_tas_lock_t) <= OMP_NEST_LOCK_T_SIZE) && \ 761 lck->tas.lk.depth_locked == -1) { \ 762 KMP_FATAL(LockSimpleUsedAsNestable, func); \ 765 if (lck->tas.lk.poll - 1 == gtid) { \ 766 lck->tas.lk.depth_locked += 1; \ 767 *depth = KMP_LOCK_ACQUIRED_NEXT; \ 769 if ((lck->tas.lk.poll != 0) || \ 770 !__kmp_compare_and_store_acq(&lck->tas.lk.poll, 0, gtid + 1)) { \ 772 KMP_FSYNC_PREPARE(lck); \ 773 KMP_INIT_YIELD(spins); \ 774 if (TCR_4(__kmp_nth) > \ 775 (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc)) { \ 778 KMP_YIELD_SPIN(spins); \ 780 while ((lck->tas.lk.poll != 0) || \ 781 !__kmp_compare_and_store_acq(&lck->tas.lk.poll, 0, gtid + 1)) { \ 782 if (TCR_4(__kmp_nth) > \ 783 (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc)) { \ 786 KMP_YIELD_SPIN(spins); \ 790 lck->tas.lk.depth_locked = 1; \ 791 *depth = KMP_LOCK_ACQUIRED_FIRST; \ 793 KMP_FSYNC_ACQUIRED(lck); \ 795 KMP_DEBUG_ASSERT(__kmp_acquire_nested_user_lock_with_checks_ != NULL); \ 796 *depth = (*__kmp_acquire_nested_user_lock_with_checks_)(lck, gtid); \ 801 __kmp_acquire_nested_user_lock_with_checks(kmp_user_lock_p lck, kmp_int32 gtid,
803 KMP_DEBUG_ASSERT(__kmp_acquire_nested_user_lock_with_checks_ != NULL);
804 *depth = (*__kmp_acquire_nested_user_lock_with_checks_)(lck, gtid);
808 extern int (*__kmp_test_nested_user_lock_with_checks_)(kmp_user_lock_p lck,
811 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64) 812 static inline int __kmp_test_nested_user_lock_with_checks(kmp_user_lock_p lck,
814 if (__kmp_user_lock_kind == lk_tas) {
816 if (__kmp_env_consistency_check) {
817 char const *
const func =
"omp_test_nest_lock";
818 if ((
sizeof(kmp_tas_lock_t) <= OMP_NEST_LOCK_T_SIZE) &&
819 lck->tas.lk.depth_locked == -1) {
820 KMP_FATAL(LockSimpleUsedAsNestable, func);
823 KMP_DEBUG_ASSERT(gtid >= 0);
824 if (lck->tas.lk.poll - 1 ==
826 return ++lck->tas.lk.depth_locked;
828 retval = ((lck->tas.lk.poll == 0) &&
829 __kmp_compare_and_store_acq(&lck->tas.lk.poll, 0, gtid + 1));
832 lck->tas.lk.depth_locked = 1;
836 KMP_DEBUG_ASSERT(__kmp_test_nested_user_lock_with_checks_ != NULL);
837 return (*__kmp_test_nested_user_lock_with_checks_)(lck, gtid);
841 static inline int __kmp_test_nested_user_lock_with_checks(kmp_user_lock_p lck,
843 KMP_DEBUG_ASSERT(__kmp_test_nested_user_lock_with_checks_ != NULL);
844 return (*__kmp_test_nested_user_lock_with_checks_)(lck, gtid);
848 extern int (*__kmp_release_nested_user_lock_with_checks_)(kmp_user_lock_p lck,
852 __kmp_release_nested_user_lock_with_checks(kmp_user_lock_p lck,
854 KMP_DEBUG_ASSERT(__kmp_release_nested_user_lock_with_checks_ != NULL);
855 return (*__kmp_release_nested_user_lock_with_checks_)(lck, gtid);
858 extern void (*__kmp_init_nested_user_lock_with_checks_)(kmp_user_lock_p lck);
861 __kmp_init_nested_user_lock_with_checks(kmp_user_lock_p lck) {
862 KMP_DEBUG_ASSERT(__kmp_init_nested_user_lock_with_checks_ != NULL);
863 (*__kmp_init_nested_user_lock_with_checks_)(lck);
866 extern void (*__kmp_destroy_nested_user_lock_with_checks_)(kmp_user_lock_p lck);
869 __kmp_destroy_nested_user_lock_with_checks(kmp_user_lock_p lck) {
870 KMP_DEBUG_ASSERT(__kmp_destroy_nested_user_lock_with_checks_ != NULL);
871 (*__kmp_destroy_nested_user_lock_with_checks_)(lck);