45 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
47 # include <sys/syscall.h>
63 # define __kmp_static_delay( arg )
67 __kmp_static_delay(
int arg )
70 # if KMP_ARCH_X86_64 && KMP_OS_LINUX
71 KMP_ASSERT( arg != 0 );
73 KMP_ASSERT( arg >= 0 );
79 __kmp_static_yield(
int arg )
88 __kmp_validate_locks(
void )
94 x = ~((kmp_uint32) 0) - 2;
97 for (i = 0; i < 8; ++i, ++x, ++y) {
98 kmp_uint32 z = (x - y);
102 KMP_ASSERT( offsetof( kmp_base_queuing_lock, tail_id ) % 8 == 0 );
120 __kmp_get_tas_lock_owner( kmp_tas_lock_t *lck )
122 return TCR_4( lck->lk.poll ) - 1;
126 __kmp_is_tas_lock_nestable( kmp_tas_lock_t *lck )
128 return lck->lk.depth_locked != -1;
131 __forceinline
static void
132 __kmp_acquire_tas_lock_timed_template( kmp_tas_lock_t *lck, kmp_int32 gtid )
136 #ifdef USE_LOCK_PROFILE
137 kmp_uint32 curr = TCR_4( lck->lk.poll );
138 if ( ( curr != 0 ) && ( curr != gtid + 1 ) )
139 __kmp_printf(
"LOCK CONTENTION: %p\n", lck );
143 if ( KMP_COMPARE_AND_STORE_ACQ32( & ( lck->lk.poll ), 0, gtid + 1 ) ) {
144 KMP_FSYNC_ACQUIRED(lck);
149 KMP_FSYNC_PREPARE( lck );
150 KMP_INIT_YIELD( spins );
151 if ( TCR_4( __kmp_nth ) > ( __kmp_avail_proc ? __kmp_avail_proc :
156 KMP_YIELD_SPIN( spins );
159 while ( KMP_COMPARE_AND_STORE_ACQ32( & ( lck->lk.poll ), 0, gtid + 1 )
164 if ( TCR_4( __kmp_nth ) > ( __kmp_avail_proc ? __kmp_avail_proc :
169 KMP_YIELD_SPIN( spins );
172 KMP_FSYNC_ACQUIRED( lck );
176 __kmp_acquire_tas_lock( kmp_tas_lock_t *lck, kmp_int32 gtid )
178 __kmp_acquire_tas_lock_timed_template( lck, gtid );
182 __kmp_acquire_tas_lock_with_checks( kmp_tas_lock_t *lck, kmp_int32 gtid )
184 if ( __kmp_env_consistency_check ) {
185 char const *
const func =
"omp_set_lock";
186 if ( (
sizeof ( kmp_tas_lock_t ) <= OMP_LOCK_T_SIZE )
187 && __kmp_is_tas_lock_nestable( lck ) ) {
188 KMP_FATAL( LockNestableUsedAsSimple, func );
190 if ( ( gtid >= 0 ) && ( __kmp_get_tas_lock_owner( lck ) == gtid ) ) {
191 KMP_FATAL( LockIsAlreadyOwned, func );
194 __kmp_acquire_tas_lock( lck, gtid );
198 __kmp_test_tas_lock( kmp_tas_lock_t *lck, kmp_int32 gtid )
200 if ( KMP_COMPARE_AND_STORE_ACQ32( & ( lck->lk.poll ), 0, gtid + 1 ) ) {
201 KMP_FSYNC_ACQUIRED( lck );
208 __kmp_test_tas_lock_with_checks( kmp_tas_lock_t *lck, kmp_int32 gtid )
210 if ( __kmp_env_consistency_check ) {
211 char const *
const func =
"omp_test_lock";
212 if ( (
sizeof ( kmp_tas_lock_t ) <= OMP_LOCK_T_SIZE )
213 && __kmp_is_tas_lock_nestable( lck ) ) {
214 KMP_FATAL( LockNestableUsedAsSimple, func );
217 return __kmp_test_tas_lock( lck, gtid );
221 __kmp_release_tas_lock( kmp_tas_lock_t *lck, kmp_int32 gtid )
225 KMP_FSYNC_RELEASING(lck);
226 TCW_4( lck->lk.poll, 0 );
230 KMP_YIELD( TCR_4( __kmp_nth ) > ( __kmp_avail_proc ? __kmp_avail_proc :
235 __kmp_release_tas_lock_with_checks( kmp_tas_lock_t *lck, kmp_int32 gtid )
237 if ( __kmp_env_consistency_check ) {
238 char const *
const func =
"omp_unset_lock";
240 if ( (
sizeof ( kmp_tas_lock_t ) <= OMP_LOCK_T_SIZE )
241 && __kmp_is_tas_lock_nestable( lck ) ) {
242 KMP_FATAL( LockNestableUsedAsSimple, func );
244 if ( __kmp_get_tas_lock_owner( lck ) == -1 ) {
245 KMP_FATAL( LockUnsettingFree, func );
247 if ( ( gtid >= 0 ) && ( __kmp_get_tas_lock_owner( lck ) >= 0 )
248 && ( __kmp_get_tas_lock_owner( lck ) != gtid ) ) {
249 KMP_FATAL( LockUnsettingSetByAnother, func );
252 __kmp_release_tas_lock( lck, gtid );
256 __kmp_init_tas_lock( kmp_tas_lock_t * lck )
258 TCW_4( lck->lk.poll, 0 );
262 __kmp_init_tas_lock_with_checks( kmp_tas_lock_t * lck )
264 __kmp_init_tas_lock( lck );
268 __kmp_destroy_tas_lock( kmp_tas_lock_t *lck )
274 __kmp_destroy_tas_lock_with_checks( kmp_tas_lock_t *lck )
276 if ( __kmp_env_consistency_check ) {
277 char const *
const func =
"omp_destroy_lock";
278 if ( (
sizeof ( kmp_tas_lock_t ) <= OMP_LOCK_T_SIZE )
279 && __kmp_is_tas_lock_nestable( lck ) ) {
280 KMP_FATAL( LockNestableUsedAsSimple, func );
282 if ( __kmp_get_tas_lock_owner( lck ) != -1 ) {
283 KMP_FATAL( LockStillOwned, func );
286 __kmp_destroy_tas_lock( lck );
295 __kmp_acquire_nested_tas_lock( kmp_tas_lock_t *lck, kmp_int32 gtid )
297 KMP_DEBUG_ASSERT( gtid >= 0 );
299 if ( __kmp_get_tas_lock_owner( lck ) == gtid ) {
300 lck->lk.depth_locked += 1;
303 __kmp_acquire_tas_lock_timed_template( lck, gtid );
304 lck->lk.depth_locked = 1;
309 __kmp_acquire_nested_tas_lock_with_checks( kmp_tas_lock_t *lck, kmp_int32 gtid )
311 if ( __kmp_env_consistency_check ) {
312 char const *
const func =
"omp_set_nest_lock";
313 if ( ! __kmp_is_tas_lock_nestable( lck ) ) {
314 KMP_FATAL( LockSimpleUsedAsNestable, func );
317 __kmp_acquire_nested_tas_lock( lck, gtid );
321 __kmp_test_nested_tas_lock( kmp_tas_lock_t *lck, kmp_int32 gtid )
325 KMP_DEBUG_ASSERT( gtid >= 0 );
327 if ( __kmp_get_tas_lock_owner( lck ) == gtid ) {
328 retval = ++lck->lk.depth_locked;
330 else if ( !__kmp_test_tas_lock( lck, gtid ) ) {
335 retval = lck->lk.depth_locked = 1;
341 __kmp_test_nested_tas_lock_with_checks( kmp_tas_lock_t *lck, kmp_int32 gtid )
343 if ( __kmp_env_consistency_check ) {
344 char const *
const func =
"omp_test_nest_lock";
345 if ( ! __kmp_is_tas_lock_nestable( lck ) ) {
346 KMP_FATAL( LockSimpleUsedAsNestable, func );
349 return __kmp_test_nested_tas_lock( lck, gtid );
353 __kmp_release_nested_tas_lock( kmp_tas_lock_t *lck, kmp_int32 gtid )
355 KMP_DEBUG_ASSERT( gtid >= 0 );
358 if ( --(lck->lk.depth_locked) == 0 ) {
359 __kmp_release_tas_lock( lck, gtid );
364 __kmp_release_nested_tas_lock_with_checks( kmp_tas_lock_t *lck, kmp_int32 gtid )
366 if ( __kmp_env_consistency_check ) {
367 char const *
const func =
"omp_unset_nest_lock";
369 if ( ! __kmp_is_tas_lock_nestable( lck ) ) {
370 KMP_FATAL( LockSimpleUsedAsNestable, func );
372 if ( __kmp_get_tas_lock_owner( lck ) == -1 ) {
373 KMP_FATAL( LockUnsettingFree, func );
375 if ( __kmp_get_tas_lock_owner( lck ) != gtid ) {
376 KMP_FATAL( LockUnsettingSetByAnother, func );
379 __kmp_release_nested_tas_lock( lck, gtid );
383 __kmp_init_nested_tas_lock( kmp_tas_lock_t * lck )
385 __kmp_init_tas_lock( lck );
386 lck->lk.depth_locked = 0;
390 __kmp_init_nested_tas_lock_with_checks( kmp_tas_lock_t * lck )
392 __kmp_init_nested_tas_lock( lck );
396 __kmp_destroy_nested_tas_lock( kmp_tas_lock_t *lck )
398 __kmp_destroy_tas_lock( lck );
399 lck->lk.depth_locked = 0;
403 __kmp_destroy_nested_tas_lock_with_checks( kmp_tas_lock_t *lck )
405 if ( __kmp_env_consistency_check ) {
406 char const *
const func =
"omp_destroy_nest_lock";
407 if ( ! __kmp_is_tas_lock_nestable( lck ) ) {
408 KMP_FATAL( LockSimpleUsedAsNestable, func );
410 if ( __kmp_get_tas_lock_owner( lck ) != -1 ) {
411 KMP_FATAL( LockStillOwned, func );
414 __kmp_destroy_nested_tas_lock( lck );
418 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
429 __kmp_get_futex_lock_owner( kmp_futex_lock_t *lck )
431 return ( TCR_4( lck->lk.poll ) >> 1 ) - 1;
435 __kmp_is_futex_lock_nestable( kmp_futex_lock_t *lck )
437 return lck->lk.depth_locked != -1;
440 __forceinline
static void
441 __kmp_acquire_futex_lock_timed_template( kmp_futex_lock_t *lck, kmp_int32 gtid )
443 kmp_int32 gtid_code = ( gtid + 1 ) << 1;
447 #ifdef USE_LOCK_PROFILE
448 kmp_uint32 curr = TCR_4( lck->lk.poll );
449 if ( ( curr != 0 ) && ( curr != gtid_code ) )
450 __kmp_printf(
"LOCK CONTENTION: %p\n", lck );
454 KMP_FSYNC_PREPARE( lck );
455 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d entering\n",
456 lck, lck->lk.poll, gtid ) );
459 while ( ( poll_val = __kmp_compare_and_store_ret32( & ( lck->lk.poll ), 0,
460 gtid_code ) ) != 0 ) {
461 kmp_int32 cond = poll_val & 1;
462 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p, T#%d poll_val = 0x%x cond = 0x%x\n",
463 lck, gtid, poll_val, cond ) );
478 if ( ! __kmp_compare_and_store32( & ( lck->lk.poll ),
479 poll_val, poll_val | 1 ) ) {
480 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d can't set bit 0\n",
481 lck, lck->lk.poll, gtid ) );
486 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d bit 0 set\n",
487 lck, lck->lk.poll, gtid ) );
490 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p, T#%d before futex_wait(0x%x)\n",
491 lck, gtid, poll_val ) );
494 if ( ( rc = syscall( __NR_futex, & ( lck->lk.poll ), FUTEX_WAIT,
495 poll_val, NULL, NULL, 0 ) ) != 0 ) {
496 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p, T#%d futex_wait(0x%x) failed (rc=%d errno=%d)\n",
497 lck, gtid, poll_val, rc, errno ) );
501 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p, T#%d after futex_wait(0x%x)\n",
502 lck, gtid, poll_val ) );
512 KMP_FSYNC_ACQUIRED( lck );
513 KA_TRACE( 1000, (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d exiting\n",
514 lck, lck->lk.poll, gtid ) );
518 __kmp_acquire_futex_lock( kmp_futex_lock_t *lck, kmp_int32 gtid )
520 __kmp_acquire_futex_lock_timed_template( lck, gtid );
524 __kmp_acquire_futex_lock_with_checks( kmp_futex_lock_t *lck, kmp_int32 gtid )
526 if ( __kmp_env_consistency_check ) {
527 char const *
const func =
"omp_set_lock";
528 if ( (
sizeof ( kmp_futex_lock_t ) <= OMP_LOCK_T_SIZE )
529 && __kmp_is_futex_lock_nestable( lck ) ) {
530 KMP_FATAL( LockNestableUsedAsSimple, func );
532 if ( ( gtid >= 0 ) && ( __kmp_get_futex_lock_owner( lck ) == gtid ) ) {
533 KMP_FATAL( LockIsAlreadyOwned, func );
536 __kmp_acquire_futex_lock( lck, gtid );
540 __kmp_test_futex_lock( kmp_futex_lock_t *lck, kmp_int32 gtid )
542 if ( KMP_COMPARE_AND_STORE_ACQ32( & ( lck->lk.poll ), 0, ( gtid + 1 ) << 1 ) ) {
543 KMP_FSYNC_ACQUIRED( lck );
550 __kmp_test_futex_lock_with_checks( kmp_futex_lock_t *lck, kmp_int32 gtid )
552 if ( __kmp_env_consistency_check ) {
553 char const *
const func =
"omp_test_lock";
554 if ( (
sizeof ( kmp_futex_lock_t ) <= OMP_LOCK_T_SIZE )
555 && __kmp_is_futex_lock_nestable( lck ) ) {
556 KMP_FATAL( LockNestableUsedAsSimple, func );
559 return __kmp_test_futex_lock( lck, gtid );
563 __kmp_release_futex_lock( kmp_futex_lock_t *lck, kmp_int32 gtid )
567 KA_TRACE( 1000, (
"__kmp_release_futex_lock: lck:%p(0x%x), T#%d entering\n",
568 lck, lck->lk.poll, gtid ) );
570 KMP_FSYNC_RELEASING(lck);
572 kmp_int32 poll_val = __kmp_xchg_fixed32( & ( lck->lk.poll ), 0 );
574 KA_TRACE( 1000, (
"__kmp_release_futex_lock: lck:%p, T#%d released poll_val = 0x%x\n",
575 lck, gtid, poll_val ) );
577 if ( poll_val & 1 ) {
578 KA_TRACE( 1000, (
"__kmp_release_futex_lock: lck:%p, T#%d futex_wake 1 thread\n",
580 syscall( __NR_futex, & ( lck->lk.poll ), FUTEX_WAKE, 1, NULL, NULL, 0 );
585 KA_TRACE( 1000, (
"__kmp_release_futex_lock: lck:%p(0x%x), T#%d exiting\n",
586 lck, lck->lk.poll, gtid ) );
588 KMP_YIELD( TCR_4( __kmp_nth ) > ( __kmp_avail_proc ? __kmp_avail_proc :
593 __kmp_release_futex_lock_with_checks( kmp_futex_lock_t *lck, kmp_int32 gtid )
595 if ( __kmp_env_consistency_check ) {
596 char const *
const func =
"omp_unset_lock";
598 if ( (
sizeof ( kmp_futex_lock_t ) <= OMP_LOCK_T_SIZE )
599 && __kmp_is_futex_lock_nestable( lck ) ) {
600 KMP_FATAL( LockNestableUsedAsSimple, func );
602 if ( __kmp_get_futex_lock_owner( lck ) == -1 ) {
603 KMP_FATAL( LockUnsettingFree, func );
605 if ( ( gtid >= 0 ) && ( __kmp_get_futex_lock_owner( lck ) >= 0 )
606 && ( __kmp_get_futex_lock_owner( lck ) != gtid ) ) {
607 KMP_FATAL( LockUnsettingSetByAnother, func );
610 __kmp_release_futex_lock( lck, gtid );
614 __kmp_init_futex_lock( kmp_futex_lock_t * lck )
616 TCW_4( lck->lk.poll, 0 );
620 __kmp_init_futex_lock_with_checks( kmp_futex_lock_t * lck )
622 __kmp_init_futex_lock( lck );
626 __kmp_destroy_futex_lock( kmp_futex_lock_t *lck )
632 __kmp_destroy_futex_lock_with_checks( kmp_futex_lock_t *lck )
634 if ( __kmp_env_consistency_check ) {
635 char const *
const func =
"omp_destroy_lock";
636 if ( (
sizeof ( kmp_futex_lock_t ) <= OMP_LOCK_T_SIZE )
637 && __kmp_is_futex_lock_nestable( lck ) ) {
638 KMP_FATAL( LockNestableUsedAsSimple, func );
640 if ( __kmp_get_futex_lock_owner( lck ) != -1 ) {
641 KMP_FATAL( LockStillOwned, func );
644 __kmp_destroy_futex_lock( lck );
653 __kmp_acquire_nested_futex_lock( kmp_futex_lock_t *lck, kmp_int32 gtid )
655 KMP_DEBUG_ASSERT( gtid >= 0 );
657 if ( __kmp_get_futex_lock_owner( lck ) == gtid ) {
658 lck->lk.depth_locked += 1;
661 __kmp_acquire_futex_lock_timed_template( lck, gtid );
662 lck->lk.depth_locked = 1;
667 __kmp_acquire_nested_futex_lock_with_checks( kmp_futex_lock_t *lck, kmp_int32 gtid )
669 if ( __kmp_env_consistency_check ) {
670 char const *
const func =
"omp_set_nest_lock";
671 if ( ! __kmp_is_futex_lock_nestable( lck ) ) {
672 KMP_FATAL( LockSimpleUsedAsNestable, func );
675 __kmp_acquire_nested_futex_lock( lck, gtid );
679 __kmp_test_nested_futex_lock( kmp_futex_lock_t *lck, kmp_int32 gtid )
683 KMP_DEBUG_ASSERT( gtid >= 0 );
685 if ( __kmp_get_futex_lock_owner( lck ) == gtid ) {
686 retval = ++lck->lk.depth_locked;
688 else if ( !__kmp_test_futex_lock( lck, gtid ) ) {
693 retval = lck->lk.depth_locked = 1;
699 __kmp_test_nested_futex_lock_with_checks( kmp_futex_lock_t *lck, kmp_int32 gtid )
701 if ( __kmp_env_consistency_check ) {
702 char const *
const func =
"omp_test_nest_lock";
703 if ( ! __kmp_is_futex_lock_nestable( lck ) ) {
704 KMP_FATAL( LockSimpleUsedAsNestable, func );
707 return __kmp_test_nested_futex_lock( lck, gtid );
711 __kmp_release_nested_futex_lock( kmp_futex_lock_t *lck, kmp_int32 gtid )
713 KMP_DEBUG_ASSERT( gtid >= 0 );
716 if ( --(lck->lk.depth_locked) == 0 ) {
717 __kmp_release_futex_lock( lck, gtid );
722 __kmp_release_nested_futex_lock_with_checks( kmp_futex_lock_t *lck, kmp_int32 gtid )
724 if ( __kmp_env_consistency_check ) {
725 char const *
const func =
"omp_unset_nest_lock";
727 if ( ! __kmp_is_futex_lock_nestable( lck ) ) {
728 KMP_FATAL( LockSimpleUsedAsNestable, func );
730 if ( __kmp_get_futex_lock_owner( lck ) == -1 ) {
731 KMP_FATAL( LockUnsettingFree, func );
733 if ( __kmp_get_futex_lock_owner( lck ) != gtid ) {
734 KMP_FATAL( LockUnsettingSetByAnother, func );
737 __kmp_release_nested_futex_lock( lck, gtid );
741 __kmp_init_nested_futex_lock( kmp_futex_lock_t * lck )
743 __kmp_init_futex_lock( lck );
744 lck->lk.depth_locked = 0;
748 __kmp_init_nested_futex_lock_with_checks( kmp_futex_lock_t * lck )
750 __kmp_init_nested_futex_lock( lck );
754 __kmp_destroy_nested_futex_lock( kmp_futex_lock_t *lck )
756 __kmp_destroy_futex_lock( lck );
757 lck->lk.depth_locked = 0;
761 __kmp_destroy_nested_futex_lock_with_checks( kmp_futex_lock_t *lck )
763 if ( __kmp_env_consistency_check ) {
764 char const *
const func =
"omp_destroy_nest_lock";
765 if ( ! __kmp_is_futex_lock_nestable( lck ) ) {
766 KMP_FATAL( LockSimpleUsedAsNestable, func );
768 if ( __kmp_get_futex_lock_owner( lck ) != -1 ) {
769 KMP_FATAL( LockStillOwned, func );
772 __kmp_destroy_nested_futex_lock( lck );
775 #endif // KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
782 __kmp_get_ticket_lock_owner( kmp_ticket_lock_t *lck )
784 return TCR_4( lck->lk.owner_id ) - 1;
788 __kmp_is_ticket_lock_nestable( kmp_ticket_lock_t *lck )
790 return lck->lk.depth_locked != -1;
794 __kmp_bakery_check(kmp_uint value, kmp_uint checker)
796 register kmp_uint32 pause;
798 if (value == checker) {
801 for (pause = checker - value; pause != 0; --pause) {
802 __kmp_static_delay(TRUE);
807 __forceinline
static void
808 __kmp_acquire_ticket_lock_timed_template( kmp_ticket_lock_t *lck, kmp_int32 gtid )
810 kmp_uint32 my_ticket;
813 my_ticket = KMP_TEST_THEN_INC32( (kmp_int32 *) &lck->lk.next_ticket );
815 #ifdef USE_LOCK_PROFILE
816 if ( TCR_4( lck->lk.now_serving ) != my_ticket )
817 __kmp_printf(
"LOCK CONTENTION: %p\n", lck );
821 if ( TCR_4( lck->lk.now_serving ) == my_ticket ) {
822 KMP_FSYNC_ACQUIRED(lck);
825 KMP_WAIT_YIELD( &lck->lk.now_serving, my_ticket, __kmp_bakery_check, lck );
826 KMP_FSYNC_ACQUIRED(lck);
830 __kmp_acquire_ticket_lock( kmp_ticket_lock_t *lck, kmp_int32 gtid )
832 __kmp_acquire_ticket_lock_timed_template( lck, gtid );
836 __kmp_acquire_ticket_lock_with_checks( kmp_ticket_lock_t *lck, kmp_int32 gtid )
838 if ( __kmp_env_consistency_check ) {
839 char const *
const func =
"omp_set_lock";
840 if ( lck->lk.initialized != lck ) {
841 KMP_FATAL( LockIsUninitialized, func );
843 if ( __kmp_is_ticket_lock_nestable( lck ) ) {
844 KMP_FATAL( LockNestableUsedAsSimple, func );
846 if ( ( gtid >= 0 ) && ( __kmp_get_ticket_lock_owner( lck ) == gtid ) ) {
847 KMP_FATAL( LockIsAlreadyOwned, func );
851 __kmp_acquire_ticket_lock( lck, gtid );
853 if ( __kmp_env_consistency_check ) {
854 lck->lk.owner_id = gtid + 1;
859 __kmp_test_ticket_lock( kmp_ticket_lock_t *lck, kmp_int32 gtid )
861 kmp_uint32 my_ticket = TCR_4( lck->lk.next_ticket );
862 if ( TCR_4( lck->lk.now_serving ) == my_ticket ) {
863 kmp_uint32 next_ticket = my_ticket + 1;
864 if ( KMP_COMPARE_AND_STORE_ACQ32( (kmp_int32 *) &lck->lk.next_ticket,
865 my_ticket, next_ticket ) ) {
866 KMP_FSYNC_ACQUIRED( lck );
874 __kmp_test_ticket_lock_with_checks( kmp_ticket_lock_t *lck, kmp_int32 gtid )
876 if ( __kmp_env_consistency_check ) {
877 char const *
const func =
"omp_test_lock";
878 if ( lck->lk.initialized != lck ) {
879 KMP_FATAL( LockIsUninitialized, func );
881 if ( __kmp_is_ticket_lock_nestable( lck ) ) {
882 KMP_FATAL( LockNestableUsedAsSimple, func );
886 int retval = __kmp_test_ticket_lock( lck, gtid );
888 if ( __kmp_env_consistency_check && retval ) {
889 lck->lk.owner_id = gtid + 1;
895 __kmp_release_ticket_lock( kmp_ticket_lock_t *lck, kmp_int32 gtid )
901 KMP_FSYNC_RELEASING(lck);
902 distance = ( TCR_4( lck->lk.next_ticket ) - TCR_4( lck->lk.now_serving ) );
904 #if USE_ITT_BUILD && defined(USE_ITT)
905 TCW_4( lck->lk.now_serving, TCR_4( lck->lk.now_serving ) + 1 );
908 lck->lk.now_serving += 1;
915 > (kmp_uint32) (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc) );
919 __kmp_release_ticket_lock_with_checks( kmp_ticket_lock_t *lck, kmp_int32 gtid )
921 if ( __kmp_env_consistency_check ) {
922 char const *
const func =
"omp_unset_lock";
924 if ( lck->lk.initialized != lck ) {
925 KMP_FATAL( LockIsUninitialized, func );
927 if ( __kmp_is_ticket_lock_nestable( lck ) ) {
928 KMP_FATAL( LockNestableUsedAsSimple, func );
930 if ( __kmp_get_ticket_lock_owner( lck ) == -1 ) {
931 KMP_FATAL( LockUnsettingFree, func );
933 if ( ( gtid >= 0 ) && ( __kmp_get_ticket_lock_owner( lck ) >= 0 )
934 && ( __kmp_get_ticket_lock_owner( lck ) != gtid ) ) {
935 KMP_FATAL( LockUnsettingSetByAnother, func );
937 lck->lk.owner_id = 0;
939 __kmp_release_ticket_lock( lck, gtid );
943 __kmp_init_ticket_lock( kmp_ticket_lock_t * lck )
945 lck->lk.location = NULL;
946 TCW_4( lck->lk.next_ticket, 0 );
947 TCW_4( lck->lk.now_serving, 0 );
948 lck->lk.owner_id = 0;
949 lck->lk.depth_locked = -1;
950 lck->lk.initialized = (kmp_ticket_lock *)lck;
954 __kmp_init_ticket_lock_with_checks( kmp_ticket_lock_t * lck )
956 __kmp_init_ticket_lock( lck );
960 __kmp_destroy_ticket_lock( kmp_ticket_lock_t *lck )
962 lck->lk.initialized = NULL;
963 lck->lk.location = NULL;
964 lck->lk.next_ticket = 0;
965 lck->lk.now_serving = 0;
966 lck->lk.owner_id = 0;
967 lck->lk.depth_locked = -1;
971 __kmp_destroy_ticket_lock_with_checks( kmp_ticket_lock_t *lck )
973 if ( __kmp_env_consistency_check ) {
974 char const *
const func =
"omp_destroy_lock";
975 if ( lck->lk.initialized != lck ) {
976 KMP_FATAL( LockIsUninitialized, func );
978 if ( __kmp_is_ticket_lock_nestable( lck ) ) {
979 KMP_FATAL( LockNestableUsedAsSimple, func );
981 if ( __kmp_get_ticket_lock_owner( lck ) != -1 ) {
982 KMP_FATAL( LockStillOwned, func );
985 __kmp_destroy_ticket_lock( lck );
994 __kmp_acquire_nested_ticket_lock( kmp_ticket_lock_t *lck, kmp_int32 gtid )
996 KMP_DEBUG_ASSERT( gtid >= 0 );
998 if ( __kmp_get_ticket_lock_owner( lck ) == gtid ) {
999 lck->lk.depth_locked += 1;
1002 __kmp_acquire_ticket_lock_timed_template( lck, gtid );
1004 lck->lk.depth_locked = 1;
1006 lck->lk.owner_id = gtid + 1;
1011 __kmp_acquire_nested_ticket_lock_with_checks( kmp_ticket_lock_t *lck, kmp_int32 gtid )
1013 if ( __kmp_env_consistency_check ) {
1014 char const *
const func =
"omp_set_nest_lock";
1015 if ( lck->lk.initialized != lck ) {
1016 KMP_FATAL( LockIsUninitialized, func );
1018 if ( ! __kmp_is_ticket_lock_nestable( lck ) ) {
1019 KMP_FATAL( LockSimpleUsedAsNestable, func );
1022 __kmp_acquire_nested_ticket_lock( lck, gtid );
1026 __kmp_test_nested_ticket_lock( kmp_ticket_lock_t *lck, kmp_int32 gtid )
1030 KMP_DEBUG_ASSERT( gtid >= 0 );
1032 if ( __kmp_get_ticket_lock_owner( lck ) == gtid ) {
1033 retval = ++lck->lk.depth_locked;
1035 else if ( !__kmp_test_ticket_lock( lck, gtid ) ) {
1040 retval = lck->lk.depth_locked = 1;
1042 lck->lk.owner_id = gtid + 1;
1048 __kmp_test_nested_ticket_lock_with_checks( kmp_ticket_lock_t *lck,
1051 if ( __kmp_env_consistency_check ) {
1052 char const *
const func =
"omp_test_nest_lock";
1053 if ( lck->lk.initialized != lck ) {
1054 KMP_FATAL( LockIsUninitialized, func );
1056 if ( ! __kmp_is_ticket_lock_nestable( lck ) ) {
1057 KMP_FATAL( LockSimpleUsedAsNestable, func );
1060 return __kmp_test_nested_ticket_lock( lck, gtid );
1064 __kmp_release_nested_ticket_lock( kmp_ticket_lock_t *lck, kmp_int32 gtid )
1066 KMP_DEBUG_ASSERT( gtid >= 0 );
1069 if ( --(lck->lk.depth_locked) == 0 ) {
1071 lck->lk.owner_id = 0;
1072 __kmp_release_ticket_lock( lck, gtid );
1077 __kmp_release_nested_ticket_lock_with_checks( kmp_ticket_lock_t *lck, kmp_int32 gtid )
1079 if ( __kmp_env_consistency_check ) {
1080 char const *
const func =
"omp_unset_nest_lock";
1082 if ( lck->lk.initialized != lck ) {
1083 KMP_FATAL( LockIsUninitialized, func );
1085 if ( ! __kmp_is_ticket_lock_nestable( lck ) ) {
1086 KMP_FATAL( LockSimpleUsedAsNestable, func );
1088 if ( __kmp_get_ticket_lock_owner( lck ) == -1 ) {
1089 KMP_FATAL( LockUnsettingFree, func );
1091 if ( __kmp_get_ticket_lock_owner( lck ) != gtid ) {
1092 KMP_FATAL( LockUnsettingSetByAnother, func );
1095 __kmp_release_nested_ticket_lock( lck, gtid );
1099 __kmp_init_nested_ticket_lock( kmp_ticket_lock_t * lck )
1101 __kmp_init_ticket_lock( lck );
1102 lck->lk.depth_locked = 0;
1106 __kmp_init_nested_ticket_lock_with_checks( kmp_ticket_lock_t * lck )
1108 __kmp_init_nested_ticket_lock( lck );
1112 __kmp_destroy_nested_ticket_lock( kmp_ticket_lock_t *lck )
1114 __kmp_destroy_ticket_lock( lck );
1115 lck->lk.depth_locked = 0;
1119 __kmp_destroy_nested_ticket_lock_with_checks( kmp_ticket_lock_t *lck )
1121 if ( __kmp_env_consistency_check ) {
1122 char const *
const func =
"omp_destroy_nest_lock";
1123 if ( lck->lk.initialized != lck ) {
1124 KMP_FATAL( LockIsUninitialized, func );
1126 if ( ! __kmp_is_ticket_lock_nestable( lck ) ) {
1127 KMP_FATAL( LockSimpleUsedAsNestable, func );
1129 if ( __kmp_get_ticket_lock_owner( lck ) != -1 ) {
1130 KMP_FATAL( LockStillOwned, func );
1133 __kmp_destroy_nested_ticket_lock( lck );
1142 __kmp_is_ticket_lock_initialized( kmp_ticket_lock_t *lck )
1144 return lck == lck->lk.initialized;
1148 __kmp_get_ticket_lock_location( kmp_ticket_lock_t *lck )
1150 return lck->lk.location;
1154 __kmp_set_ticket_lock_location( kmp_ticket_lock_t *lck,
const ident_t *loc )
1156 lck->lk.location = loc;
1159 static kmp_lock_flags_t
1160 __kmp_get_ticket_lock_flags( kmp_ticket_lock_t *lck )
1162 return lck->lk.flags;
1166 __kmp_set_ticket_lock_flags( kmp_ticket_lock_t *lck, kmp_lock_flags_t flags )
1168 lck->lk.flags = flags;
1227 #ifdef DEBUG_QUEUING_LOCKS
1230 #define TRACE_BUF_ELE 1024
1231 static char traces[TRACE_BUF_ELE][128] = { 0 }
1233 #define TRACE_LOCK(X,Y) sprintf( traces[tc++ % TRACE_BUF_ELE], "t%d at %s\n", X, Y );
1234 #define TRACE_LOCK_T(X,Y,Z) sprintf( traces[tc++ % TRACE_BUF_ELE], "t%d at %s%d\n", X,Y,Z );
1235 #define TRACE_LOCK_HT(X,Y,Z,Q) sprintf( traces[tc++ % TRACE_BUF_ELE], "t%d at %s %d,%d\n", X, Y, Z, Q );
1238 __kmp_dump_queuing_lock( kmp_info_t *this_thr, kmp_int32 gtid,
1239 kmp_queuing_lock_t *lck, kmp_int32 head_id, kmp_int32 tail_id )
1243 __kmp_printf_no_lock(
"\n__kmp_dump_queuing_lock: TRACE BEGINS HERE! \n" );
1245 i = tc % TRACE_BUF_ELE;
1246 __kmp_printf_no_lock(
"%s\n", traces[i] );
1247 i = (i+1) % TRACE_BUF_ELE;
1248 while ( i != (tc % TRACE_BUF_ELE) ) {
1249 __kmp_printf_no_lock(
"%s", traces[i] );
1250 i = (i+1) % TRACE_BUF_ELE;
1252 __kmp_printf_no_lock(
"\n" );
1254 __kmp_printf_no_lock(
1255 "\n__kmp_dump_queuing_lock: gtid+1:%d, spin_here:%d, next_wait:%d, head_id:%d, tail_id:%d\n",
1256 gtid+1, this_thr->th.th_spin_here, this_thr->th.th_next_waiting,
1259 __kmp_printf_no_lock(
"\t\thead: %d ", lck->lk.head_id );
1261 if ( lck->lk.head_id >= 1 ) {
1262 t = __kmp_threads[lck->lk.head_id-1]->th.th_next_waiting;
1264 __kmp_printf_no_lock(
"-> %d ", t );
1265 t = __kmp_threads[t-1]->th.th_next_waiting;
1268 __kmp_printf_no_lock(
"; tail: %d ", lck->lk.tail_id );
1269 __kmp_printf_no_lock(
"\n\n" );
1275 __kmp_get_queuing_lock_owner( kmp_queuing_lock_t *lck )
1277 return TCR_4( lck->lk.owner_id ) - 1;
1281 __kmp_is_queuing_lock_nestable( kmp_queuing_lock_t *lck )
1283 return lck->lk.depth_locked != -1;
1287 template <
bool takeTime>
1290 __forceinline
static void
1291 __kmp_acquire_queuing_lock_timed_template( kmp_queuing_lock_t *lck,
1294 register kmp_info_t *this_thr = __kmp_thread_from_gtid( gtid );
1295 volatile kmp_int32 *head_id_p = & lck->lk.head_id;
1296 volatile kmp_int32 *tail_id_p = & lck->lk.tail_id;
1297 volatile kmp_uint32 *spin_here_p;
1298 kmp_int32 need_mf = 1;
1300 KA_TRACE( 1000, (
"__kmp_acquire_queuing_lock: lck:%p, T#%d entering\n", lck, gtid ));
1302 KMP_FSYNC_PREPARE( lck );
1303 KMP_DEBUG_ASSERT( this_thr != NULL );
1304 spin_here_p = & this_thr->th.th_spin_here;
1306 #ifdef DEBUG_QUEUING_LOCKS
1307 TRACE_LOCK( gtid+1,
"acq ent" );
1309 __kmp_dump_queuing_lock( this_thr, gtid, lck, *head_id_p, *tail_id_p );
1310 if ( this_thr->th.th_next_waiting != 0 )
1311 __kmp_dump_queuing_lock( this_thr, gtid, lck, *head_id_p, *tail_id_p );
1313 KMP_DEBUG_ASSERT( !*spin_here_p );
1314 KMP_DEBUG_ASSERT( this_thr->th.th_next_waiting == 0 );
1324 *spin_here_p = TRUE;
1337 #ifdef DEBUG_QUEUING_LOCKS
1339 TRACE_LOCK_HT( gtid+1,
"acq read: ", head, tail );
1348 enqueued = KMP_COMPARE_AND_STORE_ACQ64( (
volatile kmp_int64 *) tail_id_p,
1349 KMP_PACK_64( -1, 0 ),
1350 KMP_PACK_64( gtid+1, gtid+1 ) );
1351 #ifdef DEBUG_QUEUING_LOCKS
1352 if ( enqueued ) TRACE_LOCK( gtid+1,
"acq enq: (-1,0)->(tid,tid)" );
1360 KMP_DEBUG_ASSERT( tail != gtid + 1 );
1362 #ifdef DEBUG_QUEUING_LOCKS
1363 TRACE_LOCK_HT( gtid+1,
"acq read: ", head, tail );
1372 enqueued = KMP_COMPARE_AND_STORE_ACQ32( tail_id_p, tail, gtid+1 );
1374 #ifdef DEBUG_QUEUING_LOCKS
1375 if ( enqueued ) TRACE_LOCK( gtid+1,
"acq enq: (h,t)->(h,tid)" );
1383 kmp_int32 grabbed_lock;
1385 #ifdef DEBUG_QUEUING_LOCKS
1387 TRACE_LOCK_HT( gtid+1,
"acq read: ", head, tail );
1392 grabbed_lock = KMP_COMPARE_AND_STORE_ACQ32( head_id_p, 0, -1 );
1394 if ( grabbed_lock ) {
1396 *spin_here_p = FALSE;
1398 KA_TRACE( 1000, (
"__kmp_acquire_queuing_lock: lck:%p, T#%d exiting: no queuing\n",
1400 #ifdef DEBUG_QUEUING_LOCKS
1401 TRACE_LOCK_HT( gtid+1,
"acq exit: ", head, 0 );
1403 KMP_FSYNC_ACQUIRED( lck );
1413 kmp_info_t *tail_thr = __kmp_thread_from_gtid( tail - 1 );
1414 KMP_ASSERT( tail_thr != NULL );
1415 tail_thr->th.th_next_waiting = gtid+1;
1418 KA_TRACE( 1000, (
"__kmp_acquire_queuing_lock: lck:%p, T#%d waiting for lock\n", lck, gtid ));
1425 KMP_WAIT_YIELD(spin_here_p, FALSE, KMP_EQ, lck);
1427 #ifdef DEBUG_QUEUING_LOCKS
1428 TRACE_LOCK( gtid+1,
"acq spin" );
1430 if ( this_thr->th.th_next_waiting != 0 )
1431 __kmp_dump_queuing_lock( this_thr, gtid, lck, *head_id_p, *tail_id_p );
1433 KMP_DEBUG_ASSERT( this_thr->th.th_next_waiting == 0 );
1434 KA_TRACE( 1000, (
"__kmp_acquire_queuing_lock: lck:%p, T#%d exiting: after waiting on queue\n",
1437 #ifdef DEBUG_QUEUING_LOCKS
1438 TRACE_LOCK( gtid+1,
"acq exit 2" );
1447 KMP_YIELD( TCR_4( __kmp_nth ) > (__kmp_avail_proc ? __kmp_avail_proc :
1449 #ifdef DEBUG_QUEUING_LOCKS
1450 TRACE_LOCK( gtid+1,
"acq retry" );
1454 KMP_ASSERT2( 0,
"should not get here" );
1458 __kmp_acquire_queuing_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1460 KMP_DEBUG_ASSERT( gtid >= 0 );
1462 __kmp_acquire_queuing_lock_timed_template<false>( lck, gtid );
1466 __kmp_acquire_queuing_lock_with_checks( kmp_queuing_lock_t *lck,
1469 if ( __kmp_env_consistency_check ) {
1470 char const *
const func =
"omp_set_lock";
1471 if ( lck->lk.initialized != lck ) {
1472 KMP_FATAL( LockIsUninitialized, func );
1474 if ( __kmp_is_queuing_lock_nestable( lck ) ) {
1475 KMP_FATAL( LockNestableUsedAsSimple, func );
1477 if ( __kmp_get_queuing_lock_owner( lck ) == gtid ) {
1478 KMP_FATAL( LockIsAlreadyOwned, func );
1482 __kmp_acquire_queuing_lock( lck, gtid );
1484 if ( __kmp_env_consistency_check ) {
1485 lck->lk.owner_id = gtid + 1;
1490 __kmp_test_queuing_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1492 volatile kmp_int32 *head_id_p = & lck->lk.head_id;
1495 kmp_info_t *this_thr;
1498 KA_TRACE( 1000, (
"__kmp_test_queuing_lock: T#%d entering\n", gtid ));
1499 KMP_DEBUG_ASSERT( gtid >= 0 );
1501 this_thr = __kmp_thread_from_gtid( gtid );
1502 KMP_DEBUG_ASSERT( this_thr != NULL );
1503 KMP_DEBUG_ASSERT( !this_thr->th.th_spin_here );
1512 if ( KMP_COMPARE_AND_STORE_ACQ32( head_id_p, 0, -1 ) ) {
1513 KA_TRACE( 1000, (
"__kmp_test_queuing_lock: T#%d exiting: holding lock\n", gtid ));
1514 KMP_FSYNC_ACQUIRED(lck);
1519 KA_TRACE( 1000, (
"__kmp_test_queuing_lock: T#%d exiting: without lock\n", gtid ));
1524 __kmp_test_queuing_lock_with_checks( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1526 if ( __kmp_env_consistency_check ) {
1527 char const *
const func =
"omp_test_lock";
1528 if ( lck->lk.initialized != lck ) {
1529 KMP_FATAL( LockIsUninitialized, func );
1531 if ( __kmp_is_queuing_lock_nestable( lck ) ) {
1532 KMP_FATAL( LockNestableUsedAsSimple, func );
1536 int retval = __kmp_test_queuing_lock( lck, gtid );
1538 if ( __kmp_env_consistency_check && retval ) {
1539 lck->lk.owner_id = gtid + 1;
1545 __kmp_release_queuing_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1547 register kmp_info_t *this_thr;
1548 volatile kmp_int32 *head_id_p = & lck->lk.head_id;
1549 volatile kmp_int32 *tail_id_p = & lck->lk.tail_id;
1551 KA_TRACE( 1000, (
"__kmp_release_queuing_lock: lck:%p, T#%d entering\n", lck, gtid ));
1552 KMP_DEBUG_ASSERT( gtid >= 0 );
1553 this_thr = __kmp_thread_from_gtid( gtid );
1554 KMP_DEBUG_ASSERT( this_thr != NULL );
1555 #ifdef DEBUG_QUEUING_LOCKS
1556 TRACE_LOCK( gtid+1,
"rel ent" );
1558 if ( this_thr->th.th_spin_here )
1559 __kmp_dump_queuing_lock( this_thr, gtid, lck, *head_id_p, *tail_id_p );
1560 if ( this_thr->th.th_next_waiting != 0 )
1561 __kmp_dump_queuing_lock( this_thr, gtid, lck, *head_id_p, *tail_id_p );
1563 KMP_DEBUG_ASSERT( !this_thr->th.th_spin_here );
1564 KMP_DEBUG_ASSERT( this_thr->th.th_next_waiting == 0 );
1566 KMP_FSYNC_RELEASING(lck);
1575 #ifdef DEBUG_QUEUING_LOCKS
1577 TRACE_LOCK_HT( gtid+1,
"rel read: ", head, tail );
1578 if ( head == 0 ) __kmp_dump_queuing_lock( this_thr, gtid, lck, head, tail );
1580 KMP_DEBUG_ASSERT( head != 0 );
1585 if ( KMP_COMPARE_AND_STORE_REL32( head_id_p, -1, 0 ) ) {
1586 KA_TRACE( 1000, (
"__kmp_release_queuing_lock: lck:%p, T#%d exiting: queue empty\n",
1588 #ifdef DEBUG_QUEUING_LOCKS
1589 TRACE_LOCK_HT( gtid+1,
"rel exit: ", 0, 0 );
1599 if ( head == tail ) {
1601 #ifdef DEBUG_QUEUING_LOCKS
1602 if ( head <= 0 ) __kmp_dump_queuing_lock( this_thr, gtid, lck, head, tail );
1604 KMP_DEBUG_ASSERT( head > 0 );
1607 dequeued = KMP_COMPARE_AND_STORE_REL64( (kmp_int64 *) tail_id_p,
1608 KMP_PACK_64( head, head ), KMP_PACK_64( -1, 0 ) );
1609 #ifdef DEBUG_QUEUING_LOCKS
1610 TRACE_LOCK( gtid+1,
"rel deq: (h,h)->(-1,0)" );
1615 volatile kmp_int32 *waiting_id_p;
1616 kmp_info_t *head_thr = __kmp_thread_from_gtid( head - 1 );
1617 KMP_DEBUG_ASSERT( head_thr != NULL );
1618 waiting_id_p = & head_thr->th.th_next_waiting;
1621 #ifdef DEBUG_QUEUING_LOCKS
1622 if ( head <= 0 || tail <= 0 ) __kmp_dump_queuing_lock( this_thr, gtid, lck, head, tail );
1624 KMP_DEBUG_ASSERT( head > 0 && tail > 0 );
1630 *head_id_p = (kmp_int32) KMP_WAIT_YIELD((
volatile kmp_uint*) waiting_id_p, 0, KMP_NEQ, NULL);
1631 #ifdef DEBUG_QUEUING_LOCKS
1632 TRACE_LOCK( gtid+1,
"rel deq: (h,t)->(h',t)" );
1639 kmp_info_t *head_thr = __kmp_thread_from_gtid( head - 1 );
1640 KMP_DEBUG_ASSERT( head_thr != NULL );
1643 #ifdef DEBUG_QUEUING_LOCKS
1644 if ( head <= 0 || tail <= 0 ) __kmp_dump_queuing_lock( this_thr, gtid, lck, head, tail );
1646 KMP_DEBUG_ASSERT( head > 0 && tail > 0 );
1651 head_thr->th.th_next_waiting = 0;
1652 #ifdef DEBUG_QUEUING_LOCKS
1653 TRACE_LOCK_T( gtid+1,
"rel nw=0 for t=", head );
1658 head_thr->th.th_spin_here = FALSE;
1660 KA_TRACE( 1000, (
"__kmp_release_queuing_lock: lck:%p, T#%d exiting: after dequeuing\n",
1662 #ifdef DEBUG_QUEUING_LOCKS
1663 TRACE_LOCK( gtid+1,
"rel exit 2" );
1669 #ifdef DEBUG_QUEUING_LOCKS
1670 TRACE_LOCK( gtid+1,
"rel retry" );
1674 KMP_ASSERT2( 0,
"should not get here" );
1678 __kmp_release_queuing_lock_with_checks( kmp_queuing_lock_t *lck,
1681 if ( __kmp_env_consistency_check ) {
1682 char const *
const func =
"omp_unset_lock";
1684 if ( lck->lk.initialized != lck ) {
1685 KMP_FATAL( LockIsUninitialized, func );
1687 if ( __kmp_is_queuing_lock_nestable( lck ) ) {
1688 KMP_FATAL( LockNestableUsedAsSimple, func );
1690 if ( __kmp_get_queuing_lock_owner( lck ) == -1 ) {
1691 KMP_FATAL( LockUnsettingFree, func );
1693 if ( __kmp_get_queuing_lock_owner( lck ) != gtid ) {
1694 KMP_FATAL( LockUnsettingSetByAnother, func );
1696 lck->lk.owner_id = 0;
1698 __kmp_release_queuing_lock( lck, gtid );
1702 __kmp_init_queuing_lock( kmp_queuing_lock_t *lck )
1704 lck->lk.location = NULL;
1705 lck->lk.head_id = 0;
1706 lck->lk.tail_id = 0;
1707 lck->lk.next_ticket = 0;
1708 lck->lk.now_serving = 0;
1709 lck->lk.owner_id = 0;
1710 lck->lk.depth_locked = -1;
1711 lck->lk.initialized = lck;
1713 KA_TRACE(1000, (
"__kmp_init_queuing_lock: lock %p initialized\n", lck));
1717 __kmp_init_queuing_lock_with_checks( kmp_queuing_lock_t * lck )
1719 __kmp_init_queuing_lock( lck );
1723 __kmp_destroy_queuing_lock( kmp_queuing_lock_t *lck )
1725 lck->lk.initialized = NULL;
1726 lck->lk.location = NULL;
1727 lck->lk.head_id = 0;
1728 lck->lk.tail_id = 0;
1729 lck->lk.next_ticket = 0;
1730 lck->lk.now_serving = 0;
1731 lck->lk.owner_id = 0;
1732 lck->lk.depth_locked = -1;
1736 __kmp_destroy_queuing_lock_with_checks( kmp_queuing_lock_t *lck )
1738 if ( __kmp_env_consistency_check ) {
1739 char const *
const func =
"omp_destroy_lock";
1740 if ( lck->lk.initialized != lck ) {
1741 KMP_FATAL( LockIsUninitialized, func );
1743 if ( __kmp_is_queuing_lock_nestable( lck ) ) {
1744 KMP_FATAL( LockNestableUsedAsSimple, func );
1746 if ( __kmp_get_queuing_lock_owner( lck ) != -1 ) {
1747 KMP_FATAL( LockStillOwned, func );
1750 __kmp_destroy_queuing_lock( lck );
1759 __kmp_acquire_nested_queuing_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1761 KMP_DEBUG_ASSERT( gtid >= 0 );
1763 if ( __kmp_get_queuing_lock_owner( lck ) == gtid ) {
1764 lck->lk.depth_locked += 1;
1767 __kmp_acquire_queuing_lock_timed_template<false>( lck, gtid );
1769 lck->lk.depth_locked = 1;
1771 lck->lk.owner_id = gtid + 1;
1776 __kmp_acquire_nested_queuing_lock_with_checks( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1778 if ( __kmp_env_consistency_check ) {
1779 char const *
const func =
"omp_set_nest_lock";
1780 if ( lck->lk.initialized != lck ) {
1781 KMP_FATAL( LockIsUninitialized, func );
1783 if ( ! __kmp_is_queuing_lock_nestable( lck ) ) {
1784 KMP_FATAL( LockSimpleUsedAsNestable, func );
1787 __kmp_acquire_nested_queuing_lock( lck, gtid );
1791 __kmp_test_nested_queuing_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1795 KMP_DEBUG_ASSERT( gtid >= 0 );
1797 if ( __kmp_get_queuing_lock_owner( lck ) == gtid ) {
1798 retval = ++lck->lk.depth_locked;
1800 else if ( !__kmp_test_queuing_lock( lck, gtid ) ) {
1805 retval = lck->lk.depth_locked = 1;
1807 lck->lk.owner_id = gtid + 1;
1813 __kmp_test_nested_queuing_lock_with_checks( kmp_queuing_lock_t *lck,
1816 if ( __kmp_env_consistency_check ) {
1817 char const *
const func =
"omp_test_nest_lock";
1818 if ( lck->lk.initialized != lck ) {
1819 KMP_FATAL( LockIsUninitialized, func );
1821 if ( ! __kmp_is_queuing_lock_nestable( lck ) ) {
1822 KMP_FATAL( LockSimpleUsedAsNestable, func );
1825 return __kmp_test_nested_queuing_lock( lck, gtid );
1829 __kmp_release_nested_queuing_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1831 KMP_DEBUG_ASSERT( gtid >= 0 );
1834 if ( --(lck->lk.depth_locked) == 0 ) {
1836 lck->lk.owner_id = 0;
1837 __kmp_release_queuing_lock( lck, gtid );
1842 __kmp_release_nested_queuing_lock_with_checks( kmp_queuing_lock_t *lck, kmp_int32 gtid )
1844 if ( __kmp_env_consistency_check ) {
1845 char const *
const func =
"omp_unset_nest_lock";
1847 if ( lck->lk.initialized != lck ) {
1848 KMP_FATAL( LockIsUninitialized, func );
1850 if ( ! __kmp_is_queuing_lock_nestable( lck ) ) {
1851 KMP_FATAL( LockSimpleUsedAsNestable, func );
1853 if ( __kmp_get_queuing_lock_owner( lck ) == -1 ) {
1854 KMP_FATAL( LockUnsettingFree, func );
1856 if ( __kmp_get_queuing_lock_owner( lck ) != gtid ) {
1857 KMP_FATAL( LockUnsettingSetByAnother, func );
1860 __kmp_release_nested_queuing_lock( lck, gtid );
1864 __kmp_init_nested_queuing_lock( kmp_queuing_lock_t * lck )
1866 __kmp_init_queuing_lock( lck );
1867 lck->lk.depth_locked = 0;
1871 __kmp_init_nested_queuing_lock_with_checks( kmp_queuing_lock_t * lck )
1873 __kmp_init_nested_queuing_lock( lck );
1877 __kmp_destroy_nested_queuing_lock( kmp_queuing_lock_t *lck )
1879 __kmp_destroy_queuing_lock( lck );
1880 lck->lk.depth_locked = 0;
1884 __kmp_destroy_nested_queuing_lock_with_checks( kmp_queuing_lock_t *lck )
1886 if ( __kmp_env_consistency_check ) {
1887 char const *
const func =
"omp_destroy_nest_lock";
1888 if ( lck->lk.initialized != lck ) {
1889 KMP_FATAL( LockIsUninitialized, func );
1891 if ( ! __kmp_is_queuing_lock_nestable( lck ) ) {
1892 KMP_FATAL( LockSimpleUsedAsNestable, func );
1894 if ( __kmp_get_queuing_lock_owner( lck ) != -1 ) {
1895 KMP_FATAL( LockStillOwned, func );
1898 __kmp_destroy_nested_queuing_lock( lck );
1907 __kmp_is_queuing_lock_initialized( kmp_queuing_lock_t *lck )
1909 return lck == lck->lk.initialized;
1913 __kmp_get_queuing_lock_location( kmp_queuing_lock_t *lck )
1915 return lck->lk.location;
1919 __kmp_set_queuing_lock_location( kmp_queuing_lock_t *lck,
const ident_t *loc )
1921 lck->lk.location = loc;
1924 static kmp_lock_flags_t
1925 __kmp_get_queuing_lock_flags( kmp_queuing_lock_t *lck )
1927 return lck->lk.flags;
1931 __kmp_set_queuing_lock_flags( kmp_queuing_lock_t *lck, kmp_lock_flags_t flags )
1933 lck->lk.flags = flags;
1936 #if KMP_USE_ADAPTIVE_LOCKS
1946 #define _XBEGIN_STARTED (~0u)
1947 #define _XABORT_EXPLICIT (1 << 0)
1948 #define _XABORT_RETRY (1 << 1)
1949 #define _XABORT_CONFLICT (1 << 2)
1950 #define _XABORT_CAPACITY (1 << 3)
1951 #define _XABORT_DEBUG (1 << 4)
1952 #define _XABORT_NESTED (1 << 5)
1953 #define _XABORT_CODE(x) ((unsigned char)(((x) >> 24) & 0xFF))
1956 #define SOFT_ABORT_MASK (_XABORT_RETRY | _XABORT_CONFLICT | _XABORT_EXPLICIT)
1958 #define STRINGIZE_INTERNAL(arg) #arg
1959 #define STRINGIZE(arg) STRINGIZE_INTERNAL(arg)
1967 static __inline
int _xbegin()
1996 #endif // KMP_ARCH_X86_64
2006 __asm__
volatile (
"1: .byte 0xC7; .byte 0xF8;\n"
2009 "1: movl %%eax,%0\n"
2011 :
"+r"(res)::
"memory",
"%eax");
2012 #endif // KMP_OS_WINDOWS
2019 static __inline
void _xend()
2028 __asm__
volatile (
".byte 0x0f; .byte 0x01; .byte 0xd5" :::
"memory");
2038 #define _xabort(ARG) \
2043 #define _xabort(ARG) \
2044 __asm__ volatile (".byte 0xC6; .byte 0xF8; .byte " STRINGIZE(ARG) :::"memory");
2050 #if KMP_DEBUG_ADAPTIVE_LOCKS
2055 static kmp_adaptive_lock_statistics_t destroyedStats;
2058 static kmp_adaptive_lock_t liveLocks;
2061 static kmp_bootstrap_lock_t chain_lock;
2065 __kmp_init_speculative_stats()
2067 kmp_adaptive_lock *lck = &liveLocks;
2069 memset( (
void * ) & ( lck->stats ), 0,
sizeof( lck->stats ) );
2070 lck->stats.next = lck;
2071 lck->stats.prev = lck;
2073 KMP_ASSERT( lck->stats.next->stats.prev == lck );
2074 KMP_ASSERT( lck->stats.prev->stats.next == lck );
2076 __kmp_init_bootstrap_lock( &chain_lock );
2082 __kmp_remember_lock( kmp_adaptive_lock * lck )
2084 __kmp_acquire_bootstrap_lock( &chain_lock );
2086 lck->stats.next = liveLocks.stats.next;
2087 lck->stats.prev = &liveLocks;
2089 liveLocks.stats.next = lck;
2090 lck->stats.next->stats.prev = lck;
2092 KMP_ASSERT( lck->stats.next->stats.prev == lck );
2093 KMP_ASSERT( lck->stats.prev->stats.next == lck );
2095 __kmp_release_bootstrap_lock( &chain_lock );
2099 __kmp_forget_lock( kmp_adaptive_lock * lck )
2101 KMP_ASSERT( lck->stats.next->stats.prev == lck );
2102 KMP_ASSERT( lck->stats.prev->stats.next == lck );
2104 kmp_adaptive_lock * n = lck->stats.next;
2105 kmp_adaptive_lock * p = lck->stats.prev;
2112 __kmp_zero_speculative_stats( kmp_adaptive_lock * lck )
2114 memset( (
void * )&lck->stats, 0,
sizeof( lck->stats ) );
2115 __kmp_remember_lock( lck );
2119 __kmp_add_stats( kmp_adaptive_lock_statistics_t * t, kmp_adaptive_lock_t * lck )
2121 kmp_adaptive_lock_statistics_t
volatile *s = &lck->stats;
2123 t->nonSpeculativeAcquireAttempts += lck->acquire_attempts;
2124 t->successfulSpeculations += s->successfulSpeculations;
2125 t->hardFailedSpeculations += s->hardFailedSpeculations;
2126 t->softFailedSpeculations += s->softFailedSpeculations;
2127 t->nonSpeculativeAcquires += s->nonSpeculativeAcquires;
2128 t->lemmingYields += s->lemmingYields;
2132 __kmp_accumulate_speculative_stats( kmp_adaptive_lock * lck)
2134 kmp_adaptive_lock_statistics_t *t = &destroyedStats;
2136 __kmp_acquire_bootstrap_lock( &chain_lock );
2138 __kmp_add_stats( &destroyedStats, lck );
2139 __kmp_forget_lock( lck );
2141 __kmp_release_bootstrap_lock( &chain_lock );
2145 percent (kmp_uint32 count, kmp_uint32 total)
2147 return (total == 0) ? 0.0: (100.0 * count)/total;
2151 FILE * __kmp_open_stats_file()
2153 if (strcmp (__kmp_speculative_statsfile,
"-") == 0)
2156 size_t buffLen = strlen( __kmp_speculative_statsfile ) + 20;
2157 char buffer[buffLen];
2158 snprintf (&buffer[0], buffLen, __kmp_speculative_statsfile, getpid());
2159 FILE * result = fopen(&buffer[0],
"w");
2162 return result ? result : stdout;
2166 __kmp_print_speculative_stats()
2168 if (__kmp_user_lock_kind != lk_adaptive)
2171 FILE * statsFile = __kmp_open_stats_file();
2173 kmp_adaptive_lock_statistics_t total = destroyedStats;
2174 kmp_adaptive_lock *lck;
2176 for (lck = liveLocks.stats.next; lck != &liveLocks; lck = lck->stats.next) {
2177 __kmp_add_stats( &total, lck );
2179 kmp_adaptive_lock_statistics_t *t = &total;
2180 kmp_uint32 totalSections = t->nonSpeculativeAcquires + t->successfulSpeculations;
2181 kmp_uint32 totalSpeculations = t->successfulSpeculations + t->hardFailedSpeculations +
2182 t->softFailedSpeculations;
2184 fprintf ( statsFile,
"Speculative lock statistics (all approximate!)\n");
2185 fprintf ( statsFile,
" Lock parameters: \n"
2186 " max_soft_retries : %10d\n"
2187 " max_badness : %10d\n",
2188 __kmp_adaptive_backoff_params.max_soft_retries,
2189 __kmp_adaptive_backoff_params.max_badness);
2190 fprintf( statsFile,
" Non-speculative acquire attempts : %10d\n", t->nonSpeculativeAcquireAttempts );
2191 fprintf( statsFile,
" Total critical sections : %10d\n", totalSections );
2192 fprintf( statsFile,
" Successful speculations : %10d (%5.1f%%)\n",
2193 t->successfulSpeculations, percent( t->successfulSpeculations, totalSections ) );
2194 fprintf( statsFile,
" Non-speculative acquires : %10d (%5.1f%%)\n",
2195 t->nonSpeculativeAcquires, percent( t->nonSpeculativeAcquires, totalSections ) );
2196 fprintf( statsFile,
" Lemming yields : %10d\n\n", t->lemmingYields );
2198 fprintf( statsFile,
" Speculative acquire attempts : %10d\n", totalSpeculations );
2199 fprintf( statsFile,
" Successes : %10d (%5.1f%%)\n",
2200 t->successfulSpeculations, percent( t->successfulSpeculations, totalSpeculations ) );
2201 fprintf( statsFile,
" Soft failures : %10d (%5.1f%%)\n",
2202 t->softFailedSpeculations, percent( t->softFailedSpeculations, totalSpeculations ) );
2203 fprintf( statsFile,
" Hard failures : %10d (%5.1f%%)\n",
2204 t->hardFailedSpeculations, percent( t->hardFailedSpeculations, totalSpeculations ) );
2206 if (statsFile != stdout)
2207 fclose( statsFile );
2210 # define KMP_INC_STAT(lck,stat) ( lck->lk.adaptive.stats.stat++ )
2212 # define KMP_INC_STAT(lck,stat)
2214 #endif // KMP_DEBUG_ADAPTIVE_LOCKS
2217 __kmp_is_unlocked_queuing_lock( kmp_queuing_lock_t *lck )
2221 bool res = lck->lk.head_id == 0;
2225 #if defined( __GNUC__ ) && !defined( __INTEL_COMPILER )
2226 __sync_synchronize();
2235 static __inline
void
2236 __kmp_update_badness_after_success( kmp_queuing_lock_t *lck )
2239 lck->lk.adaptive.badness = 0;
2240 KMP_INC_STAT(lck,successfulSpeculations);
2244 static __inline
void
2245 __kmp_step_badness( kmp_queuing_lock_t *lck )
2247 kmp_uint32 newBadness = ( lck->lk.adaptive.badness << 1 ) | 1;
2248 if ( newBadness > lck->lk.adaptive.max_badness) {
2251 lck->lk.adaptive.badness = newBadness;
2257 __kmp_should_speculate( kmp_queuing_lock_t *lck, kmp_int32 gtid )
2259 kmp_uint32 badness = lck->lk.adaptive.badness;
2260 kmp_uint32 attempts= lck->lk.adaptive.acquire_attempts;
2261 int res = (attempts & badness) == 0;
2269 __kmp_test_adaptive_lock_only( kmp_queuing_lock_t * lck, kmp_int32 gtid )
2271 int retries = lck->lk.adaptive.max_soft_retries;
2279 kmp_uint32 status = _xbegin();
2284 if (status == _XBEGIN_STARTED )
2290 if (! __kmp_is_unlocked_queuing_lock( lck ) )
2296 KMP_ASSERT2( 0, "should not get here" );
2301 if ( status & SOFT_ABORT_MASK)
2303 KMP_INC_STAT(lck,softFailedSpeculations);
2308 KMP_INC_STAT(lck,hardFailedSpeculations);
2313 }
while( retries-- );
2317 __kmp_step_badness( lck );
2325 __kmp_test_adaptive_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
2328 if ( __kmp_should_speculate( lck, gtid ) && __kmp_test_adaptive_lock_only( lck, gtid ) )
2333 lck->lk.adaptive.acquire_attempts++;
2336 if ( __kmp_test_queuing_lock( lck, gtid ) )
2338 KMP_INC_STAT(lck,nonSpeculativeAcquires);
2348 __kmp_test_adaptive_lock_with_checks( kmp_queuing_lock_t *lck, kmp_int32 gtid )
2350 if ( __kmp_env_consistency_check ) {
2351 char const *
const func =
"omp_test_lock";
2352 if ( lck->lk.initialized != lck ) {
2353 KMP_FATAL( LockIsUninitialized, func );
2357 int retval = __kmp_test_adaptive_lock( lck, gtid );
2359 if ( __kmp_env_consistency_check && retval ) {
2360 lck->lk.owner_id = gtid + 1;
2380 __kmp_acquire_adaptive_lock( kmp_queuing_lock_t * lck, kmp_int32 gtid )
2382 if ( __kmp_should_speculate( lck, gtid ) )
2384 if ( __kmp_is_unlocked_queuing_lock( lck ) )
2386 if ( __kmp_test_adaptive_lock_only( lck , gtid ) )
2398 while ( ! __kmp_is_unlocked_queuing_lock( lck ) )
2400 KMP_INC_STAT(lck,lemmingYields);
2404 if ( __kmp_test_adaptive_lock_only( lck, gtid ) )
2411 lck->lk.adaptive.acquire_attempts++;
2413 __kmp_acquire_queuing_lock_timed_template<FALSE>( lck, gtid );
2415 KMP_INC_STAT(lck,nonSpeculativeAcquires );
2419 __kmp_acquire_adaptive_lock_with_checks( kmp_queuing_lock_t *lck, kmp_int32 gtid )
2421 if ( __kmp_env_consistency_check ) {
2422 char const *
const func =
"omp_set_lock";
2423 if ( lck->lk.initialized != lck ) {
2424 KMP_FATAL( LockIsUninitialized, func );
2426 if ( __kmp_get_queuing_lock_owner( lck ) == gtid ) {
2427 KMP_FATAL( LockIsAlreadyOwned, func );
2431 __kmp_acquire_adaptive_lock( lck, gtid );
2433 if ( __kmp_env_consistency_check ) {
2434 lck->lk.owner_id = gtid + 1;
2439 __kmp_release_adaptive_lock( kmp_queuing_lock_t *lck, kmp_int32 gtid )
2441 if ( __kmp_is_unlocked_queuing_lock( lck ) )
2446 __kmp_update_badness_after_success( lck );
2451 __kmp_release_queuing_lock( lck, gtid );
2456 __kmp_release_adaptive_lock_with_checks( kmp_queuing_lock_t *lck, kmp_int32 gtid )
2458 if ( __kmp_env_consistency_check ) {
2459 char const *
const func =
"omp_unset_lock";
2461 if ( lck->lk.initialized != lck ) {
2462 KMP_FATAL( LockIsUninitialized, func );
2464 if ( __kmp_get_queuing_lock_owner( lck ) == -1 ) {
2465 KMP_FATAL( LockUnsettingFree, func );
2467 if ( __kmp_get_queuing_lock_owner( lck ) != gtid ) {
2468 KMP_FATAL( LockUnsettingSetByAnother, func );
2470 lck->lk.owner_id = 0;
2472 __kmp_release_adaptive_lock( lck, gtid );
2476 __kmp_init_adaptive_lock( kmp_queuing_lock_t *lck )
2478 __kmp_init_queuing_lock( lck );
2479 lck->lk.adaptive.badness = 0;
2480 lck->lk.adaptive.acquire_attempts = 0;
2481 lck->lk.adaptive.max_soft_retries = __kmp_adaptive_backoff_params.max_soft_retries;
2482 lck->lk.adaptive.max_badness = __kmp_adaptive_backoff_params.max_badness;
2483 #if KMP_DEBUG_ADAPTIVE_LOCKS
2484 __kmp_zero_speculative_stats( &lck->lk.adaptive );
2486 KA_TRACE(1000, (
"__kmp_init_adaptive_lock: lock %p initialized\n", lck));
2490 __kmp_init_adaptive_lock_with_checks( kmp_queuing_lock_t * lck )
2492 __kmp_init_adaptive_lock( lck );
2496 __kmp_destroy_adaptive_lock( kmp_queuing_lock_t *lck )
2498 #if KMP_DEBUG_ADAPTIVE_LOCKS
2499 __kmp_accumulate_speculative_stats( &lck->lk.adaptive );
2501 __kmp_destroy_queuing_lock (lck);
2506 __kmp_destroy_adaptive_lock_with_checks( kmp_queuing_lock_t *lck )
2508 if ( __kmp_env_consistency_check ) {
2509 char const *
const func =
"omp_destroy_lock";
2510 if ( lck->lk.initialized != lck ) {
2511 KMP_FATAL( LockIsUninitialized, func );
2513 if ( __kmp_get_queuing_lock_owner( lck ) != -1 ) {
2514 KMP_FATAL( LockStillOwned, func );
2517 __kmp_destroy_adaptive_lock( lck );
2521 #endif // KMP_USE_ADAPTIVE_LOCKS
2529 __kmp_get_drdpa_lock_owner( kmp_drdpa_lock_t *lck )
2531 return TCR_4( lck->lk.owner_id ) - 1;
2535 __kmp_is_drdpa_lock_nestable( kmp_drdpa_lock_t *lck )
2537 return lck->lk.depth_locked != -1;
2540 __forceinline
static void
2541 __kmp_acquire_drdpa_lock_timed_template( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2543 kmp_uint64 ticket = KMP_TEST_THEN_INC64((kmp_int64 *)&lck->lk.next_ticket);
2544 kmp_uint64 mask = TCR_8(lck->lk.mask);
2545 volatile struct kmp_base_drdpa_lock::kmp_lock_poll *polls
2546 = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2547 TCR_PTR(lck->lk.polls);
2549 #ifdef USE_LOCK_PROFILE
2550 if (TCR_8(polls[ticket & mask].poll) != ticket)
2551 __kmp_printf(
"LOCK CONTENTION: %p\n", lck);
2567 KMP_FSYNC_PREPARE(lck);
2568 KMP_INIT_YIELD(spins);
2569 while (TCR_8(polls[ticket & mask]).poll < ticket) {
2570 __kmp_static_delay(TRUE);
2577 KMP_YIELD(TCR_4(__kmp_nth)
2578 > (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc));
2579 KMP_YIELD_SPIN(spins);
2590 mask = TCR_8(lck->lk.mask);
2591 polls = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2592 TCR_PTR(lck->lk.polls);
2598 KMP_FSYNC_ACQUIRED(lck);
2599 KA_TRACE(1000, (
"__kmp_acquire_drdpa_lock: ticket #%lld acquired lock %p\n",
2601 lck->lk.now_serving = ticket;
2610 if ((lck->lk.old_polls != NULL) && (ticket >= lck->lk.cleanup_ticket)) {
2611 __kmp_free((
void *)lck->lk.old_polls);
2612 lck->lk.old_polls = NULL;
2613 lck->lk.cleanup_ticket = 0;
2621 if (lck->lk.old_polls == NULL) {
2622 bool reconfigure =
false;
2623 volatile struct kmp_base_drdpa_lock::kmp_lock_poll *old_polls = polls;
2624 kmp_uint32 num_polls = TCR_4(lck->lk.num_polls);
2626 if (TCR_4(__kmp_nth)
2627 > (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc)) {
2632 if (num_polls > 1) {
2634 num_polls = TCR_4(lck->lk.num_polls);
2637 polls = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2638 __kmp_allocate(num_polls *
sizeof(*polls));
2639 polls[0].poll = ticket;
2648 kmp_uint64 num_waiting = TCR_8(lck->lk.next_ticket) - ticket - 1;
2649 if (num_waiting > num_polls) {
2650 kmp_uint32 old_num_polls = num_polls;
2653 mask = (mask << 1) | 1;
2655 }
while (num_polls <= num_waiting);
2663 polls = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2664 __kmp_allocate(num_polls *
sizeof(*polls));
2666 for (i = 0; i < old_num_polls; i++) {
2667 polls[i].poll = old_polls[i].poll;
2684 KA_TRACE(1000, (
"__kmp_acquire_drdpa_lock: ticket #%lld reconfiguring lock %p to %d polls\n",
2685 ticket, lck, num_polls));
2687 lck->lk.old_polls = old_polls;
2688 lck->lk.polls = polls;
2692 lck->lk.num_polls = num_polls;
2693 lck->lk.mask = mask;
2703 lck->lk.cleanup_ticket = TCR_8(lck->lk.next_ticket);
2709 __kmp_acquire_drdpa_lock( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2711 __kmp_acquire_drdpa_lock_timed_template( lck, gtid );
2715 __kmp_acquire_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2717 if ( __kmp_env_consistency_check ) {
2718 char const *
const func =
"omp_set_lock";
2719 if ( lck->lk.initialized != lck ) {
2720 KMP_FATAL( LockIsUninitialized, func );
2722 if ( __kmp_is_drdpa_lock_nestable( lck ) ) {
2723 KMP_FATAL( LockNestableUsedAsSimple, func );
2725 if ( ( gtid >= 0 ) && ( __kmp_get_drdpa_lock_owner( lck ) == gtid ) ) {
2726 KMP_FATAL( LockIsAlreadyOwned, func );
2730 __kmp_acquire_drdpa_lock( lck, gtid );
2732 if ( __kmp_env_consistency_check ) {
2733 lck->lk.owner_id = gtid + 1;
2738 __kmp_test_drdpa_lock( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2744 kmp_uint64 ticket = TCR_8(lck->lk.next_ticket);
2745 volatile struct kmp_base_drdpa_lock::kmp_lock_poll *polls
2746 = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2747 TCR_PTR(lck->lk.polls);
2748 kmp_uint64 mask = TCR_8(lck->lk.mask);
2749 if (TCR_8(polls[ticket & mask].poll) == ticket) {
2750 kmp_uint64 next_ticket = ticket + 1;
2751 if (KMP_COMPARE_AND_STORE_ACQ64((kmp_int64 *)&lck->lk.next_ticket,
2752 ticket, next_ticket)) {
2753 KMP_FSYNC_ACQUIRED(lck);
2754 KA_TRACE(1000, (
"__kmp_test_drdpa_lock: ticket #%lld acquired lock %p\n",
2756 lck->lk.now_serving = ticket;
2774 __kmp_test_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2776 if ( __kmp_env_consistency_check ) {
2777 char const *
const func =
"omp_test_lock";
2778 if ( lck->lk.initialized != lck ) {
2779 KMP_FATAL( LockIsUninitialized, func );
2781 if ( __kmp_is_drdpa_lock_nestable( lck ) ) {
2782 KMP_FATAL( LockNestableUsedAsSimple, func );
2786 int retval = __kmp_test_drdpa_lock( lck, gtid );
2788 if ( __kmp_env_consistency_check && retval ) {
2789 lck->lk.owner_id = gtid + 1;
2795 __kmp_release_drdpa_lock( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2802 kmp_uint64 ticket = lck->lk.now_serving + 1;
2803 volatile struct kmp_base_drdpa_lock::kmp_lock_poll *polls
2804 = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2805 TCR_PTR(lck->lk.polls);
2806 kmp_uint64 mask = TCR_8(lck->lk.mask);
2807 KA_TRACE(1000, (
"__kmp_release_drdpa_lock: ticket #%lld released lock %p\n",
2809 KMP_FSYNC_RELEASING(lck);
2810 TCW_8(polls[ticket & mask].poll, ticket);
2814 __kmp_release_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2816 if ( __kmp_env_consistency_check ) {
2817 char const *
const func =
"omp_unset_lock";
2819 if ( lck->lk.initialized != lck ) {
2820 KMP_FATAL( LockIsUninitialized, func );
2822 if ( __kmp_is_drdpa_lock_nestable( lck ) ) {
2823 KMP_FATAL( LockNestableUsedAsSimple, func );
2825 if ( __kmp_get_drdpa_lock_owner( lck ) == -1 ) {
2826 KMP_FATAL( LockUnsettingFree, func );
2828 if ( ( gtid >= 0 ) && ( __kmp_get_drdpa_lock_owner( lck ) >= 0 )
2829 && ( __kmp_get_drdpa_lock_owner( lck ) != gtid ) ) {
2830 KMP_FATAL( LockUnsettingSetByAnother, func );
2832 lck->lk.owner_id = 0;
2834 __kmp_release_drdpa_lock( lck, gtid );
2838 __kmp_init_drdpa_lock( kmp_drdpa_lock_t *lck )
2840 lck->lk.location = NULL;
2842 lck->lk.num_polls = 1;
2843 lck->lk.polls = (
volatile struct kmp_base_drdpa_lock::kmp_lock_poll *)
2844 __kmp_allocate(lck->lk.num_polls *
sizeof(*(lck->lk.polls)));
2845 lck->lk.cleanup_ticket = 0;
2846 lck->lk.old_polls = NULL;
2847 lck->lk.next_ticket = 0;
2848 lck->lk.now_serving = 0;
2849 lck->lk.owner_id = 0;
2850 lck->lk.depth_locked = -1;
2851 lck->lk.initialized = lck;
2853 KA_TRACE(1000, (
"__kmp_init_drdpa_lock: lock %p initialized\n", lck));
2857 __kmp_init_drdpa_lock_with_checks( kmp_drdpa_lock_t * lck )
2859 __kmp_init_drdpa_lock( lck );
2863 __kmp_destroy_drdpa_lock( kmp_drdpa_lock_t *lck )
2865 lck->lk.initialized = NULL;
2866 lck->lk.location = NULL;
2867 if (lck->lk.polls != NULL) {
2868 __kmp_free((
void *)lck->lk.polls);
2869 lck->lk.polls = NULL;
2871 if (lck->lk.old_polls != NULL) {
2872 __kmp_free((
void *)lck->lk.old_polls);
2873 lck->lk.old_polls = NULL;
2876 lck->lk.num_polls = 0;
2877 lck->lk.cleanup_ticket = 0;
2878 lck->lk.next_ticket = 0;
2879 lck->lk.now_serving = 0;
2880 lck->lk.owner_id = 0;
2881 lck->lk.depth_locked = -1;
2885 __kmp_destroy_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck )
2887 if ( __kmp_env_consistency_check ) {
2888 char const *
const func =
"omp_destroy_lock";
2889 if ( lck->lk.initialized != lck ) {
2890 KMP_FATAL( LockIsUninitialized, func );
2892 if ( __kmp_is_drdpa_lock_nestable( lck ) ) {
2893 KMP_FATAL( LockNestableUsedAsSimple, func );
2895 if ( __kmp_get_drdpa_lock_owner( lck ) != -1 ) {
2896 KMP_FATAL( LockStillOwned, func );
2899 __kmp_destroy_drdpa_lock( lck );
2908 __kmp_acquire_nested_drdpa_lock( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2910 KMP_DEBUG_ASSERT( gtid >= 0 );
2912 if ( __kmp_get_drdpa_lock_owner( lck ) == gtid ) {
2913 lck->lk.depth_locked += 1;
2916 __kmp_acquire_drdpa_lock_timed_template( lck, gtid );
2918 lck->lk.depth_locked = 1;
2920 lck->lk.owner_id = gtid + 1;
2925 __kmp_acquire_nested_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2927 if ( __kmp_env_consistency_check ) {
2928 char const *
const func =
"omp_set_nest_lock";
2929 if ( lck->lk.initialized != lck ) {
2930 KMP_FATAL( LockIsUninitialized, func );
2932 if ( ! __kmp_is_drdpa_lock_nestable( lck ) ) {
2933 KMP_FATAL( LockSimpleUsedAsNestable, func );
2936 __kmp_acquire_nested_drdpa_lock( lck, gtid );
2940 __kmp_test_nested_drdpa_lock( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2944 KMP_DEBUG_ASSERT( gtid >= 0 );
2946 if ( __kmp_get_drdpa_lock_owner( lck ) == gtid ) {
2947 retval = ++lck->lk.depth_locked;
2949 else if ( !__kmp_test_drdpa_lock( lck, gtid ) ) {
2954 retval = lck->lk.depth_locked = 1;
2956 lck->lk.owner_id = gtid + 1;
2962 __kmp_test_nested_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2964 if ( __kmp_env_consistency_check ) {
2965 char const *
const func =
"omp_test_nest_lock";
2966 if ( lck->lk.initialized != lck ) {
2967 KMP_FATAL( LockIsUninitialized, func );
2969 if ( ! __kmp_is_drdpa_lock_nestable( lck ) ) {
2970 KMP_FATAL( LockSimpleUsedAsNestable, func );
2973 return __kmp_test_nested_drdpa_lock( lck, gtid );
2977 __kmp_release_nested_drdpa_lock( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2979 KMP_DEBUG_ASSERT( gtid >= 0 );
2982 if ( --(lck->lk.depth_locked) == 0 ) {
2984 lck->lk.owner_id = 0;
2985 __kmp_release_drdpa_lock( lck, gtid );
2990 __kmp_release_nested_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck, kmp_int32 gtid )
2992 if ( __kmp_env_consistency_check ) {
2993 char const *
const func =
"omp_unset_nest_lock";
2995 if ( lck->lk.initialized != lck ) {
2996 KMP_FATAL( LockIsUninitialized, func );
2998 if ( ! __kmp_is_drdpa_lock_nestable( lck ) ) {
2999 KMP_FATAL( LockSimpleUsedAsNestable, func );
3001 if ( __kmp_get_drdpa_lock_owner( lck ) == -1 ) {
3002 KMP_FATAL( LockUnsettingFree, func );
3004 if ( __kmp_get_drdpa_lock_owner( lck ) != gtid ) {
3005 KMP_FATAL( LockUnsettingSetByAnother, func );
3008 __kmp_release_nested_drdpa_lock( lck, gtid );
3012 __kmp_init_nested_drdpa_lock( kmp_drdpa_lock_t * lck )
3014 __kmp_init_drdpa_lock( lck );
3015 lck->lk.depth_locked = 0;
3019 __kmp_init_nested_drdpa_lock_with_checks( kmp_drdpa_lock_t * lck )
3021 __kmp_init_nested_drdpa_lock( lck );
3025 __kmp_destroy_nested_drdpa_lock( kmp_drdpa_lock_t *lck )
3027 __kmp_destroy_drdpa_lock( lck );
3028 lck->lk.depth_locked = 0;
3032 __kmp_destroy_nested_drdpa_lock_with_checks( kmp_drdpa_lock_t *lck )
3034 if ( __kmp_env_consistency_check ) {
3035 char const *
const func =
"omp_destroy_nest_lock";
3036 if ( lck->lk.initialized != lck ) {
3037 KMP_FATAL( LockIsUninitialized, func );
3039 if ( ! __kmp_is_drdpa_lock_nestable( lck ) ) {
3040 KMP_FATAL( LockSimpleUsedAsNestable, func );
3042 if ( __kmp_get_drdpa_lock_owner( lck ) != -1 ) {
3043 KMP_FATAL( LockStillOwned, func );
3046 __kmp_destroy_nested_drdpa_lock( lck );
3055 __kmp_is_drdpa_lock_initialized( kmp_drdpa_lock_t *lck )
3057 return lck == lck->lk.initialized;
3061 __kmp_get_drdpa_lock_location( kmp_drdpa_lock_t *lck )
3063 return lck->lk.location;
3067 __kmp_set_drdpa_lock_location( kmp_drdpa_lock_t *lck,
const ident_t *loc )
3069 lck->lk.location = loc;
3072 static kmp_lock_flags_t
3073 __kmp_get_drdpa_lock_flags( kmp_drdpa_lock_t *lck )
3075 return lck->lk.flags;
3079 __kmp_set_drdpa_lock_flags( kmp_drdpa_lock_t *lck, kmp_lock_flags_t flags )
3081 lck->lk.flags = flags;
3091 enum kmp_lock_kind __kmp_user_lock_kind = lk_default;
3093 size_t __kmp_base_user_lock_size = 0;
3094 size_t __kmp_user_lock_size = 0;
3096 kmp_int32 ( *__kmp_get_user_lock_owner_ )( kmp_user_lock_p lck ) = NULL;
3097 void ( *__kmp_acquire_user_lock_with_checks_ )( kmp_user_lock_p lck, kmp_int32 gtid ) = NULL;
3099 int ( *__kmp_test_user_lock_with_checks_ )( kmp_user_lock_p lck, kmp_int32 gtid ) = NULL;
3100 void ( *__kmp_release_user_lock_with_checks_ )( kmp_user_lock_p lck, kmp_int32 gtid ) = NULL;
3101 void ( *__kmp_init_user_lock_with_checks_ )( kmp_user_lock_p lck ) = NULL;
3102 void ( *__kmp_destroy_user_lock_ )( kmp_user_lock_p lck ) = NULL;
3103 void ( *__kmp_destroy_user_lock_with_checks_ )( kmp_user_lock_p lck ) = NULL;
3104 void ( *__kmp_acquire_nested_user_lock_with_checks_ )( kmp_user_lock_p lck, kmp_int32 gtid ) = NULL;
3106 int ( *__kmp_test_nested_user_lock_with_checks_ )( kmp_user_lock_p lck, kmp_int32 gtid ) = NULL;
3107 void ( *__kmp_release_nested_user_lock_with_checks_ )( kmp_user_lock_p lck, kmp_int32 gtid ) = NULL;
3108 void ( *__kmp_init_nested_user_lock_with_checks_ )( kmp_user_lock_p lck ) = NULL;
3109 void ( *__kmp_destroy_nested_user_lock_with_checks_ )( kmp_user_lock_p lck ) = NULL;
3111 int ( *__kmp_is_user_lock_initialized_ )( kmp_user_lock_p lck ) = NULL;
3112 const ident_t * ( *__kmp_get_user_lock_location_ )( kmp_user_lock_p lck ) = NULL;
3113 void ( *__kmp_set_user_lock_location_ )( kmp_user_lock_p lck,
const ident_t *loc ) = NULL;
3114 kmp_lock_flags_t ( *__kmp_get_user_lock_flags_ )( kmp_user_lock_p lck ) = NULL;
3115 void ( *__kmp_set_user_lock_flags_ )( kmp_user_lock_p lck, kmp_lock_flags_t flags ) = NULL;
3117 void __kmp_set_user_lock_vptrs( kmp_lock_kind_t user_lock_kind )
3119 switch ( user_lock_kind ) {
3125 __kmp_base_user_lock_size =
sizeof( kmp_base_tas_lock_t );
3126 __kmp_user_lock_size =
sizeof( kmp_tas_lock_t );
3128 __kmp_get_user_lock_owner_ =
3129 ( kmp_int32 ( * )( kmp_user_lock_p ) )
3130 ( &__kmp_get_tas_lock_owner );
3132 __kmp_acquire_user_lock_with_checks_ =
3133 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3134 ( &__kmp_acquire_tas_lock_with_checks );
3136 __kmp_test_user_lock_with_checks_ =
3137 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3138 ( &__kmp_test_tas_lock_with_checks );
3140 __kmp_release_user_lock_with_checks_ =
3141 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3142 ( &__kmp_release_tas_lock_with_checks );
3144 __kmp_init_user_lock_with_checks_ =
3145 ( void ( * )( kmp_user_lock_p ) )
3146 ( &__kmp_init_tas_lock_with_checks );
3148 __kmp_destroy_user_lock_ =
3149 ( void ( * )( kmp_user_lock_p ) )
3150 ( &__kmp_destroy_tas_lock );
3152 __kmp_destroy_user_lock_with_checks_ =
3153 ( void ( * )( kmp_user_lock_p ) )
3154 ( &__kmp_destroy_tas_lock_with_checks );
3156 __kmp_acquire_nested_user_lock_with_checks_ =
3157 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3158 ( &__kmp_acquire_nested_tas_lock_with_checks );
3160 __kmp_test_nested_user_lock_with_checks_ =
3161 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3162 ( &__kmp_test_nested_tas_lock_with_checks );
3164 __kmp_release_nested_user_lock_with_checks_ =
3165 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3166 ( &__kmp_release_nested_tas_lock_with_checks );
3168 __kmp_init_nested_user_lock_with_checks_ =
3169 ( void ( * )( kmp_user_lock_p ) )
3170 ( &__kmp_init_nested_tas_lock_with_checks );
3172 __kmp_destroy_nested_user_lock_with_checks_ =
3173 ( void ( * )( kmp_user_lock_p ) )
3174 ( &__kmp_destroy_nested_tas_lock_with_checks );
3176 __kmp_is_user_lock_initialized_ =
3177 ( int ( * )( kmp_user_lock_p ) ) NULL;
3179 __kmp_get_user_lock_location_ =
3180 (
const ident_t * ( * )( kmp_user_lock_p ) ) NULL;
3182 __kmp_set_user_lock_location_ =
3183 ( void ( * )( kmp_user_lock_p,
const ident_t * ) ) NULL;
3185 __kmp_get_user_lock_flags_ =
3186 ( kmp_lock_flags_t ( * )( kmp_user_lock_p ) ) NULL;
3188 __kmp_set_user_lock_flags_ =
3189 ( void ( * )( kmp_user_lock_p, kmp_lock_flags_t ) ) NULL;
3193 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
3196 __kmp_base_user_lock_size =
sizeof( kmp_base_futex_lock_t );
3197 __kmp_user_lock_size =
sizeof( kmp_futex_lock_t );
3199 __kmp_get_user_lock_owner_ =
3200 ( kmp_int32 ( * )( kmp_user_lock_p ) )
3201 ( &__kmp_get_futex_lock_owner );
3203 __kmp_acquire_user_lock_with_checks_ =
3204 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3205 ( &__kmp_acquire_futex_lock_with_checks );
3207 __kmp_test_user_lock_with_checks_ =
3208 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3209 ( &__kmp_test_futex_lock_with_checks );
3211 __kmp_release_user_lock_with_checks_ =
3212 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3213 ( &__kmp_release_futex_lock_with_checks );
3215 __kmp_init_user_lock_with_checks_ =
3216 ( void ( * )( kmp_user_lock_p ) )
3217 ( &__kmp_init_futex_lock_with_checks );
3219 __kmp_destroy_user_lock_ =
3220 ( void ( * )( kmp_user_lock_p ) )
3221 ( &__kmp_destroy_futex_lock );
3223 __kmp_destroy_user_lock_with_checks_ =
3224 ( void ( * )( kmp_user_lock_p ) )
3225 ( &__kmp_destroy_futex_lock_with_checks );
3227 __kmp_acquire_nested_user_lock_with_checks_ =
3228 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3229 ( &__kmp_acquire_nested_futex_lock_with_checks );
3231 __kmp_test_nested_user_lock_with_checks_ =
3232 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3233 ( &__kmp_test_nested_futex_lock_with_checks );
3235 __kmp_release_nested_user_lock_with_checks_ =
3236 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3237 ( &__kmp_release_nested_futex_lock_with_checks );
3239 __kmp_init_nested_user_lock_with_checks_ =
3240 ( void ( * )( kmp_user_lock_p ) )
3241 ( &__kmp_init_nested_futex_lock_with_checks );
3243 __kmp_destroy_nested_user_lock_with_checks_ =
3244 ( void ( * )( kmp_user_lock_p ) )
3245 ( &__kmp_destroy_nested_futex_lock_with_checks );
3247 __kmp_is_user_lock_initialized_ =
3248 ( int ( * )( kmp_user_lock_p ) ) NULL;
3250 __kmp_get_user_lock_location_ =
3251 (
const ident_t * ( * )( kmp_user_lock_p ) ) NULL;
3253 __kmp_set_user_lock_location_ =
3254 ( void ( * )( kmp_user_lock_p,
const ident_t * ) ) NULL;
3256 __kmp_get_user_lock_flags_ =
3257 ( kmp_lock_flags_t ( * )( kmp_user_lock_p ) ) NULL;
3259 __kmp_set_user_lock_flags_ =
3260 ( void ( * )( kmp_user_lock_p, kmp_lock_flags_t ) ) NULL;
3264 #endif // KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
3267 __kmp_base_user_lock_size =
sizeof( kmp_base_ticket_lock_t );
3268 __kmp_user_lock_size =
sizeof( kmp_ticket_lock_t );
3270 __kmp_get_user_lock_owner_ =
3271 ( kmp_int32 ( * )( kmp_user_lock_p ) )
3272 ( &__kmp_get_ticket_lock_owner );
3274 __kmp_acquire_user_lock_with_checks_ =
3275 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3276 ( &__kmp_acquire_ticket_lock_with_checks );
3278 __kmp_test_user_lock_with_checks_ =
3279 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3280 ( &__kmp_test_ticket_lock_with_checks );
3282 __kmp_release_user_lock_with_checks_ =
3283 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3284 ( &__kmp_release_ticket_lock_with_checks );
3286 __kmp_init_user_lock_with_checks_ =
3287 ( void ( * )( kmp_user_lock_p ) )
3288 ( &__kmp_init_ticket_lock_with_checks );
3290 __kmp_destroy_user_lock_ =
3291 ( void ( * )( kmp_user_lock_p ) )
3292 ( &__kmp_destroy_ticket_lock );
3294 __kmp_destroy_user_lock_with_checks_ =
3295 ( void ( * )( kmp_user_lock_p ) )
3296 ( &__kmp_destroy_ticket_lock_with_checks );
3298 __kmp_acquire_nested_user_lock_with_checks_ =
3299 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3300 ( &__kmp_acquire_nested_ticket_lock_with_checks );
3302 __kmp_test_nested_user_lock_with_checks_ =
3303 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3304 ( &__kmp_test_nested_ticket_lock_with_checks );
3306 __kmp_release_nested_user_lock_with_checks_ =
3307 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3308 ( &__kmp_release_nested_ticket_lock_with_checks );
3310 __kmp_init_nested_user_lock_with_checks_ =
3311 ( void ( * )( kmp_user_lock_p ) )
3312 ( &__kmp_init_nested_ticket_lock_with_checks );
3314 __kmp_destroy_nested_user_lock_with_checks_ =
3315 ( void ( * )( kmp_user_lock_p ) )
3316 ( &__kmp_destroy_nested_ticket_lock_with_checks );
3318 __kmp_is_user_lock_initialized_ =
3319 ( int ( * )( kmp_user_lock_p ) )
3320 ( &__kmp_is_ticket_lock_initialized );
3322 __kmp_get_user_lock_location_ =
3323 (
const ident_t * ( * )( kmp_user_lock_p ) )
3324 ( &__kmp_get_ticket_lock_location );
3326 __kmp_set_user_lock_location_ =
3327 ( void ( * )( kmp_user_lock_p,
const ident_t * ) )
3328 ( &__kmp_set_ticket_lock_location );
3330 __kmp_get_user_lock_flags_ =
3331 ( kmp_lock_flags_t ( * )( kmp_user_lock_p ) )
3332 ( &__kmp_get_ticket_lock_flags );
3334 __kmp_set_user_lock_flags_ =
3335 ( void ( * )( kmp_user_lock_p, kmp_lock_flags_t ) )
3336 ( &__kmp_set_ticket_lock_flags );
3341 __kmp_base_user_lock_size =
sizeof( kmp_base_queuing_lock_t );
3342 __kmp_user_lock_size =
sizeof( kmp_queuing_lock_t );
3344 __kmp_get_user_lock_owner_ =
3345 ( kmp_int32 ( * )( kmp_user_lock_p ) )
3346 ( &__kmp_get_queuing_lock_owner );
3348 __kmp_acquire_user_lock_with_checks_ =
3349 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3350 ( &__kmp_acquire_queuing_lock_with_checks );
3352 __kmp_test_user_lock_with_checks_ =
3353 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3354 ( &__kmp_test_queuing_lock_with_checks );
3356 __kmp_release_user_lock_with_checks_ =
3357 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3358 ( &__kmp_release_queuing_lock_with_checks );
3360 __kmp_init_user_lock_with_checks_ =
3361 ( void ( * )( kmp_user_lock_p ) )
3362 ( &__kmp_init_queuing_lock_with_checks );
3364 __kmp_destroy_user_lock_ =
3365 ( void ( * )( kmp_user_lock_p ) )
3366 ( &__kmp_destroy_queuing_lock );
3368 __kmp_destroy_user_lock_with_checks_ =
3369 ( void ( * )( kmp_user_lock_p ) )
3370 ( &__kmp_destroy_queuing_lock_with_checks );
3372 __kmp_acquire_nested_user_lock_with_checks_ =
3373 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3374 ( &__kmp_acquire_nested_queuing_lock_with_checks );
3376 __kmp_test_nested_user_lock_with_checks_ =
3377 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3378 ( &__kmp_test_nested_queuing_lock_with_checks );
3380 __kmp_release_nested_user_lock_with_checks_ =
3381 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3382 ( &__kmp_release_nested_queuing_lock_with_checks );
3384 __kmp_init_nested_user_lock_with_checks_ =
3385 ( void ( * )( kmp_user_lock_p ) )
3386 ( &__kmp_init_nested_queuing_lock_with_checks );
3388 __kmp_destroy_nested_user_lock_with_checks_ =
3389 ( void ( * )( kmp_user_lock_p ) )
3390 ( &__kmp_destroy_nested_queuing_lock_with_checks );
3392 __kmp_is_user_lock_initialized_ =
3393 ( int ( * )( kmp_user_lock_p ) )
3394 ( &__kmp_is_queuing_lock_initialized );
3396 __kmp_get_user_lock_location_ =
3397 (
const ident_t * ( * )( kmp_user_lock_p ) )
3398 ( &__kmp_get_queuing_lock_location );
3400 __kmp_set_user_lock_location_ =
3401 ( void ( * )( kmp_user_lock_p,
const ident_t * ) )
3402 ( &__kmp_set_queuing_lock_location );
3404 __kmp_get_user_lock_flags_ =
3405 ( kmp_lock_flags_t ( * )( kmp_user_lock_p ) )
3406 ( &__kmp_get_queuing_lock_flags );
3408 __kmp_set_user_lock_flags_ =
3409 ( void ( * )( kmp_user_lock_p, kmp_lock_flags_t ) )
3410 ( &__kmp_set_queuing_lock_flags );
3414 #if KMP_USE_ADAPTIVE_LOCKS
3416 __kmp_base_user_lock_size =
sizeof( kmp_base_queuing_lock_t );
3417 __kmp_user_lock_size =
sizeof( kmp_queuing_lock_t );
3419 __kmp_get_user_lock_owner_ =
3420 ( kmp_int32 ( * )( kmp_user_lock_p ) )
3421 ( &__kmp_get_queuing_lock_owner );
3423 __kmp_acquire_user_lock_with_checks_ =
3424 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3425 ( &__kmp_acquire_adaptive_lock_with_checks );
3427 __kmp_test_user_lock_with_checks_ =
3428 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3429 ( &__kmp_test_adaptive_lock_with_checks );
3431 __kmp_release_user_lock_with_checks_ =
3432 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3433 ( &__kmp_release_adaptive_lock_with_checks );
3435 __kmp_init_user_lock_with_checks_ =
3436 ( void ( * )( kmp_user_lock_p ) )
3437 ( &__kmp_init_adaptive_lock_with_checks );
3439 __kmp_destroy_user_lock_with_checks_ =
3440 ( void ( * )( kmp_user_lock_p ) )
3441 ( &__kmp_destroy_adaptive_lock_with_checks );
3443 __kmp_destroy_user_lock_ =
3444 ( void ( * )( kmp_user_lock_p ) )
3445 ( &__kmp_destroy_adaptive_lock );
3447 __kmp_is_user_lock_initialized_ =
3448 ( int ( * )( kmp_user_lock_p ) )
3449 ( &__kmp_is_queuing_lock_initialized );
3451 __kmp_get_user_lock_location_ =
3452 (
const ident_t * ( * )( kmp_user_lock_p ) )
3453 ( &__kmp_get_queuing_lock_location );
3455 __kmp_set_user_lock_location_ =
3456 ( void ( * )( kmp_user_lock_p,
const ident_t * ) )
3457 ( &__kmp_set_queuing_lock_location );
3459 __kmp_get_user_lock_flags_ =
3460 ( kmp_lock_flags_t ( * )( kmp_user_lock_p ) )
3461 ( &__kmp_get_queuing_lock_flags );
3463 __kmp_set_user_lock_flags_ =
3464 ( void ( * )( kmp_user_lock_p, kmp_lock_flags_t ) )
3465 ( &__kmp_set_queuing_lock_flags );
3469 #endif // KMP_USE_ADAPTIVE_LOCKS
3472 __kmp_base_user_lock_size =
sizeof( kmp_base_drdpa_lock_t );
3473 __kmp_user_lock_size =
sizeof( kmp_drdpa_lock_t );
3475 __kmp_get_user_lock_owner_ =
3476 ( kmp_int32 ( * )( kmp_user_lock_p ) )
3477 ( &__kmp_get_drdpa_lock_owner );
3479 __kmp_acquire_user_lock_with_checks_ =
3480 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3481 ( &__kmp_acquire_drdpa_lock_with_checks );
3483 __kmp_test_user_lock_with_checks_ =
3484 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3485 ( &__kmp_test_drdpa_lock_with_checks );
3487 __kmp_release_user_lock_with_checks_ =
3488 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3489 ( &__kmp_release_drdpa_lock_with_checks );
3491 __kmp_init_user_lock_with_checks_ =
3492 ( void ( * )( kmp_user_lock_p ) )
3493 ( &__kmp_init_drdpa_lock_with_checks );
3495 __kmp_destroy_user_lock_ =
3496 ( void ( * )( kmp_user_lock_p ) )
3497 ( &__kmp_destroy_drdpa_lock );
3499 __kmp_destroy_user_lock_with_checks_ =
3500 ( void ( * )( kmp_user_lock_p ) )
3501 ( &__kmp_destroy_drdpa_lock_with_checks );
3503 __kmp_acquire_nested_user_lock_with_checks_ =
3504 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3505 ( &__kmp_acquire_nested_drdpa_lock_with_checks );
3507 __kmp_test_nested_user_lock_with_checks_ =
3508 ( int ( * )( kmp_user_lock_p, kmp_int32 ) )
3509 ( &__kmp_test_nested_drdpa_lock_with_checks );
3511 __kmp_release_nested_user_lock_with_checks_ =
3512 ( void ( * )( kmp_user_lock_p, kmp_int32 ) )
3513 ( &__kmp_release_nested_drdpa_lock_with_checks );
3515 __kmp_init_nested_user_lock_with_checks_ =
3516 ( void ( * )( kmp_user_lock_p ) )
3517 ( &__kmp_init_nested_drdpa_lock_with_checks );
3519 __kmp_destroy_nested_user_lock_with_checks_ =
3520 ( void ( * )( kmp_user_lock_p ) )
3521 ( &__kmp_destroy_nested_drdpa_lock_with_checks );
3523 __kmp_is_user_lock_initialized_ =
3524 ( int ( * )( kmp_user_lock_p ) )
3525 ( &__kmp_is_drdpa_lock_initialized );
3527 __kmp_get_user_lock_location_ =
3528 (
const ident_t * ( * )( kmp_user_lock_p ) )
3529 ( &__kmp_get_drdpa_lock_location );
3531 __kmp_set_user_lock_location_ =
3532 ( void ( * )( kmp_user_lock_p,
const ident_t * ) )
3533 ( &__kmp_set_drdpa_lock_location );
3535 __kmp_get_user_lock_flags_ =
3536 ( kmp_lock_flags_t ( * )( kmp_user_lock_p ) )
3537 ( &__kmp_get_drdpa_lock_flags );
3539 __kmp_set_user_lock_flags_ =
3540 ( void ( * )( kmp_user_lock_p, kmp_lock_flags_t ) )
3541 ( &__kmp_set_drdpa_lock_flags );
3551 kmp_lock_table_t __kmp_user_lock_table = { 1, 0, NULL };
3552 kmp_user_lock_p __kmp_lock_pool = NULL;
3555 kmp_block_of_locks* __kmp_lock_blocks = NULL;
3556 int __kmp_num_locks_in_block = 1;
3558 static kmp_lock_index_t
3559 __kmp_lock_table_insert( kmp_user_lock_p lck )
3562 kmp_lock_index_t index;
3563 if ( __kmp_user_lock_table.used >= __kmp_user_lock_table.allocated ) {
3564 kmp_lock_index_t size;
3565 kmp_user_lock_p *table;
3568 if ( __kmp_user_lock_table.allocated == 0 ) {
3572 size = __kmp_user_lock_table.allocated * 2;
3574 table = (kmp_user_lock_p *)__kmp_allocate(
sizeof( kmp_user_lock_p ) * size );
3575 memcpy( table + 1, __kmp_user_lock_table.table + 1,
sizeof( kmp_user_lock_p ) * ( __kmp_user_lock_table.used - 1 ) );
3576 table[ 0 ] = (kmp_user_lock_p)__kmp_user_lock_table.table;
3581 __kmp_user_lock_table.table = table;
3582 __kmp_user_lock_table.allocated = size;
3584 KMP_DEBUG_ASSERT( __kmp_user_lock_table.used < __kmp_user_lock_table.allocated );
3585 index = __kmp_user_lock_table.used;
3586 __kmp_user_lock_table.table[ index ] = lck;
3587 ++ __kmp_user_lock_table.used;
3591 static kmp_user_lock_p
3592 __kmp_lock_block_allocate()
3595 static int last_index = 0;
3596 if ( ( last_index >= __kmp_num_locks_in_block )
3597 || ( __kmp_lock_blocks == NULL ) ) {
3601 KMP_DEBUG_ASSERT( __kmp_user_lock_size > 0 );
3602 size_t space_for_locks = __kmp_user_lock_size * __kmp_num_locks_in_block;
3603 char* buffer = (
char*)__kmp_allocate( space_for_locks +
sizeof( kmp_block_of_locks ) );
3605 kmp_block_of_locks *new_block = (kmp_block_of_locks *)(& buffer[space_for_locks]);
3606 new_block->next_block = __kmp_lock_blocks;
3607 new_block->locks = (
void *)buffer;
3610 __kmp_lock_blocks = new_block;
3612 kmp_user_lock_p ret = (kmp_user_lock_p)(& ( ( (
char *)( __kmp_lock_blocks->locks ) )
3613 [ last_index * __kmp_user_lock_size ] ) );
3623 __kmp_user_lock_allocate(
void **user_lock, kmp_int32 gtid,
3624 kmp_lock_flags_t flags )
3626 kmp_user_lock_p lck;
3627 kmp_lock_index_t index;
3628 KMP_DEBUG_ASSERT( user_lock );
3630 __kmp_acquire_lock( &__kmp_global_lock, gtid );
3632 if ( __kmp_lock_pool == NULL ) {
3634 if ( __kmp_num_locks_in_block <= 1 ) {
3635 lck = (kmp_user_lock_p) __kmp_allocate( __kmp_user_lock_size );
3638 lck = __kmp_lock_block_allocate();
3643 index = __kmp_lock_table_insert( lck );
3647 lck = __kmp_lock_pool;
3648 index = __kmp_lock_pool->pool.index;
3649 __kmp_lock_pool = __kmp_lock_pool->pool.next;
3656 if ( OMP_LOCK_T_SIZE <
sizeof(
void *) ) {
3657 * ( (kmp_lock_index_t *) user_lock ) = index;
3660 * ( (kmp_user_lock_p *) user_lock ) = lck;
3664 __kmp_set_user_lock_flags( lck, flags );
3666 __kmp_release_lock( & __kmp_global_lock, gtid );
3673 __kmp_user_lock_free(
void **user_lock, kmp_int32 gtid, kmp_user_lock_p lck )
3675 kmp_lock_pool_t * lock_pool;
3677 KMP_DEBUG_ASSERT( user_lock != NULL );
3678 KMP_DEBUG_ASSERT( lck != NULL );
3680 __kmp_acquire_lock( & __kmp_global_lock, gtid );
3682 lck->pool.next = __kmp_lock_pool;
3683 __kmp_lock_pool = lck;
3684 if ( OMP_LOCK_T_SIZE <
sizeof(
void *) ) {
3685 kmp_lock_index_t index = * ( (kmp_lock_index_t *) user_lock );
3686 KMP_DEBUG_ASSERT( 0 < index && index <= __kmp_user_lock_table.used );
3687 lck->pool.index = index;
3690 __kmp_release_lock( & __kmp_global_lock, gtid );
3694 __kmp_lookup_user_lock(
void **user_lock,
char const *func )
3696 kmp_user_lock_p lck = NULL;
3698 if ( __kmp_env_consistency_check ) {
3699 if ( user_lock == NULL ) {
3700 KMP_FATAL( LockIsUninitialized, func );
3704 if ( OMP_LOCK_T_SIZE <
sizeof(
void *) ) {
3705 kmp_lock_index_t index = *( (kmp_lock_index_t *)user_lock );
3706 if ( __kmp_env_consistency_check ) {
3707 if ( ! ( 0 < index && index < __kmp_user_lock_table.used ) ) {
3708 KMP_FATAL( LockIsUninitialized, func );
3711 KMP_DEBUG_ASSERT( 0 < index && index < __kmp_user_lock_table.used );
3712 KMP_DEBUG_ASSERT( __kmp_user_lock_size > 0 );
3713 lck = __kmp_user_lock_table.table[index];
3716 lck = *( (kmp_user_lock_p *)user_lock );
3719 if ( __kmp_env_consistency_check ) {
3720 if ( lck == NULL ) {
3721 KMP_FATAL( LockIsUninitialized, func );
3729 __kmp_cleanup_user_locks(
void )
3736 __kmp_lock_pool = NULL;
3738 #define IS_CRITICAL(lck) \
3739 ( ( __kmp_get_user_lock_flags_ != NULL ) && \
3740 ( ( *__kmp_get_user_lock_flags_ )( lck ) & kmp_lf_critical_section ) )
3770 while ( __kmp_user_lock_table.used > 1 ) {
3777 kmp_user_lock_p lck = __kmp_user_lock_table.table[
3778 --__kmp_user_lock_table.used ];
3780 if ( ( __kmp_is_user_lock_initialized_ != NULL ) &&
3781 ( *__kmp_is_user_lock_initialized_ )( lck ) ) {
3788 if ( __kmp_env_consistency_check && ( ! IS_CRITICAL( lck ) ) &&
3789 ( ( loc = __kmp_get_user_lock_location( lck ) ) != NULL ) &&
3791 kmp_str_loc_t str_loc = __kmp_str_loc_init( loc->
psource, 0 );
3792 KMP_WARNING( CnsLockNotDestroyed, str_loc.file, str_loc.func,
3793 str_loc.line, str_loc.col );
3794 __kmp_str_loc_free( &str_loc);
3798 if ( IS_CRITICAL( lck ) ) {
3799 KA_TRACE( 20, (
"__kmp_cleanup_user_locks: free critical section lock %p (%p)\n", lck, *(
void**)lck ) );
3802 KA_TRACE( 20, (
"__kmp_cleanup_user_locks: free lock %p (%p)\n", lck, *(
void**)lck ) );
3810 __kmp_destroy_user_lock( lck );
3816 if ( __kmp_lock_blocks == NULL ) {
3826 kmp_user_lock_p *table_ptr = __kmp_user_lock_table.table;
3827 __kmp_user_lock_table.table = NULL;
3828 __kmp_user_lock_table.allocated = 0;
3830 while ( table_ptr != NULL ) {
3835 kmp_user_lock_p *next = (kmp_user_lock_p *)( table_ptr[ 0 ] );
3836 __kmp_free( table_ptr );
3843 kmp_block_of_locks_t *block_ptr = __kmp_lock_blocks;
3844 __kmp_lock_blocks = NULL;
3846 while ( block_ptr != NULL ) {
3847 kmp_block_of_locks_t *next = block_ptr->next_block;
3848 __kmp_free( block_ptr->locks );
3855 TCW_4(__kmp_init_user_locks, FALSE);