25#include <sys/syscall.h>
51 for (
i = 0;
i < 8; ++
i, ++x, ++y) {
75 return lck->lk.depth_locked != -1;
78__forceinline
static int
82#ifdef USE_LOCK_PROFILE
84 if ((curr != 0) && (curr != gtid + 1))
108 if (!__kmp_tpause_enabled)
125 char const *
const func =
"omp_set_lock";
149 char const *
const func =
"omp_test_lock";
170 char const *
const func =
"omp_unset_lock";
193 char const *
const func =
"omp_destroy_lock";
210 lck->lk.depth_locked += 1;
214 lck->lk.depth_locked = 1;
221 char const *
const func =
"omp_set_nest_lock";
234 retval = ++
lck->lk.depth_locked;
239 retval =
lck->lk.depth_locked = 1;
246 char const *
const func =
"omp_test_nest_lock";
257 if (--(
lck->lk.depth_locked) == 0) {
266 char const *
const func =
"omp_unset_nest_lock";
282 lck->lk.depth_locked = 0;
287 lck->lk.depth_locked = 0;
291 char const *
const func =
"omp_destroy_nest_lock";
311static kmp_int32 __kmp_get_futex_lock_owner(kmp_futex_lock_t *
lck) {
315static inline bool __kmp_is_futex_lock_nestable(kmp_futex_lock_t *
lck) {
316 return lck->lk.depth_locked != -1;
319__forceinline
static int
320__kmp_acquire_futex_lock_timed_template(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
325#ifdef USE_LOCK_PROFILE
327 if ((curr != 0) && (curr != gtid_code))
333 KA_TRACE(1000, (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d entering\n",
334 lck,
lck->lk.poll, gtid));
345 (
"__kmp_acquire_futex_lock: lck:%p, T#%d poll_val = 0x%x cond = 0x%x\n",
346 lck, gtid, poll_val, cond));
361 (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d can't set bit 0\n",
362 lck,
lck->lk.poll, gtid));
368 (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d bit 0 set\n",
lck,
369 lck->lk.poll, gtid));
374 (
"__kmp_acquire_futex_lock: lck:%p, T#%d before futex_wait(0x%x)\n",
375 lck, gtid, poll_val));
378 if ((rc = syscall(__NR_futex, &(
lck->lk.poll), FUTEX_WAIT, poll_val, NULL,
380 KA_TRACE(1000, (
"__kmp_acquire_futex_lock: lck:%p, T#%d futex_wait(0x%x) "
381 "failed (rc=%ld errno=%d)\n",
382 lck, gtid, poll_val, rc, errno));
387 (
"__kmp_acquire_futex_lock: lck:%p, T#%d after futex_wait(0x%x)\n",
388 lck, gtid, poll_val));
396 KA_TRACE(1000, (
"__kmp_acquire_futex_lock: lck:%p(0x%x), T#%d exiting\n",
lck,
397 lck->lk.poll, gtid));
401int __kmp_acquire_futex_lock(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
402 int retval = __kmp_acquire_futex_lock_timed_template(
lck, gtid);
406static int __kmp_acquire_futex_lock_with_checks(kmp_futex_lock_t *
lck,
408 char const *
const func =
"omp_set_lock";
410 __kmp_is_futex_lock_nestable(
lck)) {
413 if ((gtid >= 0) && (__kmp_get_futex_lock_owner(
lck) == gtid)) {
416 return __kmp_acquire_futex_lock(
lck, gtid);
419int __kmp_test_futex_lock(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
428static int __kmp_test_futex_lock_with_checks(kmp_futex_lock_t *
lck,
430 char const *
const func =
"omp_test_lock";
432 __kmp_is_futex_lock_nestable(
lck)) {
435 return __kmp_test_futex_lock(
lck, gtid);
438int __kmp_release_futex_lock(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
441 KA_TRACE(1000, (
"__kmp_release_futex_lock: lck:%p(0x%x), T#%d entering\n",
442 lck,
lck->lk.poll, gtid));
449 (
"__kmp_release_futex_lock: lck:%p, T#%d released poll_val = 0x%x\n",
450 lck, gtid, poll_val));
454 (
"__kmp_release_futex_lock: lck:%p, T#%d futex_wake 1 thread\n",
462 KA_TRACE(1000, (
"__kmp_release_futex_lock: lck:%p(0x%x), T#%d exiting\n",
lck,
463 lck->lk.poll, gtid));
469static int __kmp_release_futex_lock_with_checks(kmp_futex_lock_t *
lck,
471 char const *
const func =
"omp_unset_lock";
474 __kmp_is_futex_lock_nestable(
lck)) {
477 if (__kmp_get_futex_lock_owner(
lck) == -1) {
480 if ((gtid >= 0) && (__kmp_get_futex_lock_owner(
lck) >= 0) &&
481 (__kmp_get_futex_lock_owner(
lck) != gtid)) {
484 return __kmp_release_futex_lock(
lck, gtid);
487void __kmp_init_futex_lock(kmp_futex_lock_t *
lck) {
491void __kmp_destroy_futex_lock(kmp_futex_lock_t *
lck) {
lck->lk.poll = 0; }
493static void __kmp_destroy_futex_lock_with_checks(kmp_futex_lock_t *
lck) {
494 char const *
const func =
"omp_destroy_lock";
496 __kmp_is_futex_lock_nestable(
lck)) {
499 if (__kmp_get_futex_lock_owner(
lck) != -1) {
502 __kmp_destroy_futex_lock(
lck);
507int __kmp_acquire_nested_futex_lock(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
510 if (__kmp_get_futex_lock_owner(
lck) == gtid) {
511 lck->lk.depth_locked += 1;
514 __kmp_acquire_futex_lock_timed_template(
lck, gtid);
515 lck->lk.depth_locked = 1;
520static int __kmp_acquire_nested_futex_lock_with_checks(kmp_futex_lock_t *
lck,
522 char const *
const func =
"omp_set_nest_lock";
523 if (!__kmp_is_futex_lock_nestable(
lck)) {
526 return __kmp_acquire_nested_futex_lock(
lck, gtid);
529int __kmp_test_nested_futex_lock(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
534 if (__kmp_get_futex_lock_owner(
lck) == gtid) {
535 retval = ++
lck->lk.depth_locked;
536 }
else if (!__kmp_test_futex_lock(
lck, gtid)) {
540 retval =
lck->lk.depth_locked = 1;
545static int __kmp_test_nested_futex_lock_with_checks(kmp_futex_lock_t *
lck,
547 char const *
const func =
"omp_test_nest_lock";
548 if (!__kmp_is_futex_lock_nestable(
lck)) {
551 return __kmp_test_nested_futex_lock(
lck, gtid);
554int __kmp_release_nested_futex_lock(kmp_futex_lock_t *
lck,
kmp_int32 gtid) {
558 if (--(
lck->lk.depth_locked) == 0) {
559 __kmp_release_futex_lock(
lck, gtid);
565static int __kmp_release_nested_futex_lock_with_checks(kmp_futex_lock_t *
lck,
567 char const *
const func =
"omp_unset_nest_lock";
569 if (!__kmp_is_futex_lock_nestable(
lck)) {
572 if (__kmp_get_futex_lock_owner(
lck) == -1) {
575 if (__kmp_get_futex_lock_owner(
lck) != gtid) {
578 return __kmp_release_nested_futex_lock(
lck, gtid);
581void __kmp_init_nested_futex_lock(kmp_futex_lock_t *
lck) {
582 __kmp_init_futex_lock(
lck);
583 lck->lk.depth_locked = 0;
586void __kmp_destroy_nested_futex_lock(kmp_futex_lock_t *
lck) {
587 __kmp_destroy_futex_lock(
lck);
588 lck->lk.depth_locked = 0;
591static void __kmp_destroy_nested_futex_lock_with_checks(kmp_futex_lock_t *
lck) {
592 char const *
const func =
"omp_destroy_nest_lock";
593 if (!__kmp_is_futex_lock_nestable(
lck)) {
596 if (__kmp_get_futex_lock_owner(
lck) != -1) {
599 __kmp_destroy_nested_futex_lock(
lck);
608 return std::atomic_load_explicit(&
lck->lk.owner_id,
609 std::memory_order_relaxed) -
614 return std::atomic_load_explicit(&
lck->lk.depth_locked,
615 std::memory_order_relaxed) != -1;
619 return std::atomic_load_explicit((std::atomic<unsigned> *)now_serving,
620 std::memory_order_acquire) == my_ticket;
623__forceinline
static int
626 kmp_uint32 my_ticket = std::atomic_fetch_add_explicit(
627 &
lck->lk.next_ticket, 1U, std::memory_order_relaxed);
629#ifdef USE_LOCK_PROFILE
630 if (std::atomic_load_explicit(&
lck->lk.now_serving,
631 std::memory_order_relaxed) != my_ticket)
636 if (std::atomic_load_explicit(&
lck->lk.now_serving,
637 std::memory_order_acquire) == my_ticket) {
651 char const *
const func =
"omp_set_lock";
653 if (!std::atomic_load_explicit(&
lck->lk.initialized,
654 std::memory_order_relaxed)) {
657 if (
lck->lk.self !=
lck) {
669 std::atomic_store_explicit(&
lck->lk.owner_id, gtid + 1,
670 std::memory_order_relaxed);
675 kmp_uint32 my_ticket = std::atomic_load_explicit(&
lck->lk.next_ticket,
676 std::memory_order_relaxed);
678 if (std::atomic_load_explicit(&
lck->lk.now_serving,
679 std::memory_order_relaxed) == my_ticket) {
681 if (std::atomic_compare_exchange_strong_explicit(
682 &
lck->lk.next_ticket, &my_ticket, next_ticket,
683 std::memory_order_acquire, std::memory_order_acquire)) {
692 char const *
const func =
"omp_test_lock";
694 if (!std::atomic_load_explicit(&
lck->lk.initialized,
695 std::memory_order_relaxed)) {
698 if (
lck->lk.self !=
lck) {
708 std::atomic_store_explicit(&
lck->lk.owner_id, gtid + 1,
709 std::memory_order_relaxed);
715 std::atomic_fetch_add_explicit(&
lck->lk.now_serving, 1U,
716 std::memory_order_release);
723 char const *
const func =
"omp_unset_lock";
725 if (!std::atomic_load_explicit(&
lck->lk.initialized,
726 std::memory_order_relaxed)) {
729 if (
lck->lk.self !=
lck) {
742 std::atomic_store_explicit(&
lck->lk.owner_id, 0, std::memory_order_relaxed);
747 lck->lk.location = NULL;
749 std::atomic_store_explicit(&
lck->lk.next_ticket, 0U,
750 std::memory_order_relaxed);
751 std::atomic_store_explicit(&
lck->lk.now_serving, 0U,
752 std::memory_order_relaxed);
753 std::atomic_store_explicit(
754 &
lck->lk.owner_id, 0,
755 std::memory_order_relaxed);
756 std::atomic_store_explicit(
757 &
lck->lk.depth_locked, -1,
758 std::memory_order_relaxed);
759 std::atomic_store_explicit(&
lck->lk.initialized,
true,
760 std::memory_order_release);
764 std::atomic_store_explicit(&
lck->lk.initialized,
false,
765 std::memory_order_release);
767 lck->lk.location = NULL;
768 std::atomic_store_explicit(&
lck->lk.next_ticket, 0U,
769 std::memory_order_relaxed);
770 std::atomic_store_explicit(&
lck->lk.now_serving, 0U,
771 std::memory_order_relaxed);
772 std::atomic_store_explicit(&
lck->lk.owner_id, 0, std::memory_order_relaxed);
773 std::atomic_store_explicit(&
lck->lk.depth_locked, -1,
774 std::memory_order_relaxed);
778 char const *
const func =
"omp_destroy_lock";
780 if (!std::atomic_load_explicit(&
lck->lk.initialized,
781 std::memory_order_relaxed)) {
784 if (
lck->lk.self !=
lck) {
802 std::atomic_fetch_add_explicit(&
lck->lk.depth_locked, 1,
803 std::memory_order_relaxed);
807 std::atomic_store_explicit(&
lck->lk.depth_locked, 1,
808 std::memory_order_relaxed);
809 std::atomic_store_explicit(&
lck->lk.owner_id, gtid + 1,
810 std::memory_order_relaxed);
817 char const *
const func =
"omp_set_nest_lock";
819 if (!std::atomic_load_explicit(&
lck->lk.initialized,
820 std::memory_order_relaxed)) {
823 if (
lck->lk.self !=
lck) {
838 retval = std::atomic_fetch_add_explicit(&
lck->lk.depth_locked, 1,
839 std::memory_order_relaxed) +
844 std::atomic_store_explicit(&
lck->lk.depth_locked, 1,
845 std::memory_order_relaxed);
846 std::atomic_store_explicit(&
lck->lk.owner_id, gtid + 1,
847 std::memory_order_relaxed);
855 char const *
const func =
"omp_test_nest_lock";
857 if (!std::atomic_load_explicit(&
lck->lk.initialized,
858 std::memory_order_relaxed)) {
861 if (
lck->lk.self !=
lck) {
873 if ((std::atomic_fetch_add_explicit(&
lck->lk.depth_locked, -1,
874 std::memory_order_relaxed) -
876 std::atomic_store_explicit(&
lck->lk.owner_id, 0, std::memory_order_relaxed);
885 char const *
const func =
"omp_unset_nest_lock";
887 if (!std::atomic_load_explicit(&
lck->lk.initialized,
888 std::memory_order_relaxed)) {
891 if (
lck->lk.self !=
lck) {
908 std::atomic_store_explicit(&
lck->lk.depth_locked, 0,
909 std::memory_order_relaxed);
915 std::atomic_store_explicit(&
lck->lk.depth_locked, 0,
916 std::memory_order_relaxed);
921 char const *
const func =
"omp_destroy_nest_lock";
923 if (!std::atomic_load_explicit(&
lck->lk.initialized,
924 std::memory_order_relaxed)) {
927 if (
lck->lk.self !=
lck) {
942 return lck->lk.location;
951 return lck->lk.flags;
956 lck->lk.flags = flags;
1014#ifdef DEBUG_QUEUING_LOCKS
1017#define TRACE_BUF_ELE 1024
1018static char traces[TRACE_BUF_ELE][128] = {0};
1020#define TRACE_LOCK(X, Y) \
1021 KMP_SNPRINTF(traces[tc++ % TRACE_BUF_ELE], 128, "t%d at %s\n", X, Y);
1022#define TRACE_LOCK_T(X, Y, Z) \
1023 KMP_SNPRINTF(traces[tc++ % TRACE_BUF_ELE], 128, "t%d at %s%d\n", X, Y, Z);
1024#define TRACE_LOCK_HT(X, Y, Z, Q) \
1025 KMP_SNPRINTF(traces[tc++ % TRACE_BUF_ELE], 128, "t%d at %s %d,%d\n", X, Y, \
1035 i = tc % TRACE_BUF_ELE;
1037 i = (
i + 1) % TRACE_BUF_ELE;
1038 while (
i != (tc % TRACE_BUF_ELE)) {
1040 i = (
i + 1) % TRACE_BUF_ELE;
1045 "next_wait:%d, head_id:%d, tail_id:%d\n",
1046 gtid + 1, this_thr->th.th_spin_here,
1047 this_thr->th.th_next_waiting, head_id, tail_id);
1051 if (
lck->lk.head_id >= 1) {
1065 return TCR_4(
lck->lk.owner_id) - 1;
1069 return lck->lk.depth_locked != -1;
1073template <
bool takeTime>
1076__forceinline
static int
1085 ompt_state_t prev_state = ompt_state_undefined;
1089 (
"__kmp_acquire_queuing_lock: lck:%p, T#%d entering\n",
lck, gtid));
1093 spin_here_p = &this_thr->th.th_spin_here;
1095#ifdef DEBUG_QUEUING_LOCKS
1096 TRACE_LOCK(gtid + 1,
"acq ent");
1098 __kmp_dump_queuing_lock(this_thr, gtid,
lck, *head_id_p, *tail_id_p);
1099 if (this_thr->th.th_next_waiting != 0)
1100 __kmp_dump_queuing_lock(this_thr, gtid,
lck, *head_id_p, *tail_id_p);
1112 *spin_here_p =
TRUE;
1124#ifdef DEBUG_QUEUING_LOCKS
1126 TRACE_LOCK_HT(gtid + 1,
"acq read: ",
head,
tail);
1137#ifdef DEBUG_QUEUING_LOCKS
1139 TRACE_LOCK(gtid + 1,
"acq enq: (-1,0)->(tid,tid)");
1147#ifdef DEBUG_QUEUING_LOCKS
1148 TRACE_LOCK_HT(gtid + 1,
"acq read: ",
head,
tail);
1157#ifdef DEBUG_QUEUING_LOCKS
1159 TRACE_LOCK(gtid + 1,
"acq enq: (h,t)->(h,tid)");
1168#ifdef DEBUG_QUEUING_LOCKS
1170 TRACE_LOCK_HT(gtid + 1,
"acq read: ",
head,
tail);
1180 *spin_here_p =
FALSE;
1184 (
"__kmp_acquire_queuing_lock: lck:%p, T#%d exiting: no queuing\n",
1186#ifdef DEBUG_QUEUING_LOCKS
1187 TRACE_LOCK_HT(gtid + 1,
"acq exit: ",
head, 0);
1191 if (
ompt_enabled.enabled && prev_state != ompt_state_undefined) {
1193 this_thr->th.ompt_thread_info.state = prev_state;
1194 this_thr->th.ompt_thread_info.wait_id = 0;
1206 if (
ompt_enabled.enabled && prev_state == ompt_state_undefined) {
1208 prev_state = this_thr->th.ompt_thread_info.state;
1209 this_thr->th.ompt_thread_info.wait_id = (uint64_t)
lck;
1210 this_thr->th.ompt_thread_info.state = ompt_state_wait_lock;
1218 tail_thr->th.th_next_waiting = gtid + 1;
1222 (
"__kmp_acquire_queuing_lock: lck:%p, T#%d waiting for lock\n",
1232#ifdef DEBUG_QUEUING_LOCKS
1233 TRACE_LOCK(gtid + 1,
"acq spin");
1235 if (this_thr->th.th_next_waiting != 0)
1236 __kmp_dump_queuing_lock(this_thr, gtid,
lck, *head_id_p, *tail_id_p);
1239 KA_TRACE(1000, (
"__kmp_acquire_queuing_lock: lck:%p, T#%d exiting: after "
1240 "waiting on queue\n",
1243#ifdef DEBUG_QUEUING_LOCKS
1244 TRACE_LOCK(gtid + 1,
"acq exit 2");
1249 this_thr->th.ompt_thread_info.state = prev_state;
1250 this_thr->th.ompt_thread_info.wait_id = 0;
1262#ifdef DEBUG_QUEUING_LOCKS
1263 TRACE_LOCK(gtid + 1,
"acq retry");
1279 char const *
const func =
"omp_set_lock";
1280 if (
lck->lk.initialized !=
lck) {
1292 lck->lk.owner_id = gtid + 1;
1303 KA_TRACE(1000, (
"__kmp_test_queuing_lock: T#%d entering\n", gtid));
1317 (
"__kmp_test_queuing_lock: T#%d exiting: holding lock\n", gtid));
1324 (
"__kmp_test_queuing_lock: T#%d exiting: without lock\n", gtid));
1330 char const *
const func =
"omp_test_lock";
1331 if (
lck->lk.initialized !=
lck) {
1341 lck->lk.owner_id = gtid + 1;
1351 (
"__kmp_release_queuing_lock: lck:%p, T#%d entering\n",
lck, gtid));
1353#if KMP_DEBUG || DEBUG_QUEUING_LOCKS
1357#ifdef DEBUG_QUEUING_LOCKS
1358 TRACE_LOCK(gtid + 1,
"rel ent");
1360 if (this_thr->th.th_spin_here)
1361 __kmp_dump_queuing_lock(this_thr, gtid,
lck, *head_id_p, *tail_id_p);
1362 if (this_thr->th.th_next_waiting != 0)
1363 __kmp_dump_queuing_lock(this_thr, gtid,
lck, *head_id_p, *tail_id_p);
1377#ifdef DEBUG_QUEUING_LOCKS
1379 TRACE_LOCK_HT(gtid + 1,
"rel read: ",
head,
tail);
1381 __kmp_dump_queuing_lock(this_thr, gtid,
lck,
head,
tail);
1391 (
"__kmp_release_queuing_lock: lck:%p, T#%d exiting: queue empty\n",
1393#ifdef DEBUG_QUEUING_LOCKS
1394 TRACE_LOCK_HT(gtid + 1,
"rel exit: ", 0, 0);
1407#ifdef DEBUG_QUEUING_LOCKS
1409 __kmp_dump_queuing_lock(this_thr, gtid,
lck,
head,
tail);
1417#ifdef DEBUG_QUEUING_LOCKS
1418 TRACE_LOCK(gtid + 1,
"rel deq: (h,h)->(-1,0)");
1425 waiting_id_p = &head_thr->th.th_next_waiting;
1428#ifdef DEBUG_QUEUING_LOCKS
1430 __kmp_dump_queuing_lock(this_thr, gtid,
lck,
head,
tail);
1440#ifdef DEBUG_QUEUING_LOCKS
1441 TRACE_LOCK(gtid + 1,
"rel deq: (h,t)->(h',t)");
1452#ifdef DEBUG_QUEUING_LOCKS
1454 __kmp_dump_queuing_lock(this_thr, gtid,
lck,
head,
tail);
1460 head_thr->th.th_next_waiting = 0;
1461#ifdef DEBUG_QUEUING_LOCKS
1462 TRACE_LOCK_T(gtid + 1,
"rel nw=0 for t=",
head);
1467 head_thr->th.th_spin_here =
FALSE;
1469 KA_TRACE(1000, (
"__kmp_release_queuing_lock: lck:%p, T#%d exiting: after "
1472#ifdef DEBUG_QUEUING_LOCKS
1473 TRACE_LOCK(gtid + 1,
"rel exit 2");
1480#ifdef DEBUG_QUEUING_LOCKS
1481 TRACE_LOCK(gtid + 1,
"rel retry");
1491 char const *
const func =
"omp_unset_lock";
1493 if (
lck->lk.initialized !=
lck) {
1505 lck->lk.owner_id = 0;
1510 lck->lk.location = NULL;
1511 lck->lk.head_id = 0;
1512 lck->lk.tail_id = 0;
1513 lck->lk.next_ticket = 0;
1514 lck->lk.now_serving = 0;
1515 lck->lk.owner_id = 0;
1516 lck->lk.depth_locked = -1;
1517 lck->lk.initialized =
lck;
1519 KA_TRACE(1000, (
"__kmp_init_queuing_lock: lock %p initialized\n",
lck));
1523 lck->lk.initialized = NULL;
1524 lck->lk.location = NULL;
1525 lck->lk.head_id = 0;
1526 lck->lk.tail_id = 0;
1527 lck->lk.next_ticket = 0;
1528 lck->lk.now_serving = 0;
1529 lck->lk.owner_id = 0;
1530 lck->lk.depth_locked = -1;
1534 char const *
const func =
"omp_destroy_lock";
1535 if (
lck->lk.initialized !=
lck) {
1553 lck->lk.depth_locked += 1;
1558 lck->lk.depth_locked = 1;
1560 lck->lk.owner_id = gtid + 1;
1568 char const *
const func =
"omp_set_nest_lock";
1569 if (
lck->lk.initialized !=
lck) {
1584 retval = ++
lck->lk.depth_locked;
1589 retval =
lck->lk.depth_locked = 1;
1591 lck->lk.owner_id = gtid + 1;
1598 char const *
const func =
"omp_test_nest_lock";
1599 if (
lck->lk.initialized !=
lck) {
1612 if (--(
lck->lk.depth_locked) == 0) {
1614 lck->lk.owner_id = 0;
1624 char const *
const func =
"omp_unset_nest_lock";
1626 if (
lck->lk.initialized !=
lck) {
1643 lck->lk.depth_locked = 0;
1648 lck->lk.depth_locked = 0;
1653 char const *
const func =
"omp_destroy_nest_lock";
1654 if (
lck->lk.initialized !=
lck) {
1669 return lck->lk.location;
1678 return lck->lk.flags;
1683 lck->lk.flags = flags;
1686#if KMP_USE_ADAPTIVE_LOCKS
1690#if KMP_HAVE_RTM_INTRINSICS
1691#include <immintrin.h>
1692#define SOFT_ABORT_MASK (_XABORT_RETRY | _XABORT_CONFLICT | _XABORT_EXPLICIT)
1697#define _XBEGIN_STARTED (~0u)
1698#define _XABORT_EXPLICIT (1 << 0)
1699#define _XABORT_RETRY (1 << 1)
1700#define _XABORT_CONFLICT (1 << 2)
1701#define _XABORT_CAPACITY (1 << 3)
1702#define _XABORT_DEBUG (1 << 4)
1703#define _XABORT_NESTED (1 << 5)
1704#define _XABORT_CODE(x) ((unsigned char)(((x) >> 24) & 0xFF))
1707#define SOFT_ABORT_MASK (_XABORT_RETRY | _XABORT_CONFLICT | _XABORT_EXPLICIT)
1709#define STRINGIZE_INTERNAL(arg) #arg
1710#define STRINGIZE(arg) STRINGIZE_INTERNAL(arg)
1716static __inline
int _xbegin() {
1753 __asm__
volatile(
"1: .byte 0xC7; .byte 0xF8;\n"
1756 "1: movl %%eax,%0\n"
1758 :
"+r"(
res)::
"memory",
"%eax");
1764static __inline
void _xend() {
1772 __asm__
volatile(
".byte 0x0f; .byte 0x01; .byte 0xd5" :::
"memory");
1781#define _xabort(ARG) _asm _emit 0xc6 _asm _emit 0xf8 _asm _emit ARG
1783#define _xabort(ARG) \
1784 __asm__ volatile(".byte 0xC6; .byte 0xF8; .byte " STRINGIZE(ARG):::"memory");
1790#if KMP_DEBUG_ADAPTIVE_LOCKS
1795static kmp_adaptive_lock_statistics_t destroyedStats;
1798static kmp_adaptive_lock_info_t liveLocks;
1805void __kmp_init_speculative_stats() {
1806 kmp_adaptive_lock_info_t *
lck = &liveLocks;
1808 memset(
CCAST(kmp_adaptive_lock_statistics_t *, &(
lck->stats)), 0,
1809 sizeof(
lck->stats));
1820static void __kmp_remember_lock(kmp_adaptive_lock_info_t *
lck) {
1823 lck->stats.next = liveLocks.stats.next;
1824 lck->stats.prev = &liveLocks;
1826 liveLocks.stats.next =
lck;
1827 lck->stats.next->stats.prev =
lck;
1835static void __kmp_forget_lock(kmp_adaptive_lock_info_t *
lck) {
1839 kmp_adaptive_lock_info_t *n =
lck->stats.next;
1840 kmp_adaptive_lock_info_t *
p =
lck->stats.prev;
1846static void __kmp_zero_speculative_stats(kmp_adaptive_lock_info_t *
lck) {
1847 memset(
CCAST(kmp_adaptive_lock_statistics_t *, &
lck->stats), 0,
1848 sizeof(
lck->stats));
1849 __kmp_remember_lock(
lck);
1852static void __kmp_add_stats(kmp_adaptive_lock_statistics_t *t,
1853 kmp_adaptive_lock_info_t *
lck) {
1854 kmp_adaptive_lock_statistics_t
volatile *
s = &
lck->stats;
1856 t->nonSpeculativeAcquireAttempts +=
lck->acquire_attempts;
1857 t->successfulSpeculations +=
s->successfulSpeculations;
1858 t->hardFailedSpeculations +=
s->hardFailedSpeculations;
1859 t->softFailedSpeculations +=
s->softFailedSpeculations;
1860 t->nonSpeculativeAcquires +=
s->nonSpeculativeAcquires;
1861 t->lemmingYields +=
s->lemmingYields;
1864static void __kmp_accumulate_speculative_stats(kmp_adaptive_lock_info_t *
lck) {
1867 __kmp_add_stats(&destroyedStats,
lck);
1868 __kmp_forget_lock(
lck);
1874 return (total == 0) ? 0.0 : (100.0 *
count) / total;
1877void __kmp_print_speculative_stats() {
1878 kmp_adaptive_lock_statistics_t total = destroyedStats;
1879 kmp_adaptive_lock_info_t *
lck;
1881 for (
lck = liveLocks.stats.next;
lck != &liveLocks;
lck =
lck->stats.next) {
1882 __kmp_add_stats(&total,
lck);
1884 kmp_adaptive_lock_statistics_t *t = &total;
1886 t->nonSpeculativeAcquires + t->successfulSpeculations;
1887 kmp_uint32 totalSpeculations = t->successfulSpeculations +
1888 t->hardFailedSpeculations +
1889 t->softFailedSpeculations;
1890 if (totalSections <= 0)
1894 if (strcmp(__kmp_speculative_statsfile,
"-") == 0) {
1897 size_t buffLen =
KMP_STRLEN(__kmp_speculative_statsfile) + 20;
1898 char buffer[buffLen];
1899 KMP_SNPRINTF(&buffer[0], buffLen, __kmp_speculative_statsfile,
1901 statsFile.
open(buffer,
"w");
1904 fprintf(statsFile,
"Speculative lock statistics (all approximate!)\n");
1906 " Lock parameters: \n"
1907 " max_soft_retries : %10d\n"
1908 " max_badness : %10d\n",
1909 __kmp_adaptive_backoff_params.max_soft_retries,
1910 __kmp_adaptive_backoff_params.max_badness);
1911 fprintf(statsFile,
" Non-speculative acquire attempts : %10d\n",
1912 t->nonSpeculativeAcquireAttempts);
1913 fprintf(statsFile,
" Total critical sections : %10d\n",
1915 fprintf(statsFile,
" Successful speculations : %10d (%5.1f%%)\n",
1916 t->successfulSpeculations,
1917 percent(t->successfulSpeculations, totalSections));
1918 fprintf(statsFile,
" Non-speculative acquires : %10d (%5.1f%%)\n",
1919 t->nonSpeculativeAcquires,
1920 percent(t->nonSpeculativeAcquires, totalSections));
1921 fprintf(statsFile,
" Lemming yields : %10d\n\n",
1924 fprintf(statsFile,
" Speculative acquire attempts : %10d\n",
1926 fprintf(statsFile,
" Successes : %10d (%5.1f%%)\n",
1927 t->successfulSpeculations,
1928 percent(t->successfulSpeculations, totalSpeculations));
1929 fprintf(statsFile,
" Soft failures : %10d (%5.1f%%)\n",
1930 t->softFailedSpeculations,
1931 percent(t->softFailedSpeculations, totalSpeculations));
1932 fprintf(statsFile,
" Hard failures : %10d (%5.1f%%)\n",
1933 t->hardFailedSpeculations,
1934 percent(t->hardFailedSpeculations, totalSpeculations));
1937#define KMP_INC_STAT(lck, stat) (lck->lk.adaptive.stats.stat++)
1939#define KMP_INC_STAT(lck, stat)
1946 bool res =
lck->lk.head_id == 0;
1950#if KMP_COMPILER_ICC || KMP_COMPILER_ICX
1953 __sync_synchronize();
1961__kmp_update_badness_after_success(kmp_adaptive_lock_t *
lck) {
1963 lck->lk.adaptive.badness = 0;
1964 KMP_INC_STAT(
lck, successfulSpeculations);
1968static __inline
void __kmp_step_badness(kmp_adaptive_lock_t *
lck) {
1969 kmp_uint32 newBadness = (
lck->lk.adaptive.badness << 1) | 1;
1970 if (newBadness >
lck->lk.adaptive.max_badness) {
1973 lck->lk.adaptive.badness = newBadness;
1979static __inline
int __kmp_should_speculate(kmp_adaptive_lock_t *
lck,
1983 int res = (attempts & badness) == 0;
1990static int __kmp_test_adaptive_lock_only(kmp_adaptive_lock_t *
lck,
1992 int retries =
lck->lk.adaptive.max_soft_retries;
2004 if (
status == _XBEGIN_STARTED) {
2009 if (!__kmp_is_unlocked_queuing_lock(GET_QLK_PTR(
lck))) {
2018 if (
status & SOFT_ABORT_MASK) {
2019 KMP_INC_STAT(
lck, softFailedSpeculations);
2022 KMP_INC_STAT(
lck, hardFailedSpeculations);
2027 }
while (retries--);
2031 __kmp_step_badness(
lck);
2038static int __kmp_test_adaptive_lock(kmp_adaptive_lock_t *
lck,
kmp_int32 gtid) {
2040 if (__kmp_should_speculate(
lck, gtid) &&
2041 __kmp_test_adaptive_lock_only(
lck, gtid))
2046 lck->lk.adaptive.acquire_attempts++;
2050 KMP_INC_STAT(
lck, nonSpeculativeAcquires);
2057static int __kmp_test_adaptive_lock_with_checks(kmp_adaptive_lock_t *
lck,
2059 char const *
const func =
"omp_test_lock";
2060 if (
lck->lk.qlk.initialized != GET_QLK_PTR(
lck)) {
2064 int retval = __kmp_test_adaptive_lock(
lck, gtid);
2067 lck->lk.qlk.owner_id = gtid + 1;
2083static void __kmp_acquire_adaptive_lock(kmp_adaptive_lock_t *
lck,
2085 if (__kmp_should_speculate(
lck, gtid)) {
2086 if (__kmp_is_unlocked_queuing_lock(GET_QLK_PTR(
lck))) {
2087 if (__kmp_test_adaptive_lock_only(
lck, gtid))
2096 while (!__kmp_is_unlocked_queuing_lock(GET_QLK_PTR(
lck))) {
2097 KMP_INC_STAT(
lck, lemmingYields);
2101 if (__kmp_test_adaptive_lock_only(
lck, gtid))
2108 lck->lk.adaptive.acquire_attempts++;
2112 KMP_INC_STAT(
lck, nonSpeculativeAcquires);
2115static void __kmp_acquire_adaptive_lock_with_checks(kmp_adaptive_lock_t *
lck,
2117 char const *
const func =
"omp_set_lock";
2118 if (
lck->lk.qlk.initialized != GET_QLK_PTR(
lck)) {
2125 __kmp_acquire_adaptive_lock(
lck, gtid);
2127 lck->lk.qlk.owner_id = gtid + 1;
2131static int __kmp_release_adaptive_lock(kmp_adaptive_lock_t *
lck,
2133 if (__kmp_is_unlocked_queuing_lock(GET_QLK_PTR(
2138 __kmp_update_badness_after_success(
lck);
2146static int __kmp_release_adaptive_lock_with_checks(kmp_adaptive_lock_t *
lck,
2148 char const *
const func =
"omp_unset_lock";
2150 if (
lck->lk.qlk.initialized != GET_QLK_PTR(
lck)) {
2159 lck->lk.qlk.owner_id = 0;
2160 __kmp_release_adaptive_lock(
lck, gtid);
2164static void __kmp_init_adaptive_lock(kmp_adaptive_lock_t *
lck) {
2166 lck->lk.adaptive.badness = 0;
2167 lck->lk.adaptive.acquire_attempts = 0;
2168 lck->lk.adaptive.max_soft_retries =
2169 __kmp_adaptive_backoff_params.max_soft_retries;
2170 lck->lk.adaptive.max_badness = __kmp_adaptive_backoff_params.max_badness;
2171#if KMP_DEBUG_ADAPTIVE_LOCKS
2172 __kmp_zero_speculative_stats(&
lck->lk.adaptive);
2174 KA_TRACE(1000, (
"__kmp_init_adaptive_lock: lock %p initialized\n",
lck));
2177static void __kmp_destroy_adaptive_lock(kmp_adaptive_lock_t *
lck) {
2178#if KMP_DEBUG_ADAPTIVE_LOCKS
2179 __kmp_accumulate_speculative_stats(&
lck->lk.adaptive);
2185static void __kmp_destroy_adaptive_lock_with_checks(kmp_adaptive_lock_t *
lck) {
2186 char const *
const func =
"omp_destroy_lock";
2187 if (
lck->lk.qlk.initialized != GET_QLK_PTR(
lck)) {
2193 __kmp_destroy_adaptive_lock(
lck);
2203 return lck->lk.owner_id - 1;
2207 return lck->lk.depth_locked != -1;
2210__forceinline
static int
2214 std::atomic<kmp_uint64> *polls =
lck->lk.polls;
2216#ifdef USE_LOCK_PROFILE
2217 if (polls[ticket &
mask] != ticket)
2234 while (polls[ticket &
mask] < ticket) {
2244 polls =
lck->lk.polls;
2249 KA_TRACE(1000, (
"__kmp_acquire_drdpa_lock: ticket #%lld acquired lock %p\n",
2251 lck->lk.now_serving = ticket;
2258 if ((
lck->lk.old_polls != NULL) && (ticket >=
lck->lk.cleanup_ticket)) {
2260 lck->lk.old_polls = NULL;
2261 lck->lk.cleanup_ticket = 0;
2267 if (
lck->lk.old_polls == NULL) {
2268 bool reconfigure =
false;
2269 std::atomic<kmp_uint64> *old_polls = polls;
2276 if (num_polls > 1) {
2278 num_polls =
TCR_4(
lck->lk.num_polls);
2290 if (num_waiting > num_polls) {
2296 }
while (num_polls <= num_waiting);
2305 for (
i = 0;
i < old_num_polls;
i++) {
2306 polls[
i].store(old_polls[
i]);
2321 KA_TRACE(1000, (
"__kmp_acquire_drdpa_lock: ticket #%lld reconfiguring "
2322 "lock %p to %d polls\n",
2323 ticket,
lck, num_polls));
2325 lck->lk.old_polls = old_polls;
2326 lck->lk.polls = polls;
2330 lck->lk.num_polls = num_polls;
2339 lck->lk.cleanup_ticket =
lck->lk.next_ticket;
2352 char const *
const func =
"omp_set_lock";
2353 if (
lck->lk.initialized !=
lck) {
2365 lck->lk.owner_id = gtid + 1;
2373 std::atomic<kmp_uint64> *polls =
lck->lk.polls;
2375 if (polls[ticket &
mask] == ticket) {
2380 KA_TRACE(1000, (
"__kmp_test_drdpa_lock: ticket #%lld acquired lock %p\n",
2382 lck->lk.now_serving = ticket;
2398 char const *
const func =
"omp_test_lock";
2399 if (
lck->lk.initialized !=
lck) {
2409 lck->lk.owner_id = gtid + 1;
2418 std::atomic<kmp_uint64> *polls =
lck->lk.polls;
2420 KA_TRACE(1000, (
"__kmp_release_drdpa_lock: ticket #%lld released lock %p\n",
2423 polls[ticket &
mask] = ticket;
2429 char const *
const func =
"omp_unset_lock";
2431 if (
lck->lk.initialized !=
lck) {
2444 lck->lk.owner_id = 0;
2449 lck->lk.location = NULL;
2451 lck->lk.num_polls = 1;
2453 lck->lk.num_polls *
sizeof(*(
lck->lk.polls)));
2454 lck->lk.cleanup_ticket = 0;
2455 lck->lk.old_polls = NULL;
2456 lck->lk.next_ticket = 0;
2457 lck->lk.now_serving = 0;
2458 lck->lk.owner_id = 0;
2459 lck->lk.depth_locked = -1;
2460 lck->lk.initialized =
lck;
2462 KA_TRACE(1000, (
"__kmp_init_drdpa_lock: lock %p initialized\n",
lck));
2466 lck->lk.initialized = NULL;
2467 lck->lk.location = NULL;
2468 if (
lck->lk.polls.load() != NULL) {
2470 lck->lk.polls = NULL;
2472 if (
lck->lk.old_polls != NULL) {
2474 lck->lk.old_polls = NULL;
2477 lck->lk.num_polls = 0;
2478 lck->lk.cleanup_ticket = 0;
2479 lck->lk.next_ticket = 0;
2480 lck->lk.now_serving = 0;
2481 lck->lk.owner_id = 0;
2482 lck->lk.depth_locked = -1;
2486 char const *
const func =
"omp_destroy_lock";
2487 if (
lck->lk.initialized !=
lck) {
2505 lck->lk.depth_locked += 1;
2510 lck->lk.depth_locked = 1;
2512 lck->lk.owner_id = gtid + 1;
2519 char const *
const func =
"omp_set_nest_lock";
2520 if (
lck->lk.initialized !=
lck) {
2535 retval = ++
lck->lk.depth_locked;
2540 retval =
lck->lk.depth_locked = 1;
2542 lck->lk.owner_id = gtid + 1;
2549 char const *
const func =
"omp_test_nest_lock";
2550 if (
lck->lk.initialized !=
lck) {
2563 if (--(
lck->lk.depth_locked) == 0) {
2565 lck->lk.owner_id = 0;
2574 char const *
const func =
"omp_unset_nest_lock";
2576 if (
lck->lk.initialized !=
lck) {
2593 lck->lk.depth_locked = 0;
2598 lck->lk.depth_locked = 0;
2602 char const *
const func =
"omp_destroy_nest_lock";
2603 if (
lck->lk.initialized !=
lck) {
2618 return lck->lk.location;
2627 return lck->lk.flags;
2632 lck->lk.flags = flags;
2636#if KMP_ARCH_X86 || KMP_ARCH_X86_64
2637#define __kmp_tsc() __kmp_hardware_timestamp()
2644#define __kmp_tsc() __kmp_now_nsec()
2662 for (
i = boff->
step;
i > 0;
i--) {
2665 if (__kmp_umwait_enabled) {
2679#if KMP_USE_DYNAMIC_LOCK
2683static void __kmp_init_direct_lock(kmp_dyna_lock_t *
lck,
2684 kmp_dyna_lockseq_t seq) {
2688 (
"__kmp_init_direct_lock: initialized direct lock with type#%d\n", seq));
2694#define HLE_ACQUIRE ".byte 0xf2;"
2695#define HLE_RELEASE ".byte 0xf3;"
2698 __asm__
volatile(HLE_ACQUIRE
"xchg %1,%0" :
"+r"(v),
"+m"(*p) : :
"memory");
2702static void __kmp_destroy_hle_lock(kmp_dyna_lock_t *
lck) {
TCW_4(*
lck, 0); }
2704static void __kmp_destroy_hle_lock_with_checks(kmp_dyna_lock_t *
lck) {
2708static void __kmp_acquire_hle_lock(kmp_dyna_lock_t *
lck,
kmp_int32 gtid) {
2722static void __kmp_acquire_hle_lock_with_checks(kmp_dyna_lock_t *
lck,
2724 __kmp_acquire_hle_lock(
lck, gtid);
2727static int __kmp_release_hle_lock(kmp_dyna_lock_t *
lck,
kmp_int32 gtid) {
2728 __asm__
volatile(HLE_RELEASE
"movl %1,%0"
2735static int __kmp_release_hle_lock_with_checks(kmp_dyna_lock_t *
lck,
2737 return __kmp_release_hle_lock(
lck, gtid);
2740static int __kmp_test_hle_lock(kmp_dyna_lock_t *
lck,
kmp_int32 gtid) {
2744static int __kmp_test_hle_lock_with_checks(kmp_dyna_lock_t *
lck,
2746 return __kmp_test_hle_lock(
lck, gtid);
2765 unsigned retries = 3,
status;
2768 if (
status == _XBEGIN_STARTED) {
2769 if (__kmp_is_unlocked_queuing_lock(
lck))
2773 if ((
status & _XABORT_EXPLICIT) && _XABORT_CODE(
status) == 0xff) {
2775 while (!__kmp_is_unlocked_queuing_lock(
lck)) {
2778 }
else if (!(
status & _XABORT_RETRY))
2780 }
while (retries--);
2788 __kmp_acquire_rtm_queuing_lock(
lck, gtid);
2794 if (__kmp_is_unlocked_queuing_lock(
lck)) {
2806 return __kmp_release_rtm_queuing_lock(
lck, gtid);
2812 unsigned retries = 3,
status;
2815 if (
status == _XBEGIN_STARTED && __kmp_is_unlocked_queuing_lock(
lck)) {
2818 if (!(
status & _XABORT_RETRY))
2820 }
while (retries--);
2827 return __kmp_test_rtm_queuing_lock(
lck, gtid);
2833static void __kmp_destroy_rtm_spin_lock(kmp_rtm_spin_lock_t *
lck) {
2837static void __kmp_destroy_rtm_spin_lock_with_checks(kmp_rtm_spin_lock_t *
lck) {
2838 __kmp_destroy_rtm_spin_lock(
lck);
2842static int __kmp_acquire_rtm_spin_lock(kmp_rtm_spin_lock_t *
lck,
2844 unsigned retries = 3,
status;
2849 if (
status == _XBEGIN_STARTED) {
2854 if ((
status & _XABORT_EXPLICIT) && _XABORT_CODE(
status) == 0xff) {
2859 }
else if (!(
status & _XABORT_RETRY))
2861 }
while (retries--);
2874static int __kmp_acquire_rtm_spin_lock_with_checks(kmp_rtm_spin_lock_t *
lck,
2876 return __kmp_acquire_rtm_spin_lock(
lck, gtid);
2880static int __kmp_release_rtm_spin_lock(kmp_rtm_spin_lock_t *
lck,
2893static int __kmp_release_rtm_spin_lock_with_checks(kmp_rtm_spin_lock_t *
lck,
2895 return __kmp_release_rtm_spin_lock(
lck, gtid);
2899static int __kmp_test_rtm_spin_lock(kmp_rtm_spin_lock_t *
lck,
kmp_int32 gtid) {
2900 unsigned retries = 3,
status;
2905 if (
status == _XBEGIN_STARTED &&
2909 if (!(
status & _XABORT_RETRY))
2911 }
while (retries--);
2921static int __kmp_test_rtm_spin_lock_with_checks(kmp_rtm_spin_lock_t *
lck,
2923 return __kmp_test_rtm_spin_lock(
lck, gtid);
2929static void __kmp_init_indirect_lock(kmp_dyna_lock_t *l,
2930 kmp_dyna_lockseq_t tag);
2931static void __kmp_destroy_indirect_lock(kmp_dyna_lock_t *
lock);
2932static int __kmp_set_indirect_lock(kmp_dyna_lock_t *
lock,
kmp_int32);
2933static int __kmp_unset_indirect_lock(kmp_dyna_lock_t *
lock,
kmp_int32);
2934static int __kmp_test_indirect_lock(kmp_dyna_lock_t *
lock,
kmp_int32);
2935static int __kmp_set_indirect_lock_with_checks(kmp_dyna_lock_t *
lock,
2937static int __kmp_unset_indirect_lock_with_checks(kmp_dyna_lock_t *
lock,
2939static int __kmp_test_indirect_lock_with_checks(kmp_dyna_lock_t *
lock,
2943#define KMP_FOREACH_LOCK_KIND(m, a) m(ticket, a) m(queuing, a) m(drdpa, a)
2945#define expand1(lk, op) \
2946 static void __kmp_##op##_##lk##_##lock(kmp_user_lock_p lock) { \
2947 __kmp_##op##_##lk##_##lock(&lock->lk); \
2949#define expand2(lk, op) \
2950 static int __kmp_##op##_##lk##_##lock(kmp_user_lock_p lock, \
2952 return __kmp_##op##_##lk##_##lock(&lock->lk, gtid); \
2954#define expand3(lk, op) \
2955 static void __kmp_set_##lk##_##lock_flags(kmp_user_lock_p lock, \
2956 kmp_lock_flags_t flags) { \
2957 __kmp_set_##lk##_lock_flags(&lock->lk, flags); \
2959#define expand4(lk, op) \
2960 static void __kmp_set_##lk##_##lock_location(kmp_user_lock_p lock, \
2961 const ident_t *loc) { \
2962 __kmp_set_##lk##_lock_location(&lock->lk, loc); \
2965KMP_FOREACH_LOCK_KIND(expand1,
init)
2966KMP_FOREACH_LOCK_KIND(expand1, init_nested)
2967KMP_FOREACH_LOCK_KIND(expand1, destroy)
2968KMP_FOREACH_LOCK_KIND(expand1, destroy_nested)
2969KMP_FOREACH_LOCK_KIND(expand2, acquire)
2970KMP_FOREACH_LOCK_KIND(expand2, acquire_nested)
2971KMP_FOREACH_LOCK_KIND(expand2,
release)
2972KMP_FOREACH_LOCK_KIND(expand2, release_nested)
2973KMP_FOREACH_LOCK_KIND(expand2,
test)
2974KMP_FOREACH_LOCK_KIND(expand2, test_nested)
2975KMP_FOREACH_LOCK_KIND(expand3, )
2976KMP_FOREACH_LOCK_KIND(expand4, )
2987#define expand(l, op) 0, __kmp_init_direct_lock,
2988void (*__kmp_direct_init[])(kmp_dyna_lock_t *, kmp_dyna_lockseq_t) = {
2989 __kmp_init_indirect_lock, 0, KMP_FOREACH_D_LOCK(expand,
init)};
2993#define expand(l, op) 0, (void (*)(kmp_dyna_lock_t *))__kmp_##op##_##l##_lock,
2994static void (*direct_destroy[])(kmp_dyna_lock_t *) = {
2995 __kmp_destroy_indirect_lock, 0, KMP_FOREACH_D_LOCK(expand, destroy)};
2997#define expand(l, op) \
2998 0, (void (*)(kmp_dyna_lock_t *))__kmp_destroy_##l##_lock_with_checks,
2999static void (*direct_destroy_check[])(kmp_dyna_lock_t *) = {
3000 __kmp_destroy_indirect_lock, 0, KMP_FOREACH_D_LOCK(expand, destroy)};
3004#define expand(l, op) \
3005 0, (int (*)(kmp_dyna_lock_t *, kmp_int32))__kmp_##op##_##l##_lock,
3006static int (*direct_set[])(kmp_dyna_lock_t *,
kmp_int32) = {
3007 __kmp_set_indirect_lock, 0, KMP_FOREACH_D_LOCK(expand, acquire)};
3009#define expand(l, op) \
3010 0, (int (*)(kmp_dyna_lock_t *, kmp_int32))__kmp_##op##_##l##_lock_with_checks,
3011static int (*direct_set_check[])(kmp_dyna_lock_t *,
kmp_int32) = {
3012 __kmp_set_indirect_lock_with_checks, 0,
3013 KMP_FOREACH_D_LOCK(expand, acquire)};
3017#define expand(l, op) \
3018 0, (int (*)(kmp_dyna_lock_t *, kmp_int32))__kmp_##op##_##l##_lock,
3019static int (*direct_unset[])(kmp_dyna_lock_t *,
kmp_int32) = {
3020 __kmp_unset_indirect_lock, 0, KMP_FOREACH_D_LOCK(expand,
release)};
3021static int (*direct_test[])(kmp_dyna_lock_t *,
kmp_int32) = {
3022 __kmp_test_indirect_lock, 0, KMP_FOREACH_D_LOCK(expand,
test)};
3024#define expand(l, op) \
3025 0, (int (*)(kmp_dyna_lock_t *, kmp_int32))__kmp_##op##_##l##_lock_with_checks,
3026static int (*direct_unset_check[])(kmp_dyna_lock_t *,
kmp_int32) = {
3027 __kmp_unset_indirect_lock_with_checks, 0,
3028 KMP_FOREACH_D_LOCK(expand,
release)};
3029static int (*direct_test_check[])(kmp_dyna_lock_t *,
kmp_int32) = {
3030 __kmp_test_indirect_lock_with_checks, 0, KMP_FOREACH_D_LOCK(expand,
test)};
3034void (**__kmp_direct_destroy)(kmp_dyna_lock_t *) = 0;
3035int (**__kmp_direct_set)(kmp_dyna_lock_t *,
kmp_int32) = 0;
3036int (**__kmp_direct_unset)(kmp_dyna_lock_t *,
kmp_int32) = 0;
3037int (**__kmp_direct_test)(kmp_dyna_lock_t *,
kmp_int32) = 0;
3040#define expand(l, op) (void (*)(kmp_user_lock_p)) __kmp_##op##_##l##_##lock,
3042 KMP_FOREACH_I_LOCK(expand,
init)};
3045#define expand(l, op) (void (*)(kmp_user_lock_p)) __kmp_##op##_##l##_##lock,
3047 KMP_FOREACH_I_LOCK(expand, destroy)};
3049#define expand(l, op) \
3050 (void (*)(kmp_user_lock_p)) __kmp_##op##_##l##_##lock_with_checks,
3052 KMP_FOREACH_I_LOCK(expand, destroy)};
3056#define expand(l, op) \
3057 (int (*)(kmp_user_lock_p, kmp_int32)) __kmp_##op##_##l##_##lock,
3059 kmp_int32) = {KMP_FOREACH_I_LOCK(expand, acquire)};
3061#define expand(l, op) \
3062 (int (*)(kmp_user_lock_p, kmp_int32)) __kmp_##op##_##l##_##lock_with_checks,
3064 KMP_FOREACH_I_LOCK(expand, acquire)};
3068#define expand(l, op) \
3069 (int (*)(kmp_user_lock_p, kmp_int32)) __kmp_##op##_##l##_##lock,
3071 KMP_FOREACH_I_LOCK(expand,
release)};
3075#define expand(l, op) \
3076 (int (*)(kmp_user_lock_p, kmp_int32)) __kmp_##op##_##l##_##lock_with_checks,
3078 KMP_FOREACH_I_LOCK(expand,
release)};
3080 KMP_FOREACH_I_LOCK(expand,
test)};
3090kmp_indirect_lock_table_t __kmp_i_lock_table;
3093static kmp_uint32 __kmp_indirect_lock_size[KMP_NUM_I_LOCKS] = {0};
3100const ident_t *(*__kmp_indirect_get_location[KMP_NUM_I_LOCKS])(
3106static kmp_indirect_lock_t *__kmp_indirect_lock_pool[KMP_NUM_I_LOCKS] = {0};
3113kmp_indirect_lock_t *__kmp_allocate_indirect_lock(
void **user_lock,
3115 kmp_indirect_locktag_t tag) {
3116 kmp_indirect_lock_t *
lck;
3121 if (__kmp_indirect_lock_pool[tag] != NULL) {
3123 lck = __kmp_indirect_lock_pool[tag];
3125 idx =
lck->lock->pool.index;
3126 __kmp_indirect_lock_pool[tag] = (kmp_indirect_lock_t *)
lck->lock->pool.next;
3127 KA_TRACE(20, (
"__kmp_allocate_indirect_lock: reusing an existing lock %p\n",
3131 kmp_indirect_lock_table_t *lock_table = &__kmp_i_lock_table;
3135 table_idx = lock_table->next;
3136 idx += lock_table->next;
3137 if (table_idx < lock_table->nrow_ptrs * KMP_I_LOCK_CHUNK) {
3138 row = table_idx / KMP_I_LOCK_CHUNK;
3139 col = table_idx % KMP_I_LOCK_CHUNK;
3141 if (!lock_table->table[row]) {
3143 sizeof(kmp_indirect_lock_t) * KMP_I_LOCK_CHUNK);
3148 if (!lock_table->next_table) {
3149 kmp_indirect_lock_table_t *next_table =
3151 sizeof(kmp_indirect_lock_table_t));
3153 sizeof(kmp_indirect_lock_t *) * 2 * lock_table->nrow_ptrs);
3154 next_table->nrow_ptrs = 2 * lock_table->nrow_ptrs;
3155 next_table->next = 0;
3156 next_table->next_table =
nullptr;
3157 lock_table->next_table = next_table;
3159 lock_table = lock_table->next_table;
3164 lck = &lock_table->table[row][col];
3168 (
"__kmp_allocate_indirect_lock: allocated a new lock %p\n",
lck));
3179 *((kmp_indirect_lock_t **)user_lock) =
lck;
3186static __forceinline kmp_indirect_lock_t *
3187__kmp_lookup_indirect_lock(
void **user_lock,
const char *
func) {
3189 kmp_indirect_lock_t *
lck = NULL;
3190 if (user_lock == NULL) {
3195 lck = __kmp_get_i_lock(idx);
3197 lck = *((kmp_indirect_lock_t **)user_lock);
3205 return __kmp_get_i_lock(KMP_EXTRACT_I_INDEX(user_lock));
3207 return *((kmp_indirect_lock_t **)user_lock);
3212static void __kmp_init_indirect_lock(kmp_dyna_lock_t *
lock,
3213 kmp_dyna_lockseq_t seq) {
3214#if KMP_USE_ADAPTIVE_LOCKS
3215 if (seq == lockseq_adaptive && !__kmp_cpuinfo.flags.rtm) {
3216 KMP_WARNING(AdaptiveNotSupported,
"kmp_lockseq_t",
"adaptive");
3217 seq = lockseq_queuing;
3221 if (seq == lockseq_rtm_queuing && !__kmp_cpuinfo.flags.rtm) {
3222 seq = lockseq_queuing;
3225 kmp_indirect_locktag_t tag = KMP_GET_I_TAG(seq);
3226 kmp_indirect_lock_t *l =
3228 KMP_I_LOCK_FUNC(l,
init)(l->lock);
3230 20, (
"__kmp_init_indirect_lock: initialized indirect lock with type#%d\n",
3234static void __kmp_destroy_indirect_lock(kmp_dyna_lock_t *
lock) {
3236 kmp_indirect_lock_t *l =
3237 __kmp_lookup_indirect_lock((
void **)
lock,
"omp_destroy_lock");
3240 KMP_I_LOCK_FUNC(l, destroy)(l->lock);
3241 kmp_indirect_locktag_t tag = l->type;
3248 l->lock->pool.index = KMP_EXTRACT_I_INDEX(
lock);
3250 __kmp_indirect_lock_pool[tag] = l;
3255static int __kmp_set_indirect_lock(kmp_dyna_lock_t *
lock,
kmp_int32 gtid) {
3256 kmp_indirect_lock_t *l = KMP_LOOKUP_I_LOCK(
lock);
3257 return KMP_I_LOCK_FUNC(l, set)(l->lock, gtid);
3260static int __kmp_unset_indirect_lock(kmp_dyna_lock_t *
lock,
kmp_int32 gtid) {
3261 kmp_indirect_lock_t *l = KMP_LOOKUP_I_LOCK(
lock);
3262 return KMP_I_LOCK_FUNC(l, unset)(l->lock, gtid);
3265static int __kmp_test_indirect_lock(kmp_dyna_lock_t *
lock,
kmp_int32 gtid) {
3266 kmp_indirect_lock_t *l = KMP_LOOKUP_I_LOCK(
lock);
3267 return KMP_I_LOCK_FUNC(l,
test)(l->lock, gtid);
3270static int __kmp_set_indirect_lock_with_checks(kmp_dyna_lock_t *
lock,
3272 kmp_indirect_lock_t *l =
3273 __kmp_lookup_indirect_lock((
void **)
lock,
"omp_set_lock");
3274 return KMP_I_LOCK_FUNC(l, set)(l->lock, gtid);
3277static int __kmp_unset_indirect_lock_with_checks(kmp_dyna_lock_t *
lock,
3279 kmp_indirect_lock_t *l =
3280 __kmp_lookup_indirect_lock((
void **)
lock,
"omp_unset_lock");
3281 return KMP_I_LOCK_FUNC(l, unset)(l->lock, gtid);
3284static int __kmp_test_indirect_lock_with_checks(kmp_dyna_lock_t *
lock,
3286 kmp_indirect_lock_t *l =
3287 __kmp_lookup_indirect_lock((
void **)
lock,
"omp_test_lock");
3288 return KMP_I_LOCK_FUNC(l,
test)(l->lock, gtid);
3291kmp_dyna_lockseq_t __kmp_user_lock_seq = lockseq_queuing;
3297 case lockseq_nested_tas:
3301 case lockseq_nested_futex:
3302 return __kmp_get_futex_lock_owner((kmp_futex_lock_t *)
lck);
3304 case lockseq_ticket:
3305 case lockseq_nested_ticket:
3307 case lockseq_queuing:
3308 case lockseq_nested_queuing:
3309#if KMP_USE_ADAPTIVE_LOCKS
3310 case lockseq_adaptive:
3314 case lockseq_nested_drdpa:
3322void __kmp_init_dynamic_user_locks() {
3325 __kmp_direct_set = direct_set_check;
3326 __kmp_direct_unset = direct_unset_check;
3327 __kmp_direct_test = direct_test_check;
3328 __kmp_direct_destroy = direct_destroy_check;
3329 __kmp_indirect_set = indirect_set_check;
3330 __kmp_indirect_unset = indirect_unset_check;
3331 __kmp_indirect_test = indirect_test_check;
3332 __kmp_indirect_destroy = indirect_destroy_check;
3334 __kmp_direct_set = direct_set;
3335 __kmp_direct_unset = direct_unset;
3336 __kmp_direct_test = direct_test;
3337 __kmp_direct_destroy = direct_destroy;
3338 __kmp_indirect_set = indirect_set;
3339 __kmp_indirect_unset = indirect_unset;
3340 __kmp_indirect_test = indirect_test;
3341 __kmp_indirect_destroy = indirect_destroy;
3350 __kmp_i_lock_table.nrow_ptrs = KMP_I_LOCK_TABLE_INIT_NROW_PTRS;
3351 __kmp_i_lock_table.table = (kmp_indirect_lock_t **)
__kmp_allocate(
3352 sizeof(kmp_indirect_lock_t *) * KMP_I_LOCK_TABLE_INIT_NROW_PTRS);
3353 *(__kmp_i_lock_table.table) = (kmp_indirect_lock_t *)
__kmp_allocate(
3354 KMP_I_LOCK_CHUNK *
sizeof(kmp_indirect_lock_t));
3355 __kmp_i_lock_table.next = 0;
3356 __kmp_i_lock_table.next_table =
nullptr;
3361#if KMP_USE_ADAPTIVE_LOCKS
3362 __kmp_indirect_lock_size[locktag_adaptive] =
sizeof(kmp_adaptive_lock_t);
3368 __kmp_indirect_lock_size[locktag_nested_tas] =
sizeof(
kmp_tas_lock_t);
3370 __kmp_indirect_lock_size[locktag_nested_futex] =
sizeof(kmp_futex_lock_t);
3377#define fill_jumps(table, expand, sep) \
3379 table[locktag##sep##ticket] = expand(ticket); \
3380 table[locktag##sep##queuing] = expand(queuing); \
3381 table[locktag##sep##drdpa] = expand(drdpa); \
3384#if KMP_USE_ADAPTIVE_LOCKS
3385#define fill_table(table, expand) \
3387 fill_jumps(table, expand, _); \
3388 table[locktag_adaptive] = expand(queuing); \
3389 fill_jumps(table, expand, _nested_); \
3392#define fill_table(table, expand) \
3394 fill_jumps(table, expand, _); \
3395 fill_jumps(table, expand, _nested_); \
3400 (void (*)(kmp_user_lock_p, const ident_t *)) __kmp_set_##l##_lock_location
3401 fill_table(__kmp_indirect_set_location, expand);
3404 (void (*)(kmp_user_lock_p, kmp_lock_flags_t)) __kmp_set_##l##_lock_flags
3405 fill_table(__kmp_indirect_set_flags, expand);
3408 (const ident_t *(*)(kmp_user_lock_p)) __kmp_get_##l##_lock_location
3409 fill_table(__kmp_indirect_get_location, expand);
3412 (kmp_lock_flags_t(*)(kmp_user_lock_p)) __kmp_get_##l##_lock_flags
3413 fill_table(__kmp_indirect_get_flags, expand);
3420void __kmp_cleanup_indirect_user_locks() {
3425 for (k = 0; k < KMP_NUM_I_LOCKS; ++k) {
3426 kmp_indirect_lock_t *l = __kmp_indirect_lock_pool[k];
3428 kmp_indirect_lock_t *ll = l;
3429 l = (kmp_indirect_lock_t *)l->lock->pool.next;
3430 KA_TRACE(20, (
"__kmp_cleanup_indirect_user_locks: freeing %p from pool\n",
3435 __kmp_indirect_lock_pool[k] = NULL;
3438 kmp_indirect_lock_table_t *ptr = &__kmp_i_lock_table;
3440 for (
kmp_uint32 row = 0; row < ptr->nrow_ptrs; ++row) {
3441 if (!ptr->table[row])
3443 for (
kmp_uint32 col = 0; col < KMP_I_LOCK_CHUNK; ++col) {
3444 kmp_indirect_lock_t *l = &ptr->table[row][col];
3447 KMP_I_LOCK_FUNC(l, destroy)(l->lock);
3448 KA_TRACE(20, (
"__kmp_cleanup_indirect_user_locks: destroy/freeing %p "
3457 kmp_indirect_lock_table_t *next_table = ptr->next_table;
3458 if (ptr != &__kmp_i_lock_table)
3480static void __kmp_init_futex_lock_with_checks(kmp_futex_lock_t *
lck) {
3481 __kmp_init_futex_lock(
lck);
3484static void __kmp_init_nested_futex_lock_with_checks(kmp_futex_lock_t *
lck) {
3485 __kmp_init_nested_futex_lock(
lck);
3490 return lck ==
lck->lk.self;
3502 return lck ==
lck->lk.initialized;
3514#if KMP_USE_ADAPTIVE_LOCKS
3515static void __kmp_init_adaptive_lock_with_checks(kmp_adaptive_lock_t *
lck) {
3516 __kmp_init_adaptive_lock(
lck);
3521 return lck ==
lck->lk.initialized;
3571 switch (user_lock_kind) {
3710#if KMP_USE_ADAPTIVE_LOCKS
3824 static int last_index = 0;
3837 new_block->
locks = (
void *)buffer;
3906 lck->pool.index = index;
3916 if (user_lock == NULL) {
3949#define IS_CRITICAL(lck) \
3950 ((__kmp_get_user_lock_flags_ != NULL) && \
3951 ((*__kmp_get_user_lock_flags_)(lck)&kmp_lf_critical_section))
3991 (
loc->psource != NULL)) {
4001 (
"__kmp_cleanup_user_locks: free critical section lock %p (%p)\n",
4004 KA_TRACE(20, (
"__kmp_cleanup_user_locks: free lock %p (%p)\n",
lck,
4026 while (table_ptr != NULL) {
4038 while (block_ptr != NULL) {
This class safely opens and closes a C-style FILE* object using RAII semantics.
void set_stdout()
Set the FILE* object to stdout and output there No open call should happen before this call.
void open(const char *filename, const char *mode, const char *env_var=nullptr)
Open filename using mode.
void const char const char int ITT_FORMAT __itt_group_sync s
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int mask
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
void const char const char int ITT_FORMAT __itt_group_sync p
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id head
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id tail
volatile int __kmp_init_user_locks
#define KMP_PACK_64(HIGH_32, LOW_32)
#define KMP_YIELD_OVERSUB_ELSE_SPIN(count, time)
kmp_lock_t __kmp_global_lock
#define __kmp_entry_gtid()
kmp_info_t ** __kmp_threads
#define KMP_YIELD_OVERSUB()
#define KMP_INIT_YIELD(count)
#define KMP_INIT_BACKOFF(time)
#define __kmp_allocate(size)
int __kmp_env_consistency_check
static kmp_info_t * __kmp_thread_from_gtid(int gtid)
union KMP_ALIGN_CACHE kmp_info kmp_info_t
KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86<<, 2i, 1, KMP_ARCH_X86) ATOMIC_CMPXCHG(fixed2, shr, kmp_int16, 16, > KMP_ARCH_X86 KMP_ARCH_X86 kmp_uint32
#define KMP_DEBUG_ASSERT(cond)
#define KMP_ASSERT2(cond, msg)
unsigned long long kmp_uint64
static volatile kmp_i18n_cat_status_t status
static kmp_bootstrap_lock_t lock
void __kmp_printf(char const *format,...)
void __kmp_printf_no_lock(char const *format,...)
#define KMP_FSYNC_PREPARE(obj)
#define KMP_FSYNC_RELEASING(obj)
#define KMP_FSYNC_ACQUIRED(obj)
kmp_backoff_t __kmp_spin_backoff_params
size_t __kmp_base_user_lock_size
static void __kmp_destroy_nested_tas_lock_with_checks(kmp_tas_lock_t *lck)
static int __kmp_test_nested_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
void __kmp_init_queuing_lock(kmp_queuing_lock_t *lck)
static void __kmp_init_nested_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck)
static bool __kmp_is_tas_lock_nestable(kmp_tas_lock_t *lck)
enum kmp_lock_kind __kmp_user_lock_kind
int __kmp_acquire_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid)
kmp_user_lock_p __kmp_user_lock_allocate(void **user_lock, kmp_int32 gtid, kmp_lock_flags_t flags)
static int __kmp_is_queuing_lock_initialized(kmp_queuing_lock_t *lck)
size_t __kmp_user_lock_size
int __kmp_acquire_nested_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid)
int(* __kmp_acquire_nested_user_lock_with_checks_)(kmp_user_lock_p lck, kmp_int32 gtid)
static const ident_t * __kmp_get_drdpa_lock_location(kmp_drdpa_lock_t *lck)
static void __kmp_set_drdpa_lock_location(kmp_drdpa_lock_t *lck, const ident_t *loc)
void __kmp_destroy_ticket_lock(kmp_ticket_lock_t *lck)
static __forceinline int __kmp_acquire_queuing_lock_timed_template(kmp_queuing_lock_t *lck, kmp_int32 gtid)
static void __kmp_set_queuing_lock_flags(kmp_queuing_lock_t *lck, kmp_lock_flags_t flags)
static void __kmp_init_nested_queuing_lock_with_checks(kmp_queuing_lock_t *lck)
void __kmp_init_nested_tas_lock(kmp_tas_lock_t *lck)
int __kmp_acquire_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
void(* __kmp_set_user_lock_location_)(kmp_user_lock_p lck, const ident_t *loc)
static void __kmp_init_nested_ticket_lock_with_checks(kmp_ticket_lock_t *lck)
int(* __kmp_release_nested_user_lock_with_checks_)(kmp_user_lock_p lck, kmp_int32 gtid)
int __kmp_release_nested_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid)
static int __kmp_is_ticket_lock_initialized(kmp_ticket_lock_t *lck)
int __kmp_release_nested_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid)
int __kmp_test_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
void __kmp_init_nested_drdpa_lock(kmp_drdpa_lock_t *lck)
int(* __kmp_test_nested_user_lock_with_checks_)(kmp_user_lock_p lck, kmp_int32 gtid)
void __kmp_destroy_nested_drdpa_lock(kmp_drdpa_lock_t *lck)
void __kmp_set_user_lock_vptrs(kmp_lock_kind_t user_lock_kind)
kmp_int32(* __kmp_get_user_lock_owner_)(kmp_user_lock_p lck)
static kmp_int32 __kmp_get_drdpa_lock_owner(kmp_drdpa_lock_t *lck)
static kmp_int32 __kmp_get_ticket_lock_owner(kmp_ticket_lock_t *lck)
kmp_block_of_locks * __kmp_lock_blocks
static int __kmp_test_nested_queuing_lock_with_checks(kmp_queuing_lock_t *lck, kmp_int32 gtid)
int __kmp_release_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid)
void __kmp_destroy_tas_lock(kmp_tas_lock_t *lck)
kmp_uint64 __kmp_now_nsec()
static kmp_lock_flags_t __kmp_get_drdpa_lock_flags(kmp_drdpa_lock_t *lck)
void __kmp_init_nested_ticket_lock(kmp_ticket_lock_t *lck)
static bool __kmp_is_queuing_lock_nestable(kmp_queuing_lock_t *lck)
static int __kmp_acquire_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
static void __kmp_init_ticket_lock_with_checks(kmp_ticket_lock_t *lck)
static void __kmp_destroy_nested_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck)
int __kmp_acquire_nested_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
static int __kmp_release_queuing_lock_with_checks(kmp_queuing_lock_t *lck, kmp_int32 gtid)
int(* __kmp_is_user_lock_initialized_)(kmp_user_lock_p lck)
int __kmp_test_nested_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static void __kmp_init_queuing_lock_with_checks(kmp_queuing_lock_t *lck)
static kmp_int32 __kmp_get_queuing_lock_owner(kmp_queuing_lock_t *lck)
void(* __kmp_destroy_user_lock_with_checks_)(kmp_user_lock_p lck)
static int __kmp_acquire_nested_ticket_lock_with_checks(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static const ident_t * __kmp_get_ticket_lock_location(kmp_ticket_lock_t *lck)
void __kmp_init_tas_lock(kmp_tas_lock_t *lck)
static void __kmp_set_queuing_lock_location(kmp_queuing_lock_t *lck, const ident_t *loc)
static int __kmp_acquire_nested_queuing_lock_with_checks(kmp_queuing_lock_t *lck, kmp_int32 gtid)
int __kmp_release_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid)
int(* __kmp_acquire_user_lock_with_checks_)(kmp_user_lock_p lck, kmp_int32 gtid)
kmp_lock_table_t __kmp_user_lock_table
static void __kmp_init_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck)
void(* __kmp_init_nested_user_lock_with_checks_)(kmp_user_lock_p lck)
void(* __kmp_init_user_lock_with_checks_)(kmp_user_lock_p lck)
int __kmp_test_nested_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid)
static void __kmp_destroy_nested_ticket_lock_with_checks(kmp_ticket_lock_t *lck)
static int __kmp_test_nested_ticket_lock_with_checks(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_release_nested_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
void __kmp_init_ticket_lock(kmp_ticket_lock_t *lck)
int __kmp_num_locks_in_block
static const ident_t * __kmp_get_queuing_lock_location(kmp_queuing_lock_t *lck)
static kmp_uint32 __kmp_bakery_check(void *now_serving, kmp_uint32 my_ticket)
int __kmp_release_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
int __kmp_test_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid)
void __kmp_user_lock_free(void **user_lock, kmp_int32 gtid, kmp_user_lock_p lck)
static __forceinline int __kmp_acquire_drdpa_lock_timed_template(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
static void __kmp_destroy_queuing_lock_with_checks(kmp_queuing_lock_t *lck)
static int __kmp_test_tas_lock_with_checks(kmp_tas_lock_t *lck, kmp_int32 gtid)
static void __kmp_destroy_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck)
static __forceinline int __kmp_acquire_tas_lock_timed_template(kmp_tas_lock_t *lck, kmp_int32 gtid)
static int __kmp_acquire_ticket_lock_with_checks(kmp_ticket_lock_t *lck, kmp_int32 gtid)
void __kmp_init_nested_queuing_lock(kmp_queuing_lock_t *lck)
int(* __kmp_test_user_lock_with_checks_)(kmp_user_lock_p lck, kmp_int32 gtid)
static void __kmp_init_tas_lock_with_checks(kmp_tas_lock_t *lck)
const ident_t *(* __kmp_get_user_lock_location_)(kmp_user_lock_p lck)
static void __kmp_init_nested_tas_lock_with_checks(kmp_tas_lock_t *lck)
int __kmp_release_nested_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
static bool __kmp_is_ticket_lock_nestable(kmp_ticket_lock_t *lck)
static kmp_user_lock_p __kmp_lock_block_allocate()
static void __kmp_set_drdpa_lock_flags(kmp_drdpa_lock_t *lck, kmp_lock_flags_t flags)
int __kmp_acquire_nested_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid)
kmp_user_lock_p __kmp_lookup_user_lock(void **user_lock, char const *func)
int __kmp_test_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static void __kmp_set_ticket_lock_flags(kmp_ticket_lock_t *lck, kmp_lock_flags_t flags)
static bool before(kmp_uint64 a, kmp_uint64 b)
void(* __kmp_destroy_nested_user_lock_with_checks_)(kmp_user_lock_p lck)
kmp_user_lock_p __kmp_lock_pool
int __kmp_acquire_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_release_nested_ticket_lock_with_checks(kmp_ticket_lock_t *lck, kmp_int32 gtid)
int(* __kmp_release_user_lock_with_checks_)(kmp_user_lock_p lck, kmp_int32 gtid)
static void __kmp_destroy_ticket_lock_with_checks(kmp_ticket_lock_t *lck)
static void __kmp_destroy_tas_lock_with_checks(kmp_tas_lock_t *lck)
void __kmp_destroy_drdpa_lock(kmp_drdpa_lock_t *lck)
void __kmp_destroy_nested_tas_lock(kmp_tas_lock_t *lck)
void __kmp_cleanup_user_locks(void)
void(* __kmp_destroy_user_lock_)(kmp_user_lock_p lck)
static int __kmp_test_nested_tas_lock_with_checks(kmp_tas_lock_t *lck, kmp_int32 gtid)
void __kmp_destroy_nested_queuing_lock(kmp_queuing_lock_t *lck)
static int __kmp_test_ticket_lock_with_checks(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_test_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
int __kmp_test_nested_drdpa_lock(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
void __kmp_init_drdpa_lock(kmp_drdpa_lock_t *lck)
void __kmp_spin_backoff(kmp_backoff_t *boff)
void __kmp_destroy_queuing_lock(kmp_queuing_lock_t *lck)
void __kmp_validate_locks(void)
int __kmp_acquire_queuing_lock(kmp_queuing_lock_t *lck, kmp_int32 gtid)
static int __kmp_acquire_nested_tas_lock_with_checks(kmp_tas_lock_t *lck, kmp_int32 gtid)
int __kmp_release_nested_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid)
int __kmp_acquire_nested_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_release_ticket_lock_with_checks(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_acquire_tas_lock_with_checks(kmp_tas_lock_t *lck, kmp_int32 gtid)
static int __kmp_acquire_queuing_lock_with_checks(kmp_queuing_lock_t *lck, kmp_int32 gtid)
static int __kmp_release_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
int __kmp_test_nested_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid)
kmp_lock_flags_t(* __kmp_get_user_lock_flags_)(kmp_user_lock_p lck)
static bool __kmp_is_drdpa_lock_nestable(kmp_drdpa_lock_t *lck)
static kmp_lock_index_t __kmp_lock_table_insert(kmp_user_lock_p lck)
static void __kmp_set_ticket_lock_location(kmp_ticket_lock_t *lck, const ident_t *loc)
static int __kmp_release_nested_tas_lock_with_checks(kmp_tas_lock_t *lck, kmp_int32 gtid)
static kmp_lock_flags_t __kmp_get_queuing_lock_flags(kmp_queuing_lock_t *lck)
static int __kmp_release_tas_lock_with_checks(kmp_tas_lock_t *lck, kmp_int32 gtid)
static __forceinline int __kmp_acquire_ticket_lock_timed_template(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_release_nested_queuing_lock_with_checks(kmp_queuing_lock_t *lck, kmp_int32 gtid)
static void __kmp_acquire_nested_drdpa_lock_with_checks(kmp_drdpa_lock_t *lck, kmp_int32 gtid)
static void __kmp_destroy_nested_queuing_lock_with_checks(kmp_queuing_lock_t *lck)
static kmp_lock_flags_t __kmp_get_ticket_lock_flags(kmp_ticket_lock_t *lck)
static kmp_int32 __kmp_get_tas_lock_owner(kmp_tas_lock_t *lck)
int __kmp_test_tas_lock(kmp_tas_lock_t *lck, kmp_int32 gtid)
int __kmp_release_ticket_lock(kmp_ticket_lock_t *lck, kmp_int32 gtid)
static int __kmp_is_drdpa_lock_initialized(kmp_drdpa_lock_t *lck)
static int __kmp_test_queuing_lock_with_checks(kmp_queuing_lock_t *lck, kmp_int32 gtid)
void(* __kmp_set_user_lock_flags_)(kmp_user_lock_p lck, kmp_lock_flags_t flags)
void __kmp_destroy_nested_ticket_lock(kmp_ticket_lock_t *lck)
static void __kmp_release_bootstrap_lock(kmp_bootstrap_lock_t *lck)
struct kmp_base_tas_lock kmp_base_tas_lock_t
#define KMP_BIND_NESTED_USER_LOCK(kind)
static int __kmp_acquire_lock(kmp_lock_t *lck, kmp_int32 gtid)
enum kmp_lock_kind kmp_lock_kind_t
union kmp_user_lock * kmp_user_lock_p
struct kmp_block_of_locks kmp_block_of_locks_t
kmp_ticket_lock_t kmp_bootstrap_lock_t
union kmp_ticket_lock kmp_ticket_lock_t
static void __kmp_destroy_user_lock(kmp_user_lock_p lck)
#define KMP_LOCK_RELEASED
static int __kmp_acquire_bootstrap_lock(kmp_bootstrap_lock_t *lck)
#define KMP_LOCK_FREE(type)
#define KMP_LOCK_STRIP(v)
struct kmp_base_drdpa_lock kmp_base_drdpa_lock_t
#define KMP_BIND_NESTED_USER_LOCK_WITH_CHECKS(kind)
#define KMP_LOCK_ACQUIRED_NEXT
#define KMP_BIND_USER_LOCK_WITH_CHECKS(kind)
kmp_uint32 kmp_lock_flags_t
union kmp_drdpa_lock kmp_drdpa_lock_t
static void __kmp_release_lock(kmp_lock_t *lck, kmp_int32 gtid)
kmp_uint32 kmp_lock_index_t
#define KMP_LOCK_ACQUIRED_FIRST
struct kmp_base_queuing_lock kmp_base_queuing_lock_t
struct kmp_lock_table kmp_lock_table_t
#define KMP_BIND_USER_LOCK(kind)
static kmp_int32 __kmp_get_user_lock_owner(kmp_user_lock_p lck)
static void __kmp_init_bootstrap_lock(kmp_bootstrap_lock_t *lck)
union kmp_tas_lock kmp_tas_lock_t
static void __kmp_set_user_lock_flags(kmp_user_lock_p lck, kmp_lock_flags_t flags)
#define KMP_LOCK_STILL_HELD
#define KMP_LOCK_BUSY(v, type)
#define KMP_BOOTSTRAP_LOCK_INITIALIZER(lock)
struct kmp_base_ticket_lock kmp_base_ticket_lock_t
union kmp_queuing_lock kmp_queuing_lock_t
static const ident_t * __kmp_get_user_lock_location(kmp_user_lock_p lck)
#define KMP_XCHG_FIXED32(p, v)
#define KMP_COMPARE_AND_STORE_REL64(p, cv, sv)
#define KMP_COMPARE_AND_STORE_REL32(p, cv, sv)
#define KMP_ATOMIC_ST_REL(p, v)
#define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv)
#define KMP_COMPARE_AND_STORE_RET32(p, cv, sv)
bool __kmp_atomic_compare_store_acq(std::atomic< T > *p, T expected, T desired)
#define KMP_ATOMIC_LD_RLX(p)
#define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv)
#define KMP_ATTRIBUTE_TARGET_RTM
#define KMP_ATOMIC_INC(p)
kmp_str_loc_t __kmp_str_loc_init(char const *psource, bool init_fname)
void __kmp_str_loc_free(kmp_str_loc_t *loc)
struct kmp_str_loc kmp_str_loc_t
void init(int &A, int val)
ompt_callbacks_active_t ompt_enabled
The ident structure that describes a source location.
struct kmp_block_of_locks * next_block