xref: /llvm-project/openmp/runtime/src/kmp_error.cpp (revision 97d000cfc6d498ec8f4cde48d75b6d0ddc390c38)
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[] = {
23309b00a4SShilei Tian     "(none)",
24309b00a4SShilei Tian     "\"parallel\"",
25309b00a4SShilei 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 */
33309b00a4SShilei Tian     "\"critical\"",
34309b00a4SShilei Tian     "\"ordered\"", /* in PARALLEL */
357cc577a4SJonathan Peyton     "\"ordered\"", /* in PDO */
36309b00a4SShilei Tian     "\"master\"",
37309b00a4SShilei Tian     "\"reduce\"",
38*97d000cfStlwilmar     "\"barrier\"",
39*97d000cfStlwilmar     "\"masked\""};
407cc577a4SJonathan Peyton 
417cc577a4SJonathan Peyton #define get_src(ident) ((ident) == NULL ? NULL : (ident)->psource)
427cc577a4SJonathan Peyton 
437cc577a4SJonathan Peyton #define PUSH_MSG(ct, ident)                                                    \
447cc577a4SJonathan Peyton   "\tpushing on stack: %s (%s)\n", cons_text_c[(ct)], get_src((ident))
457cc577a4SJonathan Peyton #define POP_MSG(p)                                                             \
463041982dSJonathan Peyton   "\tpopping off stack: %s (%s)\n", cons_text_c[(p)->stack_data[tos].type],    \
477cc577a4SJonathan Peyton       get_src((p)->stack_data[tos].ident)
487cc577a4SJonathan Peyton 
497cc577a4SJonathan Peyton static int const cons_text_c_num = sizeof(cons_text_c) / sizeof(char const *);
507cc577a4SJonathan Peyton 
517cc577a4SJonathan Peyton /* --------------- START OF STATIC LOCAL ROUTINES ------------------------- */
527cc577a4SJonathan Peyton 
__kmp_check_null_func(void)533041982dSJonathan Peyton static void __kmp_check_null_func(void) { /* nothing to do */
547cc577a4SJonathan Peyton }
557cc577a4SJonathan Peyton 
__kmp_expand_cons_stack(int gtid,struct cons_header * p)563041982dSJonathan Peyton static void __kmp_expand_cons_stack(int gtid, struct cons_header *p) {
577cc577a4SJonathan Peyton   int i;
587cc577a4SJonathan Peyton   struct cons_data *d;
597cc577a4SJonathan Peyton 
607cc577a4SJonathan Peyton   /* TODO for monitor perhaps? */
617cc577a4SJonathan Peyton   if (gtid < 0)
627cc577a4SJonathan Peyton     __kmp_check_null_func();
637cc577a4SJonathan Peyton 
647cc577a4SJonathan Peyton   KE_TRACE(10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid()));
657cc577a4SJonathan Peyton 
667cc577a4SJonathan Peyton   d = p->stack_data;
677cc577a4SJonathan Peyton 
687cc577a4SJonathan Peyton   p->stack_size = (p->stack_size * 2) + 100;
697cc577a4SJonathan Peyton 
707cc577a4SJonathan Peyton   /* TODO free the old data */
713041982dSJonathan Peyton   p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) *
723041982dSJonathan Peyton                                                      (p->stack_size + 1));
737cc577a4SJonathan Peyton 
747cc577a4SJonathan Peyton   for (i = p->stack_top; i >= 0; --i)
757cc577a4SJonathan Peyton     p->stack_data[i] = d[i];
767cc577a4SJonathan Peyton 
777cc577a4SJonathan Peyton   /* NOTE: we do not free the old stack_data */
787cc577a4SJonathan Peyton }
797cc577a4SJonathan Peyton 
807cc577a4SJonathan Peyton // NOTE: Function returns allocated memory, caller must free it!
__kmp_pragma(int ct,ident_t const * ident)81aeb40adaSJonas Hahnfeld static char *__kmp_pragma(int ct, ident_t const *ident) {
827cc577a4SJonathan Peyton   char const *cons = NULL; // Construct name.
837cc577a4SJonathan Peyton   char *file = NULL; // File name.
847cc577a4SJonathan Peyton   char *func = NULL; // Function (routine) name.
857cc577a4SJonathan Peyton   char *line = NULL; // Line number.
867cc577a4SJonathan Peyton   kmp_str_buf_t buffer;
877cc577a4SJonathan Peyton   kmp_msg_t prgm;
887cc577a4SJonathan Peyton   __kmp_str_buf_init(&buffer);
897cc577a4SJonathan Peyton   if (0 < ct && ct < cons_text_c_num) {
907cc577a4SJonathan Peyton     cons = cons_text_c[ct];
917cc577a4SJonathan Peyton   } else {
927cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(0);
93bd3a7633SJonathan Peyton   }
947cc577a4SJonathan Peyton   if (ident != NULL && ident->psource != NULL) {
957cc577a4SJonathan Peyton     char *tail = NULL;
963041982dSJonathan Peyton     __kmp_str_buf_print(&buffer, "%s",
973041982dSJonathan Peyton                         ident->psource); // Copy source to buffer.
987cc577a4SJonathan Peyton     // Split string in buffer to file, func, and line.
997cc577a4SJonathan Peyton     tail = buffer.str;
1007cc577a4SJonathan Peyton     __kmp_str_split(tail, ';', NULL, &tail);
1017cc577a4SJonathan Peyton     __kmp_str_split(tail, ';', &file, &tail);
1027cc577a4SJonathan Peyton     __kmp_str_split(tail, ';', &func, &tail);
1037cc577a4SJonathan Peyton     __kmp_str_split(tail, ';', &line, &tail);
104bd3a7633SJonathan Peyton   }
1057cc577a4SJonathan Peyton   prgm = __kmp_msg_format(kmp_i18n_fmt_Pragma, cons, file, func, line);
1067cc577a4SJonathan Peyton   __kmp_str_buf_free(&buffer);
1077cc577a4SJonathan Peyton   return prgm.str;
1087cc577a4SJonathan Peyton } // __kmp_pragma
1097cc577a4SJonathan Peyton 
1107cc577a4SJonathan Peyton /* ----------------- END OF STATIC LOCAL ROUTINES ------------------------- */
1117cc577a4SJonathan Peyton 
__kmp_error_construct(kmp_i18n_id_t id,enum cons_type ct,ident_t const * ident)1123041982dSJonathan Peyton void __kmp_error_construct(kmp_i18n_id_t id, // Message identifier.
1137cc577a4SJonathan Peyton                            enum cons_type ct, // Construct type.
1147cc577a4SJonathan Peyton                            ident_t const *ident // Construct ident.
1157cc577a4SJonathan Peyton ) {
116aeb40adaSJonas Hahnfeld   char *construct = __kmp_pragma(ct, ident);
1176a393f75SJonathan Peyton   __kmp_fatal(__kmp_msg_format(id, construct), __kmp_msg_null);
118aeb40adaSJonas Hahnfeld   KMP_INTERNAL_FREE(construct);
1197cc577a4SJonathan Peyton }
1207cc577a4SJonathan Peyton 
__kmp_error_construct2(kmp_i18n_id_t id,enum cons_type ct,ident_t const * ident,struct cons_data const * cons)1213041982dSJonathan Peyton void __kmp_error_construct2(kmp_i18n_id_t id, // Message identifier.
1227cc577a4SJonathan Peyton                             enum cons_type ct, // First construct type.
1237cc577a4SJonathan Peyton                             ident_t const *ident, // First construct ident.
1247cc577a4SJonathan Peyton                             struct cons_data const *cons // Second construct.
1257cc577a4SJonathan Peyton ) {
126aeb40adaSJonas Hahnfeld   char *construct1 = __kmp_pragma(ct, ident);
127aeb40adaSJonas Hahnfeld   char *construct2 = __kmp_pragma(cons->type, cons->ident);
1286a393f75SJonathan Peyton   __kmp_fatal(__kmp_msg_format(id, construct1, construct2), __kmp_msg_null);
129aeb40adaSJonas Hahnfeld   KMP_INTERNAL_FREE(construct1);
130aeb40adaSJonas Hahnfeld   KMP_INTERNAL_FREE(construct2);
1317cc577a4SJonathan Peyton }
1327cc577a4SJonathan Peyton 
__kmp_allocate_cons_stack(int gtid)1333041982dSJonathan Peyton struct cons_header *__kmp_allocate_cons_stack(int gtid) {
1347cc577a4SJonathan Peyton   struct cons_header *p;
1357cc577a4SJonathan Peyton 
1367cc577a4SJonathan Peyton   /* TODO for monitor perhaps? */
1377cc577a4SJonathan Peyton   if (gtid < 0) {
1387cc577a4SJonathan Peyton     __kmp_check_null_func();
139bd3a7633SJonathan Peyton   }
1407cc577a4SJonathan Peyton   KE_TRACE(10, ("allocate cons_stack (%d)\n", gtid));
1417cc577a4SJonathan Peyton   p = (struct cons_header *)__kmp_allocate(sizeof(struct cons_header));
1427cc577a4SJonathan Peyton   p->p_top = p->w_top = p->s_top = 0;
1433041982dSJonathan Peyton   p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) *
1443041982dSJonathan Peyton                                                      (MIN_STACK + 1));
1457cc577a4SJonathan Peyton   p->stack_size = MIN_STACK;
1467cc577a4SJonathan Peyton   p->stack_top = 0;
1477cc577a4SJonathan Peyton   p->stack_data[0].type = ct_none;
1487cc577a4SJonathan Peyton   p->stack_data[0].prev = 0;
1497cc577a4SJonathan Peyton   p->stack_data[0].ident = NULL;
1507cc577a4SJonathan Peyton   return p;
1517cc577a4SJonathan Peyton }
1527cc577a4SJonathan Peyton 
__kmp_free_cons_stack(void * ptr)1533041982dSJonathan Peyton void __kmp_free_cons_stack(void *ptr) {
1547cc577a4SJonathan Peyton   struct cons_header *p = (struct cons_header *)ptr;
1557cc577a4SJonathan Peyton   if (p != NULL) {
1567cc577a4SJonathan Peyton     if (p->stack_data != NULL) {
1577cc577a4SJonathan Peyton       __kmp_free(p->stack_data);
1587cc577a4SJonathan Peyton       p->stack_data = NULL;
159bd3a7633SJonathan Peyton     }
1607cc577a4SJonathan Peyton     __kmp_free(p);
161bd3a7633SJonathan Peyton   }
1627cc577a4SJonathan Peyton }
1637cc577a4SJonathan Peyton 
1647cc577a4SJonathan Peyton #if KMP_DEBUG
dump_cons_stack(int gtid,struct cons_header * p)1653041982dSJonathan Peyton static void dump_cons_stack(int gtid, struct cons_header *p) {
1667cc577a4SJonathan Peyton   int i;
1677cc577a4SJonathan Peyton   int tos = p->stack_top;
1687cc577a4SJonathan Peyton   kmp_str_buf_t buffer;
1697cc577a4SJonathan Peyton   __kmp_str_buf_init(&buffer);
1703041982dSJonathan Peyton   __kmp_str_buf_print(
1713041982dSJonathan Peyton       &buffer,
1723041982dSJonathan Peyton       "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
1733041982dSJonathan Peyton   __kmp_str_buf_print(&buffer,
1743041982dSJonathan Peyton                       "Begin construct stack with %d items for thread %d\n",
1753041982dSJonathan Peyton                       tos, gtid);
1763041982dSJonathan Peyton   __kmp_str_buf_print(&buffer, "     stack_top=%d { P=%d, W=%d, S=%d }\n", tos,
1773041982dSJonathan Peyton                       p->p_top, p->w_top, p->s_top);
1787cc577a4SJonathan Peyton   for (i = tos; i > 0; i--) {
1797cc577a4SJonathan Peyton     struct cons_data *c = &(p->stack_data[i]);
1803041982dSJonathan Peyton     __kmp_str_buf_print(
1813041982dSJonathan Peyton         &buffer, "        stack_data[%2d] = { %s (%s) %d %p }\n", i,
1823041982dSJonathan Peyton         cons_text_c[c->type], get_src(c->ident), c->prev, c->name);
183bd3a7633SJonathan Peyton   }
1847cc577a4SJonathan Peyton   __kmp_str_buf_print(&buffer, "End construct stack for thread %d\n", gtid);
1853041982dSJonathan Peyton   __kmp_str_buf_print(
1863041982dSJonathan Peyton       &buffer,
1873041982dSJonathan Peyton       "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
1887cc577a4SJonathan Peyton   __kmp_debug_printf("%s", buffer.str);
1897cc577a4SJonathan Peyton   __kmp_str_buf_free(&buffer);
1907cc577a4SJonathan Peyton }
1917cc577a4SJonathan Peyton #endif
1927cc577a4SJonathan Peyton 
__kmp_push_parallel(int gtid,ident_t const * ident)1933041982dSJonathan Peyton void __kmp_push_parallel(int gtid, ident_t const *ident) {
1947cc577a4SJonathan Peyton   int tos;
1957cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
1967cc577a4SJonathan Peyton 
1977cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons);
1987cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid()));
1997cc577a4SJonathan Peyton   KE_TRACE(100, (PUSH_MSG(ct_parallel, ident)));
2007cc577a4SJonathan Peyton   if (p->stack_top >= p->stack_size) {
2017cc577a4SJonathan Peyton     __kmp_expand_cons_stack(gtid, p);
202bd3a7633SJonathan Peyton   }
2037cc577a4SJonathan Peyton   tos = ++p->stack_top;
2047cc577a4SJonathan Peyton   p->stack_data[tos].type = ct_parallel;
2057cc577a4SJonathan Peyton   p->stack_data[tos].prev = p->p_top;
2067cc577a4SJonathan Peyton   p->stack_data[tos].ident = ident;
2077cc577a4SJonathan Peyton   p->stack_data[tos].name = NULL;
2087cc577a4SJonathan Peyton   p->p_top = tos;
2097cc577a4SJonathan Peyton   KE_DUMP(1000, dump_cons_stack(gtid, p));
2107cc577a4SJonathan Peyton }
2117cc577a4SJonathan Peyton 
__kmp_check_workshare(int gtid,enum cons_type ct,ident_t const * ident)2123041982dSJonathan Peyton void __kmp_check_workshare(int gtid, enum cons_type ct, ident_t const *ident) {
2137cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
2147cc577a4SJonathan Peyton 
2157cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons);
2167cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
2177cc577a4SJonathan Peyton 
2187cc577a4SJonathan Peyton   if (p->stack_top >= p->stack_size) {
2197cc577a4SJonathan Peyton     __kmp_expand_cons_stack(gtid, p);
220bd3a7633SJonathan Peyton   }
22144b476c1SJonathan Peyton   if (p->w_top > p->p_top) {
2227cc577a4SJonathan Peyton     // We are already in a WORKSHARE construct for this PARALLEL region.
2233041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
2243041982dSJonathan Peyton                            &p->stack_data[p->w_top]);
225bd3a7633SJonathan Peyton   }
2267cc577a4SJonathan Peyton   if (p->s_top > p->p_top) {
2277cc577a4SJonathan Peyton     // We are already in a SYNC construct for this PARALLEL region.
2283041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
2293041982dSJonathan Peyton                            &p->stack_data[p->s_top]);
230bd3a7633SJonathan Peyton   }
2317cc577a4SJonathan Peyton }
2327cc577a4SJonathan Peyton 
__kmp_push_workshare(int gtid,enum cons_type ct,ident_t const * ident)2333041982dSJonathan Peyton void __kmp_push_workshare(int gtid, enum cons_type ct, ident_t const *ident) {
2347cc577a4SJonathan Peyton   int tos;
2357cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
2367cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
2377cc577a4SJonathan Peyton   __kmp_check_workshare(gtid, ct, ident);
2387cc577a4SJonathan Peyton   KE_TRACE(100, (PUSH_MSG(ct, ident)));
2397cc577a4SJonathan Peyton   tos = ++p->stack_top;
2407cc577a4SJonathan Peyton   p->stack_data[tos].type = ct;
2417cc577a4SJonathan Peyton   p->stack_data[tos].prev = p->w_top;
2427cc577a4SJonathan Peyton   p->stack_data[tos].ident = ident;
2437cc577a4SJonathan Peyton   p->stack_data[tos].name = NULL;
2447cc577a4SJonathan Peyton   p->w_top = tos;
2457cc577a4SJonathan Peyton   KE_DUMP(1000, dump_cons_stack(gtid, p));
2467cc577a4SJonathan Peyton }
2477cc577a4SJonathan Peyton 
2487cc577a4SJonathan Peyton void
2497cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK
__kmp_check_sync(int gtid,enum cons_type ct,ident_t const * ident,kmp_user_lock_p lck,kmp_uint32 seq)2507cc577a4SJonathan Peyton __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq )
2517cc577a4SJonathan Peyton #else
2527cc577a4SJonathan Peyton __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
2537cc577a4SJonathan Peyton #endif
2547cc577a4SJonathan Peyton {
2557cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
2567cc577a4SJonathan Peyton 
2577cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid()));
2587cc577a4SJonathan Peyton 
2597cc577a4SJonathan Peyton   if (p->stack_top >= p->stack_size)
2607cc577a4SJonathan Peyton     __kmp_expand_cons_stack(gtid, p);
2617cc577a4SJonathan Peyton 
26244b476c1SJonathan Peyton   if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo) {
2637cc577a4SJonathan Peyton     if (p->w_top <= p->p_top) {
2647cc577a4SJonathan Peyton /* we are not in a worksharing construct */
2657cc577a4SJonathan Peyton #ifdef BUILD_PARALLEL_ORDERED
2667cc577a4SJonathan Peyton       /* do not report error messages for PARALLEL ORDERED */
2677cc577a4SJonathan Peyton       KMP_ASSERT(ct == ct_ordered_in_parallel);
2687cc577a4SJonathan Peyton #else
2697cc577a4SJonathan Peyton       __kmp_error_construct(kmp_i18n_msg_CnsBoundToWorksharing, ct, ident);
2707cc577a4SJonathan Peyton #endif /* BUILD_PARALLEL_ORDERED */
2717cc577a4SJonathan Peyton     } else {
2727cc577a4SJonathan Peyton       /* inside a WORKSHARING construct for this PARALLEL region */
2737cc577a4SJonathan Peyton       if (!IS_CONS_TYPE_ORDERED(p->stack_data[p->w_top].type)) {
2743041982dSJonathan Peyton         __kmp_error_construct2(kmp_i18n_msg_CnsNoOrderedClause, ct, ident,
2753041982dSJonathan Peyton                                &p->stack_data[p->w_top]);
2767cc577a4SJonathan Peyton       }
2777cc577a4SJonathan Peyton     }
2787cc577a4SJonathan Peyton     if (p->s_top > p->p_top && p->s_top > p->w_top) {
2797cc577a4SJonathan Peyton       /* inside a sync construct which is inside a worksharing construct */
2807cc577a4SJonathan Peyton       int index = p->s_top;
2817cc577a4SJonathan Peyton       enum cons_type stack_type;
2827cc577a4SJonathan Peyton 
2837cc577a4SJonathan Peyton       stack_type = p->stack_data[index].type;
2847cc577a4SJonathan Peyton 
2857cc577a4SJonathan Peyton       if (stack_type == ct_critical ||
2867cc577a4SJonathan Peyton           ((stack_type == ct_ordered_in_parallel ||
28744b476c1SJonathan Peyton             stack_type == ct_ordered_in_pdo) &&
28844b476c1SJonathan Peyton            /* C doesn't allow named ordered; ordered in ordered gets error */
2897cc577a4SJonathan Peyton            p->stack_data[index].ident != NULL &&
2907cc577a4SJonathan Peyton            (p->stack_data[index].ident->flags & KMP_IDENT_KMPC))) {
2917cc577a4SJonathan Peyton         /* we are in ORDERED which is inside an ORDERED or CRITICAL construct */
2923041982dSJonathan Peyton         __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
2933041982dSJonathan Peyton                                &p->stack_data[index]);
2947cc577a4SJonathan Peyton       }
2957cc577a4SJonathan Peyton     }
2967cc577a4SJonathan Peyton   } else if (ct == ct_critical) {
2977cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK
2983041982dSJonathan Peyton     if (lck != NULL &&
2993041982dSJonathan Peyton         __kmp_get_user_lock_owner(lck, seq) ==
3003041982dSJonathan Peyton             gtid) { /* this thread already has lock for this critical section */
3017cc577a4SJonathan Peyton #else
3023041982dSJonathan Peyton     if (lck != NULL &&
3033041982dSJonathan Peyton         __kmp_get_user_lock_owner(lck) ==
3043041982dSJonathan Peyton             gtid) { /* this thread already has lock for this critical section */
3057cc577a4SJonathan Peyton #endif
3067cc577a4SJonathan Peyton       int index = p->s_top;
3077cc577a4SJonathan Peyton       struct cons_data cons = {NULL, ct_critical, 0, NULL};
3087cc577a4SJonathan Peyton       /* walk up construct stack and try to find critical with matching name */
3097cc577a4SJonathan Peyton       while (index != 0 && p->stack_data[index].name != lck) {
3107cc577a4SJonathan Peyton         index = p->stack_data[index].prev;
3117cc577a4SJonathan Peyton       }
3127cc577a4SJonathan Peyton       if (index != 0) {
3133041982dSJonathan Peyton         /* found match on the stack (may not always because of interleaved
3143041982dSJonathan Peyton          * critical for Fortran) */
3157cc577a4SJonathan Peyton         cons = p->stack_data[index];
3167cc577a4SJonathan Peyton       }
3173041982dSJonathan Peyton       /* we are in CRITICAL which is inside a CRITICAL construct of same name */
3187cc577a4SJonathan Peyton       __kmp_error_construct2(kmp_i18n_msg_CnsNestingSameName, ct, ident, &cons);
3197cc577a4SJonathan Peyton     }
320*97d000cfStlwilmar   } else if (ct == ct_master || ct == ct_masked || ct == ct_reduce) {
3217cc577a4SJonathan Peyton     if (p->w_top > p->p_top) {
3227cc577a4SJonathan Peyton       /* inside a WORKSHARING construct for this PARALLEL region */
3233041982dSJonathan Peyton       __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
3243041982dSJonathan Peyton                              &p->stack_data[p->w_top]);
3257cc577a4SJonathan Peyton     }
3267cc577a4SJonathan Peyton     if (ct == ct_reduce && p->s_top > p->p_top) {
3277cc577a4SJonathan Peyton       /* inside a another SYNC construct for this PARALLEL region */
3283041982dSJonathan Peyton       __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
3293041982dSJonathan Peyton                              &p->stack_data[p->s_top]);
330bd3a7633SJonathan Peyton     }
331bd3a7633SJonathan Peyton   }
3327cc577a4SJonathan Peyton }
3337cc577a4SJonathan Peyton 
3347cc577a4SJonathan Peyton void
3357cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK
3367cc577a4SJonathan Peyton __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq )
3377cc577a4SJonathan Peyton #else
3387cc577a4SJonathan Peyton __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
3397cc577a4SJonathan Peyton #endif
3407cc577a4SJonathan Peyton {
3417cc577a4SJonathan Peyton   int tos;
3427cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
3437cc577a4SJonathan Peyton 
3447cc577a4SJonathan Peyton   KMP_ASSERT(gtid == __kmp_get_gtid());
3457cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_push_sync (gtid=%d)\n", gtid));
3467cc577a4SJonathan Peyton #if KMP_USE_DYNAMIC_LOCK
3477cc577a4SJonathan Peyton   __kmp_check_sync(gtid, ct, ident, lck, seq);
3487cc577a4SJonathan Peyton #else
3497cc577a4SJonathan Peyton   __kmp_check_sync(gtid, ct, ident, lck);
3507cc577a4SJonathan Peyton #endif
3517cc577a4SJonathan Peyton   KE_TRACE(100, (PUSH_MSG(ct, ident)));
3527cc577a4SJonathan Peyton   tos = ++p->stack_top;
3537cc577a4SJonathan Peyton   p->stack_data[tos].type = ct;
3547cc577a4SJonathan Peyton   p->stack_data[tos].prev = p->s_top;
3557cc577a4SJonathan Peyton   p->stack_data[tos].ident = ident;
3567cc577a4SJonathan Peyton   p->stack_data[tos].name = lck;
3577cc577a4SJonathan Peyton   p->s_top = tos;
3587cc577a4SJonathan Peyton   KE_DUMP(1000, dump_cons_stack(gtid, p));
3597cc577a4SJonathan Peyton }
3607cc577a4SJonathan Peyton 
3617cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */
3627cc577a4SJonathan Peyton 
3633041982dSJonathan Peyton void __kmp_pop_parallel(int gtid, ident_t const *ident) {
3647cc577a4SJonathan Peyton   int tos;
3657cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
3667cc577a4SJonathan Peyton   tos = p->stack_top;
3677cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_pop_parallel (%d %d)\n", gtid, __kmp_get_gtid()));
3687cc577a4SJonathan Peyton   if (tos == 0 || p->p_top == 0) {
3697cc577a4SJonathan Peyton     __kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct_parallel, ident);
3707cc577a4SJonathan Peyton   }
3717cc577a4SJonathan Peyton   if (tos != p->p_top || p->stack_data[tos].type != ct_parallel) {
3723041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct_parallel, ident,
3733041982dSJonathan Peyton                            &p->stack_data[tos]);
3747cc577a4SJonathan Peyton   }
3757cc577a4SJonathan Peyton   KE_TRACE(100, (POP_MSG(p)));
3767cc577a4SJonathan Peyton   p->p_top = p->stack_data[tos].prev;
3777cc577a4SJonathan Peyton   p->stack_data[tos].type = ct_none;
3787cc577a4SJonathan Peyton   p->stack_data[tos].ident = NULL;
3797cc577a4SJonathan Peyton   p->stack_top = tos - 1;
3807cc577a4SJonathan Peyton   KE_DUMP(1000, dump_cons_stack(gtid, p));
3817cc577a4SJonathan Peyton }
3827cc577a4SJonathan Peyton 
3833041982dSJonathan Peyton enum cons_type __kmp_pop_workshare(int gtid, enum cons_type ct,
3843041982dSJonathan Peyton                                    ident_t const *ident) {
3857cc577a4SJonathan Peyton   int tos;
3867cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
3877cc577a4SJonathan Peyton 
3887cc577a4SJonathan Peyton   tos = p->stack_top;
3897cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
3907cc577a4SJonathan Peyton   if (tos == 0 || p->w_top == 0) {
3917cc577a4SJonathan Peyton     __kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident);
3927cc577a4SJonathan Peyton   }
3937cc577a4SJonathan Peyton 
3947cc577a4SJonathan Peyton   if (tos != p->w_top ||
3957cc577a4SJonathan Peyton       (p->stack_data[tos].type != ct &&
39644b476c1SJonathan Peyton        // below is the exception to the rule that construct types must match
39744b476c1SJonathan Peyton        !(p->stack_data[tos].type == ct_pdo_ordered && ct == ct_pdo))) {
3987cc577a4SJonathan Peyton     __kmp_check_null_func();
3993041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident,
4003041982dSJonathan Peyton                            &p->stack_data[tos]);
4017cc577a4SJonathan Peyton   }
4027cc577a4SJonathan Peyton   KE_TRACE(100, (POP_MSG(p)));
4037cc577a4SJonathan Peyton   p->w_top = p->stack_data[tos].prev;
4047cc577a4SJonathan Peyton   p->stack_data[tos].type = ct_none;
4057cc577a4SJonathan Peyton   p->stack_data[tos].ident = NULL;
4067cc577a4SJonathan Peyton   p->stack_top = tos - 1;
4077cc577a4SJonathan Peyton   KE_DUMP(1000, dump_cons_stack(gtid, p));
4087cc577a4SJonathan Peyton   return p->stack_data[p->w_top].type;
4097cc577a4SJonathan Peyton }
4107cc577a4SJonathan Peyton 
4113041982dSJonathan Peyton void __kmp_pop_sync(int gtid, enum cons_type ct, ident_t const *ident) {
4127cc577a4SJonathan Peyton   int tos;
4137cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
4147cc577a4SJonathan Peyton   tos = p->stack_top;
4157cc577a4SJonathan Peyton   KE_TRACE(10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid()));
4167cc577a4SJonathan Peyton   if (tos == 0 || p->s_top == 0) {
4177cc577a4SJonathan Peyton     __kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident);
418bd3a7633SJonathan Peyton   }
4197cc577a4SJonathan Peyton   if (tos != p->s_top || p->stack_data[tos].type != ct) {
4207cc577a4SJonathan Peyton     __kmp_check_null_func();
4213041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident,
4223041982dSJonathan Peyton                            &p->stack_data[tos]);
423bd3a7633SJonathan Peyton   }
4247cc577a4SJonathan Peyton   KE_TRACE(100, (POP_MSG(p)));
4257cc577a4SJonathan Peyton   p->s_top = p->stack_data[tos].prev;
4267cc577a4SJonathan Peyton   p->stack_data[tos].type = ct_none;
4277cc577a4SJonathan Peyton   p->stack_data[tos].ident = NULL;
4287cc577a4SJonathan Peyton   p->stack_top = tos - 1;
4297cc577a4SJonathan Peyton   KE_DUMP(1000, dump_cons_stack(gtid, p));
4307cc577a4SJonathan Peyton }
4317cc577a4SJonathan Peyton 
4327cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */
4337cc577a4SJonathan Peyton 
4343041982dSJonathan Peyton void __kmp_check_barrier(int gtid, enum cons_type ct, ident_t const *ident) {
4357cc577a4SJonathan Peyton   struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
4363041982dSJonathan Peyton   KE_TRACE(10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid,
4373041982dSJonathan Peyton                 __kmp_get_gtid()));
4387cc577a4SJonathan Peyton   if (ident != 0) {
4397cc577a4SJonathan Peyton     __kmp_check_null_func();
4407cc577a4SJonathan Peyton   }
4417cc577a4SJonathan Peyton   if (p->w_top > p->p_top) {
4427cc577a4SJonathan Peyton     /* we are already in a WORKSHARING construct for this PARALLEL region */
4433041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
4443041982dSJonathan Peyton                            &p->stack_data[p->w_top]);
4457cc577a4SJonathan Peyton   }
4467cc577a4SJonathan Peyton   if (p->s_top > p->p_top) {
4477cc577a4SJonathan Peyton     /* we are already in a SYNC construct for this PARALLEL region */
4483041982dSJonathan Peyton     __kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
4493041982dSJonathan Peyton                            &p->stack_data[p->s_top]);
4507cc577a4SJonathan Peyton   }
4517cc577a4SJonathan Peyton }
452