17cc577a4SJonathan Peyton /* 2de4749b7SJonathan Peyton * kmp_error.cpp -- KPTS functions for error checking at runtime 37cc577a4SJonathan Peyton */ 47cc577a4SJonathan Peyton 57cc577a4SJonathan Peyton //===----------------------------------------------------------------------===// 67cc577a4SJonathan Peyton // 757b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 857b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 957b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 107cc577a4SJonathan Peyton // 117cc577a4SJonathan Peyton //===----------------------------------------------------------------------===// 127cc577a4SJonathan Peyton 137cc577a4SJonathan Peyton #include "kmp.h" 143041982dSJonathan Peyton #include "kmp_error.h" 157cc577a4SJonathan Peyton #include "kmp_i18n.h" 167cc577a4SJonathan Peyton #include "kmp_str.h" 177cc577a4SJonathan Peyton 187cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */ 197cc577a4SJonathan Peyton 207cc577a4SJonathan Peyton #define MIN_STACK 100 217cc577a4SJonathan Peyton 227cc577a4SJonathan Peyton static char const *cons_text_c[] = { 23*309b00a4SShilei Tian "(none)", 24*309b00a4SShilei Tian "\"parallel\"", 25*309b00a4SShilei Tian "work-sharing", /* this is not called "for" 263041982dSJonathan Peyton because of lowering of 273041982dSJonathan Peyton "sections" pragmas */ 283041982dSJonathan Peyton "\"ordered\" work-sharing", /* this is not called "for ordered" because of 293041982dSJonathan Peyton lowering of "sections" pragmas */ 307cc577a4SJonathan Peyton "\"sections\"", 313041982dSJonathan Peyton "work-sharing", /* this is not called "single" because of lowering of 323041982dSJonathan Peyton "sections" pragmas */ 33*309b00a4SShilei Tian "\"critical\"", 34*309b00a4SShilei Tian "\"ordered\"", /* in PARALLEL */ 357cc577a4SJonathan Peyton "\"ordered\"", /* in PDO */ 36*309b00a4SShilei Tian "\"master\"", 37*309b00a4SShilei Tian "\"reduce\"", 38*309b00a4SShilei Tian "\"barrier\""}; 397cc577a4SJonathan Peyton 407cc577a4SJonathan Peyton #define get_src(ident) ((ident) == NULL ? NULL : (ident)->psource) 417cc577a4SJonathan Peyton 427cc577a4SJonathan Peyton #define PUSH_MSG(ct, ident) \ 437cc577a4SJonathan Peyton "\tpushing on stack: %s (%s)\n", cons_text_c[(ct)], get_src((ident)) 447cc577a4SJonathan Peyton #define POP_MSG(p) \ 453041982dSJonathan Peyton "\tpopping off stack: %s (%s)\n", cons_text_c[(p)->stack_data[tos].type], \ 467cc577a4SJonathan Peyton get_src((p)->stack_data[tos].ident) 477cc577a4SJonathan Peyton 487cc577a4SJonathan Peyton static int const cons_text_c_num = sizeof(cons_text_c) / sizeof(char const *); 497cc577a4SJonathan Peyton 507cc577a4SJonathan Peyton /* --------------- START OF STATIC LOCAL ROUTINES ------------------------- */ 517cc577a4SJonathan Peyton 523041982dSJonathan Peyton static void __kmp_check_null_func(void) { /* nothing to do */ 537cc577a4SJonathan Peyton } 547cc577a4SJonathan Peyton 553041982dSJonathan Peyton static void __kmp_expand_cons_stack(int gtid, struct cons_header *p) { 567cc577a4SJonathan Peyton int i; 577cc577a4SJonathan Peyton struct cons_data *d; 587cc577a4SJonathan Peyton 597cc577a4SJonathan Peyton /* TODO for monitor perhaps? */ 607cc577a4SJonathan Peyton if (gtid < 0) 617cc577a4SJonathan Peyton __kmp_check_null_func(); 627cc577a4SJonathan Peyton 637cc577a4SJonathan Peyton KE_TRACE(10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid())); 647cc577a4SJonathan Peyton 657cc577a4SJonathan Peyton d = p->stack_data; 667cc577a4SJonathan Peyton 677cc577a4SJonathan Peyton p->stack_size = (p->stack_size * 2) + 100; 687cc577a4SJonathan Peyton 697cc577a4SJonathan Peyton /* TODO free the old data */ 703041982dSJonathan Peyton p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) * 713041982dSJonathan Peyton (p->stack_size + 1)); 727cc577a4SJonathan Peyton 737cc577a4SJonathan Peyton for (i = p->stack_top; i >= 0; --i) 747cc577a4SJonathan Peyton p->stack_data[i] = d[i]; 757cc577a4SJonathan Peyton 767cc577a4SJonathan Peyton /* NOTE: we do not free the old stack_data */ 777cc577a4SJonathan Peyton } 787cc577a4SJonathan Peyton 797cc577a4SJonathan Peyton // NOTE: Function returns allocated memory, caller must free it! 80aeb40adaSJonas Hahnfeld static char *__kmp_pragma(int ct, ident_t const *ident) { 817cc577a4SJonathan Peyton char const *cons = NULL; // Construct name. 827cc577a4SJonathan Peyton char *file = NULL; // File name. 837cc577a4SJonathan Peyton char *func = NULL; // Function (routine) name. 847cc577a4SJonathan Peyton char *line = NULL; // Line number. 857cc577a4SJonathan Peyton kmp_str_buf_t buffer; 867cc577a4SJonathan Peyton kmp_msg_t prgm; 877cc577a4SJonathan Peyton __kmp_str_buf_init(&buffer); 887cc577a4SJonathan Peyton if (0 < ct && ct < cons_text_c_num) { 897cc577a4SJonathan Peyton cons = cons_text_c[ct]; 907cc577a4SJonathan Peyton } else { 917cc577a4SJonathan Peyton KMP_DEBUG_ASSERT(0); 92bd3a7633SJonathan Peyton } 937cc577a4SJonathan Peyton if (ident != NULL && ident->psource != NULL) { 947cc577a4SJonathan Peyton char *tail = NULL; 953041982dSJonathan Peyton __kmp_str_buf_print(&buffer, "%s", 963041982dSJonathan Peyton ident->psource); // Copy source to buffer. 977cc577a4SJonathan Peyton // Split string in buffer to file, func, and line. 987cc577a4SJonathan Peyton tail = buffer.str; 997cc577a4SJonathan Peyton __kmp_str_split(tail, ';', NULL, &tail); 1007cc577a4SJonathan Peyton __kmp_str_split(tail, ';', &file, &tail); 1017cc577a4SJonathan Peyton __kmp_str_split(tail, ';', &func, &tail); 1027cc577a4SJonathan Peyton __kmp_str_split(tail, ';', &line, &tail); 103bd3a7633SJonathan Peyton } 1047cc577a4SJonathan Peyton prgm = __kmp_msg_format(kmp_i18n_fmt_Pragma, cons, file, func, line); 1057cc577a4SJonathan Peyton __kmp_str_buf_free(&buffer); 1067cc577a4SJonathan Peyton return prgm.str; 1077cc577a4SJonathan Peyton } // __kmp_pragma 1087cc577a4SJonathan Peyton 1097cc577a4SJonathan Peyton /* ----------------- END OF STATIC LOCAL ROUTINES ------------------------- */ 1107cc577a4SJonathan Peyton 1113041982dSJonathan Peyton void __kmp_error_construct(kmp_i18n_id_t id, // Message identifier. 1127cc577a4SJonathan Peyton enum cons_type ct, // Construct type. 1137cc577a4SJonathan Peyton ident_t const *ident // Construct ident. 1147cc577a4SJonathan Peyton ) { 115aeb40adaSJonas Hahnfeld char *construct = __kmp_pragma(ct, ident); 1166a393f75SJonathan Peyton __kmp_fatal(__kmp_msg_format(id, construct), __kmp_msg_null); 117aeb40adaSJonas Hahnfeld KMP_INTERNAL_FREE(construct); 1187cc577a4SJonathan Peyton } 1197cc577a4SJonathan Peyton 1203041982dSJonathan Peyton void __kmp_error_construct2(kmp_i18n_id_t id, // Message identifier. 1217cc577a4SJonathan Peyton enum cons_type ct, // First construct type. 1227cc577a4SJonathan Peyton ident_t const *ident, // First construct ident. 1237cc577a4SJonathan Peyton struct cons_data const *cons // Second construct. 1247cc577a4SJonathan Peyton ) { 125aeb40adaSJonas Hahnfeld char *construct1 = __kmp_pragma(ct, ident); 126aeb40adaSJonas Hahnfeld char *construct2 = __kmp_pragma(cons->type, cons->ident); 1276a393f75SJonathan Peyton __kmp_fatal(__kmp_msg_format(id, construct1, construct2), __kmp_msg_null); 128aeb40adaSJonas Hahnfeld KMP_INTERNAL_FREE(construct1); 129aeb40adaSJonas Hahnfeld KMP_INTERNAL_FREE(construct2); 1307cc577a4SJonathan Peyton } 1317cc577a4SJonathan Peyton 1323041982dSJonathan Peyton struct cons_header *__kmp_allocate_cons_stack(int gtid) { 1337cc577a4SJonathan Peyton struct cons_header *p; 1347cc577a4SJonathan Peyton 1357cc577a4SJonathan Peyton /* TODO for monitor perhaps? */ 1367cc577a4SJonathan Peyton if (gtid < 0) { 1377cc577a4SJonathan Peyton __kmp_check_null_func(); 138bd3a7633SJonathan Peyton } 1397cc577a4SJonathan Peyton KE_TRACE(10, ("allocate cons_stack (%d)\n", gtid)); 1407cc577a4SJonathan Peyton p = (struct cons_header *)__kmp_allocate(sizeof(struct cons_header)); 1417cc577a4SJonathan Peyton p->p_top = p->w_top = p->s_top = 0; 1423041982dSJonathan Peyton p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) * 1433041982dSJonathan Peyton (MIN_STACK + 1)); 1447cc577a4SJonathan Peyton p->stack_size = MIN_STACK; 1457cc577a4SJonathan Peyton p->stack_top = 0; 1467cc577a4SJonathan Peyton p->stack_data[0].type = ct_none; 1477cc577a4SJonathan Peyton p->stack_data[0].prev = 0; 1487cc577a4SJonathan Peyton p->stack_data[0].ident = NULL; 1497cc577a4SJonathan Peyton return p; 1507cc577a4SJonathan Peyton } 1517cc577a4SJonathan Peyton 1523041982dSJonathan Peyton void __kmp_free_cons_stack(void *ptr) { 1537cc577a4SJonathan Peyton struct cons_header *p = (struct cons_header *)ptr; 1547cc577a4SJonathan Peyton if (p != NULL) { 1557cc577a4SJonathan Peyton if (p->stack_data != NULL) { 1567cc577a4SJonathan Peyton __kmp_free(p->stack_data); 1577cc577a4SJonathan Peyton p->stack_data = NULL; 158bd3a7633SJonathan Peyton } 1597cc577a4SJonathan Peyton __kmp_free(p); 160bd3a7633SJonathan Peyton } 1617cc577a4SJonathan Peyton } 1627cc577a4SJonathan Peyton 1637cc577a4SJonathan Peyton #if KMP_DEBUG 1643041982dSJonathan Peyton static void dump_cons_stack(int gtid, struct cons_header *p) { 1657cc577a4SJonathan Peyton int i; 1667cc577a4SJonathan Peyton int tos = p->stack_top; 1677cc577a4SJonathan Peyton kmp_str_buf_t buffer; 1687cc577a4SJonathan Peyton __kmp_str_buf_init(&buffer); 1693041982dSJonathan Peyton __kmp_str_buf_print( 1703041982dSJonathan Peyton &buffer, 1713041982dSJonathan Peyton "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n"); 1723041982dSJonathan Peyton __kmp_str_buf_print(&buffer, 1733041982dSJonathan Peyton "Begin construct stack with %d items for thread %d\n", 1743041982dSJonathan Peyton tos, gtid); 1753041982dSJonathan Peyton __kmp_str_buf_print(&buffer, " stack_top=%d { P=%d, W=%d, S=%d }\n", tos, 1763041982dSJonathan Peyton p->p_top, p->w_top, p->s_top); 1777cc577a4SJonathan Peyton for (i = tos; i > 0; i--) { 1787cc577a4SJonathan Peyton struct cons_data *c = &(p->stack_data[i]); 1793041982dSJonathan Peyton __kmp_str_buf_print( 1803041982dSJonathan Peyton &buffer, " stack_data[%2d] = { %s (%s) %d %p }\n", i, 1813041982dSJonathan Peyton cons_text_c[c->type], get_src(c->ident), c->prev, c->name); 182bd3a7633SJonathan Peyton } 1837cc577a4SJonathan Peyton __kmp_str_buf_print(&buffer, "End construct stack for thread %d\n", gtid); 1843041982dSJonathan Peyton __kmp_str_buf_print( 1853041982dSJonathan Peyton &buffer, 1863041982dSJonathan Peyton "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n"); 1877cc577a4SJonathan Peyton __kmp_debug_printf("%s", buffer.str); 1887cc577a4SJonathan Peyton __kmp_str_buf_free(&buffer); 1897cc577a4SJonathan Peyton } 1907cc577a4SJonathan Peyton #endif 1917cc577a4SJonathan Peyton 1923041982dSJonathan Peyton void __kmp_push_parallel(int gtid, ident_t const *ident) { 1937cc577a4SJonathan Peyton int tos; 1947cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 1957cc577a4SJonathan Peyton 1967cc577a4SJonathan Peyton KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons); 1977cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid())); 1987cc577a4SJonathan Peyton KE_TRACE(100, (PUSH_MSG(ct_parallel, ident))); 1997cc577a4SJonathan Peyton if (p->stack_top >= p->stack_size) { 2007cc577a4SJonathan Peyton __kmp_expand_cons_stack(gtid, p); 201bd3a7633SJonathan Peyton } 2027cc577a4SJonathan Peyton tos = ++p->stack_top; 2037cc577a4SJonathan Peyton p->stack_data[tos].type = ct_parallel; 2047cc577a4SJonathan Peyton p->stack_data[tos].prev = p->p_top; 2057cc577a4SJonathan Peyton p->stack_data[tos].ident = ident; 2067cc577a4SJonathan Peyton p->stack_data[tos].name = NULL; 2077cc577a4SJonathan Peyton p->p_top = tos; 2087cc577a4SJonathan Peyton KE_DUMP(1000, dump_cons_stack(gtid, p)); 2097cc577a4SJonathan Peyton } 2107cc577a4SJonathan Peyton 2113041982dSJonathan Peyton void __kmp_check_workshare(int gtid, enum cons_type ct, ident_t const *ident) { 2127cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 2137cc577a4SJonathan Peyton 2147cc577a4SJonathan Peyton KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons); 2157cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid())); 2167cc577a4SJonathan Peyton 2177cc577a4SJonathan Peyton if (p->stack_top >= p->stack_size) { 2187cc577a4SJonathan Peyton __kmp_expand_cons_stack(gtid, p); 219bd3a7633SJonathan Peyton } 22044b476c1SJonathan Peyton if (p->w_top > p->p_top) { 2217cc577a4SJonathan Peyton // We are already in a WORKSHARE construct for this PARALLEL region. 2223041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 2233041982dSJonathan Peyton &p->stack_data[p->w_top]); 224bd3a7633SJonathan Peyton } 2257cc577a4SJonathan Peyton if (p->s_top > p->p_top) { 2267cc577a4SJonathan Peyton // We are already in a SYNC construct for this PARALLEL region. 2273041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 2283041982dSJonathan Peyton &p->stack_data[p->s_top]); 229bd3a7633SJonathan Peyton } 2307cc577a4SJonathan Peyton } 2317cc577a4SJonathan Peyton 2323041982dSJonathan Peyton void __kmp_push_workshare(int gtid, enum cons_type ct, ident_t const *ident) { 2337cc577a4SJonathan Peyton int tos; 2347cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 2357cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid())); 2367cc577a4SJonathan Peyton __kmp_check_workshare(gtid, ct, ident); 2377cc577a4SJonathan Peyton KE_TRACE(100, (PUSH_MSG(ct, ident))); 2387cc577a4SJonathan Peyton tos = ++p->stack_top; 2397cc577a4SJonathan Peyton p->stack_data[tos].type = ct; 2407cc577a4SJonathan Peyton p->stack_data[tos].prev = p->w_top; 2417cc577a4SJonathan Peyton p->stack_data[tos].ident = ident; 2427cc577a4SJonathan Peyton p->stack_data[tos].name = NULL; 2437cc577a4SJonathan Peyton p->w_top = tos; 2447cc577a4SJonathan Peyton KE_DUMP(1000, dump_cons_stack(gtid, p)); 2457cc577a4SJonathan Peyton } 2467cc577a4SJonathan Peyton 2477cc577a4SJonathan Peyton void 2487cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK 2497cc577a4SJonathan Peyton __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq ) 2507cc577a4SJonathan Peyton #else 2517cc577a4SJonathan Peyton __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck ) 2527cc577a4SJonathan Peyton #endif 2537cc577a4SJonathan Peyton { 2547cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 2557cc577a4SJonathan Peyton 2567cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid())); 2577cc577a4SJonathan Peyton 2587cc577a4SJonathan Peyton if (p->stack_top >= p->stack_size) 2597cc577a4SJonathan Peyton __kmp_expand_cons_stack(gtid, p); 2607cc577a4SJonathan Peyton 26144b476c1SJonathan Peyton if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo) { 2627cc577a4SJonathan Peyton if (p->w_top <= p->p_top) { 2637cc577a4SJonathan Peyton /* we are not in a worksharing construct */ 2647cc577a4SJonathan Peyton #ifdef BUILD_PARALLEL_ORDERED 2657cc577a4SJonathan Peyton /* do not report error messages for PARALLEL ORDERED */ 2667cc577a4SJonathan Peyton KMP_ASSERT(ct == ct_ordered_in_parallel); 2677cc577a4SJonathan Peyton #else 2687cc577a4SJonathan Peyton __kmp_error_construct(kmp_i18n_msg_CnsBoundToWorksharing, ct, ident); 2697cc577a4SJonathan Peyton #endif /* BUILD_PARALLEL_ORDERED */ 2707cc577a4SJonathan Peyton } else { 2717cc577a4SJonathan Peyton /* inside a WORKSHARING construct for this PARALLEL region */ 2727cc577a4SJonathan Peyton if (!IS_CONS_TYPE_ORDERED(p->stack_data[p->w_top].type)) { 2733041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsNoOrderedClause, ct, ident, 2743041982dSJonathan Peyton &p->stack_data[p->w_top]); 2757cc577a4SJonathan Peyton } 2767cc577a4SJonathan Peyton } 2777cc577a4SJonathan Peyton if (p->s_top > p->p_top && p->s_top > p->w_top) { 2787cc577a4SJonathan Peyton /* inside a sync construct which is inside a worksharing construct */ 2797cc577a4SJonathan Peyton int index = p->s_top; 2807cc577a4SJonathan Peyton enum cons_type stack_type; 2817cc577a4SJonathan Peyton 2827cc577a4SJonathan Peyton stack_type = p->stack_data[index].type; 2837cc577a4SJonathan Peyton 2847cc577a4SJonathan Peyton if (stack_type == ct_critical || 2857cc577a4SJonathan Peyton ((stack_type == ct_ordered_in_parallel || 28644b476c1SJonathan Peyton stack_type == ct_ordered_in_pdo) && 28744b476c1SJonathan Peyton /* C doesn't allow named ordered; ordered in ordered gets error */ 2887cc577a4SJonathan Peyton p->stack_data[index].ident != NULL && 2897cc577a4SJonathan Peyton (p->stack_data[index].ident->flags & KMP_IDENT_KMPC))) { 2907cc577a4SJonathan Peyton /* we are in ORDERED which is inside an ORDERED or CRITICAL construct */ 2913041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 2923041982dSJonathan Peyton &p->stack_data[index]); 2937cc577a4SJonathan Peyton } 2947cc577a4SJonathan Peyton } 2957cc577a4SJonathan Peyton } else if (ct == ct_critical) { 2967cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK 2973041982dSJonathan Peyton if (lck != NULL && 2983041982dSJonathan Peyton __kmp_get_user_lock_owner(lck, seq) == 2993041982dSJonathan Peyton gtid) { /* this thread already has lock for this critical section */ 3007cc577a4SJonathan Peyton #else 3013041982dSJonathan Peyton if (lck != NULL && 3023041982dSJonathan Peyton __kmp_get_user_lock_owner(lck) == 3033041982dSJonathan Peyton gtid) { /* this thread already has lock for this critical section */ 3047cc577a4SJonathan Peyton #endif 3057cc577a4SJonathan Peyton int index = p->s_top; 3067cc577a4SJonathan Peyton struct cons_data cons = {NULL, ct_critical, 0, NULL}; 3077cc577a4SJonathan Peyton /* walk up construct stack and try to find critical with matching name */ 3087cc577a4SJonathan Peyton while (index != 0 && p->stack_data[index].name != lck) { 3097cc577a4SJonathan Peyton index = p->stack_data[index].prev; 3107cc577a4SJonathan Peyton } 3117cc577a4SJonathan Peyton if (index != 0) { 3123041982dSJonathan Peyton /* found match on the stack (may not always because of interleaved 3133041982dSJonathan Peyton * critical for Fortran) */ 3147cc577a4SJonathan Peyton cons = p->stack_data[index]; 3157cc577a4SJonathan Peyton } 3163041982dSJonathan Peyton /* we are in CRITICAL which is inside a CRITICAL construct of same name */ 3177cc577a4SJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsNestingSameName, ct, ident, &cons); 3187cc577a4SJonathan Peyton } 3197cc577a4SJonathan Peyton } else if (ct == ct_master || ct == ct_reduce) { 3207cc577a4SJonathan Peyton if (p->w_top > p->p_top) { 3217cc577a4SJonathan Peyton /* inside a WORKSHARING construct for this PARALLEL region */ 3223041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 3233041982dSJonathan Peyton &p->stack_data[p->w_top]); 3247cc577a4SJonathan Peyton } 3257cc577a4SJonathan Peyton if (ct == ct_reduce && p->s_top > p->p_top) { 3267cc577a4SJonathan Peyton /* inside a another SYNC construct for this PARALLEL region */ 3273041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 3283041982dSJonathan Peyton &p->stack_data[p->s_top]); 329bd3a7633SJonathan Peyton } 330bd3a7633SJonathan Peyton } 3317cc577a4SJonathan Peyton } 3327cc577a4SJonathan Peyton 3337cc577a4SJonathan Peyton void 3347cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK 3357cc577a4SJonathan Peyton __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq ) 3367cc577a4SJonathan Peyton #else 3377cc577a4SJonathan Peyton __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck ) 3387cc577a4SJonathan Peyton #endif 3397cc577a4SJonathan Peyton { 3407cc577a4SJonathan Peyton int tos; 3417cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 3427cc577a4SJonathan Peyton 3437cc577a4SJonathan Peyton KMP_ASSERT(gtid == __kmp_get_gtid()); 3447cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_push_sync (gtid=%d)\n", gtid)); 3457cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK 3467cc577a4SJonathan Peyton __kmp_check_sync(gtid, ct, ident, lck, seq); 3477cc577a4SJonathan Peyton #else 3487cc577a4SJonathan Peyton __kmp_check_sync(gtid, ct, ident, lck); 3497cc577a4SJonathan Peyton #endif 3507cc577a4SJonathan Peyton KE_TRACE(100, (PUSH_MSG(ct, ident))); 3517cc577a4SJonathan Peyton tos = ++p->stack_top; 3527cc577a4SJonathan Peyton p->stack_data[tos].type = ct; 3537cc577a4SJonathan Peyton p->stack_data[tos].prev = p->s_top; 3547cc577a4SJonathan Peyton p->stack_data[tos].ident = ident; 3557cc577a4SJonathan Peyton p->stack_data[tos].name = lck; 3567cc577a4SJonathan Peyton p->s_top = tos; 3577cc577a4SJonathan Peyton KE_DUMP(1000, dump_cons_stack(gtid, p)); 3587cc577a4SJonathan Peyton } 3597cc577a4SJonathan Peyton 3607cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */ 3617cc577a4SJonathan Peyton 3623041982dSJonathan Peyton void __kmp_pop_parallel(int gtid, ident_t const *ident) { 3637cc577a4SJonathan Peyton int tos; 3647cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 3657cc577a4SJonathan Peyton tos = p->stack_top; 3667cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_pop_parallel (%d %d)\n", gtid, __kmp_get_gtid())); 3677cc577a4SJonathan Peyton if (tos == 0 || p->p_top == 0) { 3687cc577a4SJonathan Peyton __kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct_parallel, ident); 3697cc577a4SJonathan Peyton } 3707cc577a4SJonathan Peyton if (tos != p->p_top || p->stack_data[tos].type != ct_parallel) { 3713041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct_parallel, ident, 3723041982dSJonathan Peyton &p->stack_data[tos]); 3737cc577a4SJonathan Peyton } 3747cc577a4SJonathan Peyton KE_TRACE(100, (POP_MSG(p))); 3757cc577a4SJonathan Peyton p->p_top = p->stack_data[tos].prev; 3767cc577a4SJonathan Peyton p->stack_data[tos].type = ct_none; 3777cc577a4SJonathan Peyton p->stack_data[tos].ident = NULL; 3787cc577a4SJonathan Peyton p->stack_top = tos - 1; 3797cc577a4SJonathan Peyton KE_DUMP(1000, dump_cons_stack(gtid, p)); 3807cc577a4SJonathan Peyton } 3817cc577a4SJonathan Peyton 3823041982dSJonathan Peyton enum cons_type __kmp_pop_workshare(int gtid, enum cons_type ct, 3833041982dSJonathan Peyton ident_t const *ident) { 3847cc577a4SJonathan Peyton int tos; 3857cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 3867cc577a4SJonathan Peyton 3877cc577a4SJonathan Peyton tos = p->stack_top; 3887cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid())); 3897cc577a4SJonathan Peyton if (tos == 0 || p->w_top == 0) { 3907cc577a4SJonathan Peyton __kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident); 3917cc577a4SJonathan Peyton } 3927cc577a4SJonathan Peyton 3937cc577a4SJonathan Peyton if (tos != p->w_top || 3947cc577a4SJonathan Peyton (p->stack_data[tos].type != ct && 39544b476c1SJonathan Peyton // below is the exception to the rule that construct types must match 39644b476c1SJonathan Peyton !(p->stack_data[tos].type == ct_pdo_ordered && ct == ct_pdo))) { 3977cc577a4SJonathan Peyton __kmp_check_null_func(); 3983041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident, 3993041982dSJonathan Peyton &p->stack_data[tos]); 4007cc577a4SJonathan Peyton } 4017cc577a4SJonathan Peyton KE_TRACE(100, (POP_MSG(p))); 4027cc577a4SJonathan Peyton p->w_top = p->stack_data[tos].prev; 4037cc577a4SJonathan Peyton p->stack_data[tos].type = ct_none; 4047cc577a4SJonathan Peyton p->stack_data[tos].ident = NULL; 4057cc577a4SJonathan Peyton p->stack_top = tos - 1; 4067cc577a4SJonathan Peyton KE_DUMP(1000, dump_cons_stack(gtid, p)); 4077cc577a4SJonathan Peyton return p->stack_data[p->w_top].type; 4087cc577a4SJonathan Peyton } 4097cc577a4SJonathan Peyton 4103041982dSJonathan Peyton void __kmp_pop_sync(int gtid, enum cons_type ct, ident_t const *ident) { 4117cc577a4SJonathan Peyton int tos; 4127cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 4137cc577a4SJonathan Peyton tos = p->stack_top; 4147cc577a4SJonathan Peyton KE_TRACE(10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid())); 4157cc577a4SJonathan Peyton if (tos == 0 || p->s_top == 0) { 4167cc577a4SJonathan Peyton __kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident); 417bd3a7633SJonathan Peyton } 4187cc577a4SJonathan Peyton if (tos != p->s_top || p->stack_data[tos].type != ct) { 4197cc577a4SJonathan Peyton __kmp_check_null_func(); 4203041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident, 4213041982dSJonathan Peyton &p->stack_data[tos]); 422bd3a7633SJonathan Peyton } 4237cc577a4SJonathan Peyton KE_TRACE(100, (POP_MSG(p))); 4247cc577a4SJonathan Peyton p->s_top = p->stack_data[tos].prev; 4257cc577a4SJonathan Peyton p->stack_data[tos].type = ct_none; 4267cc577a4SJonathan Peyton p->stack_data[tos].ident = NULL; 4277cc577a4SJonathan Peyton p->stack_top = tos - 1; 4287cc577a4SJonathan Peyton KE_DUMP(1000, dump_cons_stack(gtid, p)); 4297cc577a4SJonathan Peyton } 4307cc577a4SJonathan Peyton 4317cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */ 4327cc577a4SJonathan Peyton 4333041982dSJonathan Peyton void __kmp_check_barrier(int gtid, enum cons_type ct, ident_t const *ident) { 4347cc577a4SJonathan Peyton struct cons_header *p = __kmp_threads[gtid]->th.th_cons; 4353041982dSJonathan Peyton KE_TRACE(10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid, 4363041982dSJonathan Peyton __kmp_get_gtid())); 4377cc577a4SJonathan Peyton if (ident != 0) { 4387cc577a4SJonathan Peyton __kmp_check_null_func(); 4397cc577a4SJonathan Peyton } 4407cc577a4SJonathan Peyton if (p->w_top > p->p_top) { 4417cc577a4SJonathan Peyton /* we are already in a WORKSHARING construct for this PARALLEL region */ 4423041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 4433041982dSJonathan Peyton &p->stack_data[p->w_top]); 4447cc577a4SJonathan Peyton } 4457cc577a4SJonathan Peyton if (p->s_top > p->p_top) { 4467cc577a4SJonathan Peyton /* we are already in a SYNC construct for this PARALLEL region */ 4473041982dSJonathan Peyton __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident, 4483041982dSJonathan Peyton &p->stack_data[p->s_top]); 4497cc577a4SJonathan Peyton } 4507cc577a4SJonathan Peyton } 451