16 #include "kmp_error.h"
20 #include "kmp_stats.h"
21 #include "ompt-specific.h"
23 #define MAX_MESSAGE 512
39 if ((env = getenv(
"KMP_INITIAL_THREAD_BIND")) != NULL &&
40 __kmp_str_match_true(env)) {
41 __kmp_middle_initialize();
42 __kmp_assign_root_init_mask();
43 KC_TRACE(10, (
"__kmpc_begin: middle initialization called\n"));
44 }
else if (__kmp_ignore_mppbeg() == FALSE) {
46 __kmp_internal_begin();
47 KC_TRACE(10, (
"__kmpc_begin: called\n"));
65 if (__kmp_ignore_mppend() == FALSE) {
66 KC_TRACE(10, (
"__kmpc_end: called\n"));
67 KA_TRACE(30, (
"__kmpc_end\n"));
69 __kmp_internal_end_thread(-1);
71 #if KMP_OS_WINDOWS && OMPT_SUPPORT
76 if (ompt_enabled.enabled)
77 __kmp_internal_end_library(__kmp_gtid_get_specific());
100 kmp_int32 gtid = __kmp_entry_gtid();
102 KC_TRACE(10, (
"__kmpc_global_thread_num: T#%d\n", gtid));
123 (
"__kmpc_global_num_threads: num_threads = %d\n", __kmp_all_nth));
125 return TCR_4(__kmp_all_nth);
135 KC_TRACE(10, (
"__kmpc_bound_thread_num: called\n"));
136 return __kmp_tid_from_gtid(__kmp_entry_gtid());
145 KC_TRACE(10, (
"__kmpc_bound_num_threads: called\n"));
147 return __kmp_entry_thread()->th.th_team->t.t_nproc;
167 if (__kmp_par_range == 0) {
174 semi2 = strchr(semi2,
';');
178 semi2 = strchr(semi2 + 1,
';');
182 if (__kmp_par_range_filename[0]) {
183 const char *name = semi2 - 1;
184 while ((name > loc->
psource) && (*name !=
'/') && (*name !=
';')) {
187 if ((*name ==
'/') || (*name ==
';')) {
190 if (strncmp(__kmp_par_range_filename, name, semi2 - name)) {
191 return __kmp_par_range < 0;
194 semi3 = strchr(semi2 + 1,
';');
195 if (__kmp_par_range_routine[0]) {
196 if ((semi3 != NULL) && (semi3 > semi2) &&
197 (strncmp(__kmp_par_range_routine, semi2 + 1, semi3 - semi2 - 1))) {
198 return __kmp_par_range < 0;
201 if (KMP_SSCANF(semi3 + 1,
"%d", &line_no) == 1) {
202 if ((line_no >= __kmp_par_range_lb) && (line_no <= __kmp_par_range_ub)) {
203 return __kmp_par_range > 0;
205 return __kmp_par_range < 0;
219 return __kmp_entry_thread()->th.th_root->r.r_active;
232 kmp_int32 num_threads) {
233 KA_TRACE(20, (
"__kmpc_push_num_threads: enter T#%d num_threads=%d\n",
234 global_tid, num_threads));
235 __kmp_assert_valid_gtid(global_tid);
236 __kmp_push_num_threads(loc, global_tid, num_threads);
239 void __kmpc_pop_num_threads(
ident_t *loc, kmp_int32 global_tid) {
240 KA_TRACE(20, (
"__kmpc_pop_num_threads: enter\n"));
244 void __kmpc_push_proc_bind(
ident_t *loc, kmp_int32 global_tid,
245 kmp_int32 proc_bind) {
246 KA_TRACE(20, (
"__kmpc_push_proc_bind: enter T#%d proc_bind=%d\n", global_tid,
248 __kmp_assert_valid_gtid(global_tid);
249 __kmp_push_proc_bind(loc, global_tid, (kmp_proc_bind_t)proc_bind);
263 int gtid = __kmp_entry_gtid();
265 #if (KMP_STATS_ENABLED)
269 if (previous_state == stats_state_e::SERIAL_REGION) {
270 KMP_EXCHANGE_PARTITIONED_TIMER(OMP_parallel_overhead);
272 KMP_PUSH_PARTITIONED_TIMER(OMP_parallel_overhead);
285 va_start(ap, microtask);
288 ompt_frame_t *ompt_frame;
289 if (ompt_enabled.enabled) {
290 kmp_info_t *master_th = __kmp_threads[gtid];
291 kmp_team_t *parent_team = master_th->th.th_team;
292 ompt_lw_taskteam_t *lwt = parent_team->t.ompt_serialized_team_info;
294 ompt_frame = &(lwt->ompt_task_info.frame);
296 int tid = __kmp_tid_from_gtid(gtid);
298 parent_team->t.t_implicit_task_taskdata[tid].ompt_task_info.frame);
300 ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
302 OMPT_STORE_RETURN_ADDRESS(gtid);
305 #if INCLUDE_SSC_MARKS
308 __kmp_fork_call(loc, gtid, fork_context_intel, argc,
309 VOLATILE_CAST(microtask_t) microtask,
310 VOLATILE_CAST(launch_t) __kmp_invoke_task_func,
312 #if INCLUDE_SSC_MARKS
315 __kmp_join_call(loc, gtid
325 #if KMP_STATS_ENABLED
326 if (previous_state == stats_state_e::SERIAL_REGION) {
327 KMP_EXCHANGE_PARTITIONED_TIMER(OMP_serial);
328 KMP_SET_THREAD_STATE(previous_state);
330 KMP_POP_PARTITIONED_TIMER();
347 kmp_int32 num_teams, kmp_int32 num_threads) {
349 (
"__kmpc_push_num_teams: enter T#%d num_teams=%d num_threads=%d\n",
350 global_tid, num_teams, num_threads));
351 __kmp_assert_valid_gtid(global_tid);
352 __kmp_push_num_teams(loc, global_tid, num_teams, num_threads);
372 kmp_int32 num_teams_lb, kmp_int32 num_teams_ub,
373 kmp_int32 num_threads) {
374 KA_TRACE(20, (
"__kmpc_push_num_teams_51: enter T#%d num_teams_lb=%d"
375 " num_teams_ub=%d num_threads=%d\n",
376 global_tid, num_teams_lb, num_teams_ub, num_threads));
377 __kmp_assert_valid_gtid(global_tid);
378 __kmp_push_num_teams_51(loc, global_tid, num_teams_lb, num_teams_ub,
394 int gtid = __kmp_entry_gtid();
395 kmp_info_t *this_thr = __kmp_threads[gtid];
397 va_start(ap, microtask);
399 #if KMP_STATS_ENABLED
402 if (previous_state == stats_state_e::SERIAL_REGION) {
403 KMP_EXCHANGE_PARTITIONED_TIMER(OMP_teams_overhead);
405 KMP_PUSH_PARTITIONED_TIMER(OMP_teams_overhead);
410 this_thr->th.th_teams_microtask = microtask;
411 this_thr->th.th_teams_level =
412 this_thr->th.th_team->t.t_level;
415 kmp_team_t *parent_team = this_thr->th.th_team;
416 int tid = __kmp_tid_from_gtid(gtid);
417 if (ompt_enabled.enabled) {
418 parent_team->t.t_implicit_task_taskdata[tid]
419 .ompt_task_info.frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
421 OMPT_STORE_RETURN_ADDRESS(gtid);
426 if (this_thr->th.th_teams_size.nteams == 0) {
427 __kmp_push_num_teams(loc, gtid, 0, 0);
429 KMP_DEBUG_ASSERT(this_thr->th.th_set_nproc >= 1);
430 KMP_DEBUG_ASSERT(this_thr->th.th_teams_size.nteams >= 1);
431 KMP_DEBUG_ASSERT(this_thr->th.th_teams_size.nth >= 1);
434 loc, gtid, fork_context_intel, argc,
435 VOLATILE_CAST(microtask_t) __kmp_teams_master,
436 VOLATILE_CAST(launch_t) __kmp_invoke_teams_master, kmp_va_addr_of(ap));
437 __kmp_join_call(loc, gtid
445 KMP_DEBUG_ASSERT(this_thr->th.th_cg_roots);
446 kmp_cg_root_t *tmp = this_thr->th.th_cg_roots;
447 this_thr->th.th_cg_roots = tmp->up;
448 KA_TRACE(100, (
"__kmpc_fork_teams: Thread %p popping node %p and moving up"
449 " to node %p. cg_nthreads was %d\n",
450 this_thr, tmp, this_thr->th.th_cg_roots, tmp->cg_nthreads));
451 KMP_DEBUG_ASSERT(tmp->cg_nthreads);
452 int i = tmp->cg_nthreads--;
457 KMP_DEBUG_ASSERT(this_thr->th.th_cg_roots);
458 this_thr->th.th_current_task->td_icvs.thread_limit =
459 this_thr->th.th_cg_roots->cg_thread_limit;
461 this_thr->th.th_teams_microtask = NULL;
462 this_thr->th.th_teams_level = 0;
463 *(kmp_int64 *)(&this_thr->th.th_teams_size) = 0L;
465 #if KMP_STATS_ENABLED
466 if (previous_state == stats_state_e::SERIAL_REGION) {
467 KMP_EXCHANGE_PARTITIONED_TIMER(OMP_serial);
468 KMP_SET_THREAD_STATE(previous_state);
470 KMP_POP_PARTITIONED_TIMER();
479 int __kmpc_invoke_task_func(
int gtid) {
return __kmp_invoke_task_func(gtid); }
497 __kmp_assert_valid_gtid(global_tid);
499 OMPT_STORE_RETURN_ADDRESS(global_tid);
501 __kmp_serialized_parallel(loc, global_tid);
512 kmp_internal_control_t *top;
513 kmp_info_t *this_thr;
514 kmp_team_t *serial_team;
517 (
"__kmpc_end_serialized_parallel: called by T#%d\n", global_tid));
525 __kmp_assert_valid_gtid(global_tid);
526 if (!TCR_4(__kmp_init_parallel))
527 __kmp_parallel_initialize();
529 __kmp_resume_if_soft_paused();
531 this_thr = __kmp_threads[global_tid];
532 serial_team = this_thr->th.th_serial_team;
534 kmp_task_team_t *task_team = this_thr->th.th_task_team;
536 if (task_team != NULL && task_team->tt.tt_found_proxy_tasks)
537 __kmp_task_team_wait(this_thr, serial_team USE_ITT_BUILD_ARG(NULL));
540 KMP_DEBUG_ASSERT(serial_team);
541 KMP_ASSERT(serial_team->t.t_serialized);
542 KMP_DEBUG_ASSERT(this_thr->th.th_team == serial_team);
543 KMP_DEBUG_ASSERT(serial_team != this_thr->th.th_root->r.r_root_team);
544 KMP_DEBUG_ASSERT(serial_team->t.t_threads);
545 KMP_DEBUG_ASSERT(serial_team->t.t_threads[0] == this_thr);
548 if (ompt_enabled.enabled &&
549 this_thr->th.ompt_thread_info.state != ompt_state_overhead) {
550 OMPT_CUR_TASK_INFO(this_thr)->frame.exit_frame = ompt_data_none;
551 if (ompt_enabled.ompt_callback_implicit_task) {
552 ompt_callbacks.ompt_callback(ompt_callback_implicit_task)(
553 ompt_scope_end, NULL, OMPT_CUR_TASK_DATA(this_thr), 1,
554 OMPT_CUR_TASK_INFO(this_thr)->thread_num, ompt_task_implicit);
558 ompt_data_t *parent_task_data;
559 __ompt_get_task_info_internal(1, NULL, &parent_task_data, NULL, NULL, NULL);
561 if (ompt_enabled.ompt_callback_parallel_end) {
562 ompt_callbacks.ompt_callback(ompt_callback_parallel_end)(
563 &(serial_team->t.ompt_team_info.parallel_data), parent_task_data,
564 ompt_parallel_invoker_program | ompt_parallel_team,
565 OMPT_LOAD_RETURN_ADDRESS(global_tid));
567 __ompt_lw_taskteam_unlink(this_thr);
568 this_thr->th.ompt_thread_info.state = ompt_state_overhead;
574 top = serial_team->t.t_control_stack_top;
575 if (top && top->serial_nesting_level == serial_team->t.t_serialized) {
576 copy_icvs(&serial_team->t.t_threads[0]->th.th_current_task->td_icvs, top);
577 serial_team->t.t_control_stack_top = top->next;
582 serial_team->t.t_level--;
585 KMP_DEBUG_ASSERT(serial_team->t.t_dispatch->th_disp_buffer);
587 dispatch_private_info_t *disp_buffer =
588 serial_team->t.t_dispatch->th_disp_buffer;
589 serial_team->t.t_dispatch->th_disp_buffer =
590 serial_team->t.t_dispatch->th_disp_buffer->next;
591 __kmp_free(disp_buffer);
593 this_thr->th.th_def_allocator = serial_team->t.t_def_allocator;
595 --serial_team->t.t_serialized;
596 if (serial_team->t.t_serialized == 0) {
600 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
601 if (__kmp_inherit_fp_control && serial_team->t.t_fp_control_saved) {
602 __kmp_clear_x87_fpu_status_word();
603 __kmp_load_x87_fpu_control_word(&serial_team->t.t_x87_fpu_control_word);
604 __kmp_load_mxcsr(&serial_team->t.t_mxcsr);
609 if (ompd_state & OMPD_ENABLE_BP)
610 ompd_bp_parallel_end();
613 this_thr->th.th_team = serial_team->t.t_parent;
614 this_thr->th.th_info.ds.ds_tid = serial_team->t.t_master_tid;
617 this_thr->th.th_team_nproc = serial_team->t.t_parent->t.t_nproc;
618 this_thr->th.th_team_master =
619 serial_team->t.t_parent->t.t_threads[0];
620 this_thr->th.th_team_serialized = this_thr->th.th_team->t.t_serialized;
623 this_thr->th.th_dispatch =
624 &this_thr->th.th_team->t.t_dispatch[serial_team->t.t_master_tid];
626 __kmp_pop_current_task_from_thread(this_thr);
628 KMP_ASSERT(this_thr->th.th_current_task->td_flags.executing == 0);
629 this_thr->th.th_current_task->td_flags.executing = 1;
631 if (__kmp_tasking_mode != tskm_immediate_exec) {
633 this_thr->th.th_task_team =
634 this_thr->th.th_team->t.t_task_team[this_thr->th.th_task_state];
636 (
"__kmpc_end_serialized_parallel: T#%d restoring task_team %p / "
638 global_tid, this_thr->th.th_task_team, this_thr->th.th_team));
641 if (__kmp_tasking_mode != tskm_immediate_exec) {
642 KA_TRACE(20, (
"__kmpc_end_serialized_parallel: T#%d decreasing nesting "
643 "depth of serial team %p to %d\n",
644 global_tid, serial_team, serial_team->t.t_serialized));
648 if (__kmp_env_consistency_check)
649 __kmp_pop_parallel(global_tid, NULL);
651 if (ompt_enabled.enabled)
652 this_thr->th.ompt_thread_info.state =
653 ((this_thr->th.th_team_serialized) ? ompt_state_work_serial
654 : ompt_state_work_parallel);
667 KC_TRACE(10, (
"__kmpc_flush: called\n"));
672 #if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
686 if (!__kmp_cpuinfo.initialized) {
687 __kmp_query_cpuid(&__kmp_cpuinfo);
689 if (!__kmp_cpuinfo.sse2) {
694 #elif KMP_COMPILER_MSVC
697 __sync_synchronize();
701 #elif (KMP_ARCH_ARM || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS || KMP_ARCH_MIPS64 || \
707 #error Unknown or unsupported architecture
710 #if OMPT_SUPPORT && OMPT_OPTIONAL
711 if (ompt_enabled.ompt_callback_flush) {
712 ompt_callbacks.ompt_callback(ompt_callback_flush)(
713 __ompt_get_thread_data_internal(), OMPT_GET_RETURN_ADDRESS(0));
728 KC_TRACE(10, (
"__kmpc_barrier: called T#%d\n", global_tid));
729 __kmp_assert_valid_gtid(global_tid);
731 if (!TCR_4(__kmp_init_parallel))
732 __kmp_parallel_initialize();
734 __kmp_resume_if_soft_paused();
736 if (__kmp_env_consistency_check) {
738 KMP_WARNING(ConstructIdentInvalid);
740 __kmp_check_barrier(global_tid, ct_barrier, loc);
744 ompt_frame_t *ompt_frame;
745 if (ompt_enabled.enabled) {
746 __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
747 if (ompt_frame->enter_frame.ptr == NULL)
748 ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
750 OMPT_STORE_RETURN_ADDRESS(global_tid);
752 __kmp_threads[global_tid]->th.th_ident = loc;
760 __kmp_barrier(bs_plain_barrier, global_tid, FALSE, 0, NULL, NULL);
761 #if OMPT_SUPPORT && OMPT_OPTIONAL
762 if (ompt_enabled.enabled) {
763 ompt_frame->enter_frame = ompt_data_none;
778 KC_TRACE(10, (
"__kmpc_master: called T#%d\n", global_tid));
779 __kmp_assert_valid_gtid(global_tid);
781 if (!TCR_4(__kmp_init_parallel))
782 __kmp_parallel_initialize();
784 __kmp_resume_if_soft_paused();
786 if (KMP_MASTER_GTID(global_tid)) {
788 KMP_PUSH_PARTITIONED_TIMER(OMP_master);
792 #if OMPT_SUPPORT && OMPT_OPTIONAL
794 if (ompt_enabled.ompt_callback_masked) {
795 kmp_info_t *this_thr = __kmp_threads[global_tid];
796 kmp_team_t *team = this_thr->th.th_team;
798 int tid = __kmp_tid_from_gtid(global_tid);
799 ompt_callbacks.ompt_callback(ompt_callback_masked)(
800 ompt_scope_begin, &(team->t.ompt_team_info.parallel_data),
801 &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
802 OMPT_GET_RETURN_ADDRESS(0));
807 if (__kmp_env_consistency_check) {
808 #if KMP_USE_DYNAMIC_LOCK
810 __kmp_push_sync(global_tid, ct_master, loc, NULL, 0);
812 __kmp_check_sync(global_tid, ct_master, loc, NULL, 0);
815 __kmp_push_sync(global_tid, ct_master, loc, NULL);
817 __kmp_check_sync(global_tid, ct_master, loc, NULL);
833 KC_TRACE(10, (
"__kmpc_end_master: called T#%d\n", global_tid));
834 __kmp_assert_valid_gtid(global_tid);
835 KMP_DEBUG_ASSERT(KMP_MASTER_GTID(global_tid));
836 KMP_POP_PARTITIONED_TIMER();
838 #if OMPT_SUPPORT && OMPT_OPTIONAL
839 kmp_info_t *this_thr = __kmp_threads[global_tid];
840 kmp_team_t *team = this_thr->th.th_team;
841 if (ompt_enabled.ompt_callback_masked) {
842 int tid = __kmp_tid_from_gtid(global_tid);
843 ompt_callbacks.ompt_callback(ompt_callback_masked)(
844 ompt_scope_end, &(team->t.ompt_team_info.parallel_data),
845 &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
846 OMPT_GET_RETURN_ADDRESS(0));
850 if (__kmp_env_consistency_check) {
851 if (KMP_MASTER_GTID(global_tid))
852 __kmp_pop_sync(global_tid, ct_master, loc);
867 KC_TRACE(10, (
"__kmpc_masked: called T#%d\n", global_tid));
868 __kmp_assert_valid_gtid(global_tid);
870 if (!TCR_4(__kmp_init_parallel))
871 __kmp_parallel_initialize();
873 __kmp_resume_if_soft_paused();
875 tid = __kmp_tid_from_gtid(global_tid);
878 KMP_PUSH_PARTITIONED_TIMER(OMP_masked);
882 #if OMPT_SUPPORT && OMPT_OPTIONAL
884 if (ompt_enabled.ompt_callback_masked) {
885 kmp_info_t *this_thr = __kmp_threads[global_tid];
886 kmp_team_t *team = this_thr->th.th_team;
887 ompt_callbacks.ompt_callback(ompt_callback_masked)(
888 ompt_scope_begin, &(team->t.ompt_team_info.parallel_data),
889 &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
890 OMPT_GET_RETURN_ADDRESS(0));
895 if (__kmp_env_consistency_check) {
896 #if KMP_USE_DYNAMIC_LOCK
898 __kmp_push_sync(global_tid, ct_masked, loc, NULL, 0);
900 __kmp_check_sync(global_tid, ct_masked, loc, NULL, 0);
903 __kmp_push_sync(global_tid, ct_masked, loc, NULL);
905 __kmp_check_sync(global_tid, ct_masked, loc, NULL);
921 KC_TRACE(10, (
"__kmpc_end_masked: called T#%d\n", global_tid));
922 __kmp_assert_valid_gtid(global_tid);
923 KMP_POP_PARTITIONED_TIMER();
925 #if OMPT_SUPPORT && OMPT_OPTIONAL
926 kmp_info_t *this_thr = __kmp_threads[global_tid];
927 kmp_team_t *team = this_thr->th.th_team;
928 if (ompt_enabled.ompt_callback_masked) {
929 int tid = __kmp_tid_from_gtid(global_tid);
930 ompt_callbacks.ompt_callback(ompt_callback_masked)(
931 ompt_scope_end, &(team->t.ompt_team_info.parallel_data),
932 &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
933 OMPT_GET_RETURN_ADDRESS(0));
937 if (__kmp_env_consistency_check) {
938 __kmp_pop_sync(global_tid, ct_masked, loc);
952 KMP_DEBUG_ASSERT(__kmp_init_serial);
954 KC_TRACE(10, (
"__kmpc_ordered: called T#%d\n", gtid));
955 __kmp_assert_valid_gtid(gtid);
957 if (!TCR_4(__kmp_init_parallel))
958 __kmp_parallel_initialize();
960 __kmp_resume_if_soft_paused();
963 __kmp_itt_ordered_prep(gtid);
967 th = __kmp_threads[gtid];
969 #if OMPT_SUPPORT && OMPT_OPTIONAL
973 OMPT_STORE_RETURN_ADDRESS(gtid);
974 if (ompt_enabled.enabled) {
975 team = __kmp_team_from_gtid(gtid);
976 lck = (ompt_wait_id_t)(uintptr_t)&team->t.t_ordered.dt.t_value;
978 th->th.ompt_thread_info.wait_id = lck;
979 th->th.ompt_thread_info.state = ompt_state_wait_ordered;
982 codeptr_ra = OMPT_LOAD_RETURN_ADDRESS(gtid);
983 if (ompt_enabled.ompt_callback_mutex_acquire) {
984 ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)(
985 ompt_mutex_ordered, omp_lock_hint_none, kmp_mutex_impl_spin, lck,
991 if (th->th.th_dispatch->th_deo_fcn != 0)
992 (*th->th.th_dispatch->th_deo_fcn)(>id, &cid, loc);
994 __kmp_parallel_deo(>id, &cid, loc);
996 #if OMPT_SUPPORT && OMPT_OPTIONAL
997 if (ompt_enabled.enabled) {
999 th->th.ompt_thread_info.state = ompt_state_work_parallel;
1000 th->th.ompt_thread_info.wait_id = 0;
1003 if (ompt_enabled.ompt_callback_mutex_acquired) {
1004 ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)(
1005 ompt_mutex_ordered, (ompt_wait_id_t)(uintptr_t)lck, codeptr_ra);
1011 __kmp_itt_ordered_start(gtid);
1026 KC_TRACE(10, (
"__kmpc_end_ordered: called T#%d\n", gtid));
1027 __kmp_assert_valid_gtid(gtid);
1030 __kmp_itt_ordered_end(gtid);
1034 th = __kmp_threads[gtid];
1036 if (th->th.th_dispatch->th_dxo_fcn != 0)
1037 (*th->th.th_dispatch->th_dxo_fcn)(>id, &cid, loc);
1039 __kmp_parallel_dxo(>id, &cid, loc);
1041 #if OMPT_SUPPORT && OMPT_OPTIONAL
1042 OMPT_STORE_RETURN_ADDRESS(gtid);
1043 if (ompt_enabled.ompt_callback_mutex_released) {
1044 ompt_callbacks.ompt_callback(ompt_callback_mutex_released)(
1046 (ompt_wait_id_t)(uintptr_t)&__kmp_team_from_gtid(gtid)
1047 ->t.t_ordered.dt.t_value,
1048 OMPT_LOAD_RETURN_ADDRESS(gtid));
1053 #if KMP_USE_DYNAMIC_LOCK
1055 static __forceinline
void
1056 __kmp_init_indirect_csptr(kmp_critical_name *crit,
ident_t const *loc,
1057 kmp_int32 gtid, kmp_indirect_locktag_t tag) {
1061 kmp_indirect_lock_t **lck;
1062 lck = (kmp_indirect_lock_t **)crit;
1063 kmp_indirect_lock_t *ilk = __kmp_allocate_indirect_lock(&idx, gtid, tag);
1064 KMP_I_LOCK_FUNC(ilk, init)(ilk->lock);
1065 KMP_SET_I_LOCK_LOCATION(ilk, loc);
1066 KMP_SET_I_LOCK_FLAGS(ilk, kmp_lf_critical_section);
1068 (
"__kmp_init_indirect_csptr: initialized indirect lock #%d\n", tag));
1070 __kmp_itt_critical_creating(ilk->lock, loc);
1072 int status = KMP_COMPARE_AND_STORE_PTR(lck,
nullptr, ilk);
1075 __kmp_itt_critical_destroyed(ilk->lock);
1081 KMP_DEBUG_ASSERT(*lck != NULL);
1085 #define KMP_ACQUIRE_TAS_LOCK(lock, gtid) \
1087 kmp_tas_lock_t *l = (kmp_tas_lock_t *)lock; \
1088 kmp_int32 tas_free = KMP_LOCK_FREE(tas); \
1089 kmp_int32 tas_busy = KMP_LOCK_BUSY(gtid + 1, tas); \
1090 if (KMP_ATOMIC_LD_RLX(&l->lk.poll) != tas_free || \
1091 !__kmp_atomic_compare_store_acq(&l->lk.poll, tas_free, tas_busy)) { \
1093 KMP_FSYNC_PREPARE(l); \
1094 KMP_INIT_YIELD(spins); \
1095 kmp_backoff_t backoff = __kmp_spin_backoff_params; \
1097 if (TCR_4(__kmp_nth) > \
1098 (__kmp_avail_proc ? __kmp_avail_proc : __kmp_xproc)) { \
1101 KMP_YIELD_SPIN(spins); \
1103 __kmp_spin_backoff(&backoff); \
1105 KMP_ATOMIC_LD_RLX(&l->lk.poll) != tas_free || \
1106 !__kmp_atomic_compare_store_acq(&l->lk.poll, tas_free, tas_busy)); \
1108 KMP_FSYNC_ACQUIRED(l); \
1112 #define KMP_TEST_TAS_LOCK(lock, gtid, rc) \
1114 kmp_tas_lock_t *l = (kmp_tas_lock_t *)lock; \
1115 kmp_int32 tas_free = KMP_LOCK_FREE(tas); \
1116 kmp_int32 tas_busy = KMP_LOCK_BUSY(gtid + 1, tas); \
1117 rc = KMP_ATOMIC_LD_RLX(&l->lk.poll) == tas_free && \
1118 __kmp_atomic_compare_store_acq(&l->lk.poll, tas_free, tas_busy); \
1122 #define KMP_RELEASE_TAS_LOCK(lock, gtid) \
1123 { KMP_ATOMIC_ST_REL(&((kmp_tas_lock_t *)lock)->lk.poll, KMP_LOCK_FREE(tas)); }
1127 #include <sys/syscall.h>
1130 #define FUTEX_WAIT 0
1133 #define FUTEX_WAKE 1
1137 #define KMP_ACQUIRE_FUTEX_LOCK(lock, gtid) \
1139 kmp_futex_lock_t *ftx = (kmp_futex_lock_t *)lock; \
1140 kmp_int32 gtid_code = (gtid + 1) << 1; \
1142 KMP_FSYNC_PREPARE(ftx); \
1143 kmp_int32 poll_val; \
1144 while ((poll_val = KMP_COMPARE_AND_STORE_RET32( \
1145 &(ftx->lk.poll), KMP_LOCK_FREE(futex), \
1146 KMP_LOCK_BUSY(gtid_code, futex))) != KMP_LOCK_FREE(futex)) { \
1147 kmp_int32 cond = KMP_LOCK_STRIP(poll_val) & 1; \
1149 if (!KMP_COMPARE_AND_STORE_RET32(&(ftx->lk.poll), poll_val, \
1151 KMP_LOCK_BUSY(1, futex))) { \
1154 poll_val |= KMP_LOCK_BUSY(1, futex); \
1157 if ((rc = syscall(__NR_futex, &(ftx->lk.poll), FUTEX_WAIT, poll_val, \
1158 NULL, NULL, 0)) != 0) { \
1163 KMP_FSYNC_ACQUIRED(ftx); \
1167 #define KMP_TEST_FUTEX_LOCK(lock, gtid, rc) \
1169 kmp_futex_lock_t *ftx = (kmp_futex_lock_t *)lock; \
1170 if (KMP_COMPARE_AND_STORE_ACQ32(&(ftx->lk.poll), KMP_LOCK_FREE(futex), \
1171 KMP_LOCK_BUSY(gtid + 1 << 1, futex))) { \
1172 KMP_FSYNC_ACQUIRED(ftx); \
1180 #define KMP_RELEASE_FUTEX_LOCK(lock, gtid) \
1182 kmp_futex_lock_t *ftx = (kmp_futex_lock_t *)lock; \
1184 KMP_FSYNC_RELEASING(ftx); \
1185 kmp_int32 poll_val = \
1186 KMP_XCHG_FIXED32(&(ftx->lk.poll), KMP_LOCK_FREE(futex)); \
1187 if (KMP_LOCK_STRIP(poll_val) & 1) { \
1188 syscall(__NR_futex, &(ftx->lk.poll), FUTEX_WAKE, \
1189 KMP_LOCK_BUSY(1, futex), NULL, NULL, 0); \
1192 KMP_YIELD_OVERSUB(); \
1199 static kmp_user_lock_p __kmp_get_critical_section_ptr(kmp_critical_name *crit,
1202 kmp_user_lock_p *lck_pp = (kmp_user_lock_p *)crit;
1205 kmp_user_lock_p lck = (kmp_user_lock_p)TCR_PTR(*lck_pp);
1212 lck = __kmp_user_lock_allocate(&idx, gtid, kmp_lf_critical_section);
1213 __kmp_init_user_lock_with_checks(lck);
1214 __kmp_set_user_lock_location(lck, loc);
1216 __kmp_itt_critical_creating(lck);
1227 int status = KMP_COMPARE_AND_STORE_PTR(lck_pp, 0, lck);
1232 __kmp_itt_critical_destroyed(lck);
1236 __kmp_destroy_user_lock_with_checks(lck);
1237 __kmp_user_lock_free(&idx, gtid, lck);
1238 lck = (kmp_user_lock_p)TCR_PTR(*lck_pp);
1239 KMP_DEBUG_ASSERT(lck != NULL);
1258 kmp_critical_name *crit) {
1259 #if KMP_USE_DYNAMIC_LOCK
1260 #if OMPT_SUPPORT && OMPT_OPTIONAL
1261 OMPT_STORE_RETURN_ADDRESS(global_tid);
1266 #if OMPT_SUPPORT && OMPT_OPTIONAL
1267 ompt_state_t prev_state = ompt_state_undefined;
1268 ompt_thread_info_t ti;
1270 kmp_user_lock_p lck;
1272 KC_TRACE(10, (
"__kmpc_critical: called T#%d\n", global_tid));
1273 __kmp_assert_valid_gtid(global_tid);
1277 KMP_PUSH_PARTITIONED_TIMER(OMP_critical_wait);
1278 KMP_CHECK_USER_LOCK_INIT();
1280 if ((__kmp_user_lock_kind == lk_tas) &&
1281 (
sizeof(lck->tas.lk.poll) <= OMP_CRITICAL_SIZE)) {
1282 lck = (kmp_user_lock_p)crit;
1285 else if ((__kmp_user_lock_kind == lk_futex) &&
1286 (
sizeof(lck->futex.lk.poll) <= OMP_CRITICAL_SIZE)) {
1287 lck = (kmp_user_lock_p)crit;
1291 lck = __kmp_get_critical_section_ptr(crit, loc, global_tid);
1294 if (__kmp_env_consistency_check)
1295 __kmp_push_sync(global_tid, ct_critical, loc, lck);
1303 __kmp_itt_critical_acquiring(lck);
1305 #if OMPT_SUPPORT && OMPT_OPTIONAL
1306 OMPT_STORE_RETURN_ADDRESS(gtid);
1307 void *codeptr_ra = NULL;
1308 if (ompt_enabled.enabled) {
1309 ti = __kmp_threads[global_tid]->th.ompt_thread_info;
1311 prev_state = ti.state;
1312 ti.wait_id = (ompt_wait_id_t)(uintptr_t)lck;
1313 ti.state = ompt_state_wait_critical;
1316 codeptr_ra = OMPT_LOAD_RETURN_ADDRESS(gtid);
1317 if (ompt_enabled.ompt_callback_mutex_acquire) {
1318 ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)(
1319 ompt_mutex_critical, omp_lock_hint_none, __ompt_get_mutex_impl_type(),
1320 (ompt_wait_id_t)(uintptr_t)lck, codeptr_ra);
1326 __kmp_acquire_user_lock_with_checks(lck, global_tid);
1329 __kmp_itt_critical_acquired(lck);
1331 #if OMPT_SUPPORT && OMPT_OPTIONAL
1332 if (ompt_enabled.enabled) {
1334 ti.state = prev_state;
1338 if (ompt_enabled.ompt_callback_mutex_acquired) {
1339 ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)(
1340 ompt_mutex_critical, (ompt_wait_id_t)(uintptr_t)lck, codeptr_ra);