Intel® OpenMP* Runtime Library
kmp_error.c
1 /*
2  * kmp_error.c -- KPTS functions for error checking at runtime
3  */
4 
5 /* <copyright>
6  Copyright (c) 1997-2015 Intel Corporation. All Rights Reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11 
12  * Redistributions of source code must retain the above copyright
13  notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17  * Neither the name of Intel Corporation nor the names of its
18  contributors may be used to endorse or promote products derived
19  from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 </copyright> */
34 
35 #include "kmp.h"
36 #include "kmp_i18n.h"
37 #include "kmp_str.h"
38 #include "kmp_error.h"
39 
40 /* ------------------------------------------------------------------------ */
41 /* ------------------------------------------------------------------------ */
42 
43 #define MIN_STACK 100
44 
45 static char const * cons_text_fort[] = {
46  "(none)",
47  "PARALLEL",
48  "work-sharing", /* this is not called DO because of lowering of SECTIONS and WORKSHARE directives */
49  "ORDERED work-sharing", /* this is not called DO ORDERED because of lowering of SECTIONS directives */
50  "SECTIONS",
51  "work-sharing", /* this is not called SINGLE because of lowering of SECTIONS and WORKSHARE directives */
52  "TASKQ",
53  "TASKQ",
54  "TASKQ ORDERED",
55  "CRITICAL",
56  "ORDERED", /* in PARALLEL */
57  "ORDERED", /* in PDO */
58  "ORDERED", /* in TASKQ */
59  "MASTER",
60  "REDUCE",
61  "BARRIER"
62 };
63 
64 static char const * cons_text_c[] = {
65  "(none)",
66  "\"parallel\"",
67  "work-sharing", /* this is not called "for" because of lowering of "sections" pragmas */
68  "\"ordered\" work-sharing", /* this is not called "for ordered" because of lowering of "sections" pragmas */
69  "\"sections\"",
70  "work-sharing", /* this is not called "single" because of lowering of "sections" pragmas */
71  "\"taskq\"",
72  "\"taskq\"",
73  "\"taskq ordered\"",
74  "\"critical\"",
75  "\"ordered\"", /* in PARALLEL */
76  "\"ordered\"", /* in PDO */
77  "\"ordered\"", /* in TASKQ */
78  "\"master\"",
79  "\"reduce\"",
80  "\"barrier\""
81 };
82 
83 #define get_src( ident ) ( (ident) == NULL ? NULL : (ident)->psource )
84 
85 #define PUSH_MSG( ct, ident ) \
86  "\tpushing on stack: %s (%s)\n", cons_text_c[ (ct) ], get_src( (ident) )
87 #define POP_MSG( p ) \
88  "\tpopping off stack: %s (%s)\n", \
89  cons_text_c[ (p)->stack_data[ tos ].type ], \
90  get_src( (p)->stack_data[ tos ].ident )
91 
92 static int const cons_text_fort_num = sizeof( cons_text_fort ) / sizeof( char const * );
93 static int const cons_text_c_num = sizeof( cons_text_c ) / sizeof( char const * );
94 
95 /* ------------------------------------------------------------------------ */
96 /* --------------- START OF STATIC LOCAL ROUTINES ------------------------- */
97 /* ------------------------------------------------------------------------ */
98 
99 static void
100 __kmp_check_null_func( void )
101 {
102  /* nothing to do */
103 }
104 
105 static void
106 __kmp_expand_cons_stack( int gtid, struct cons_header *p )
107 {
108  int i;
109  struct cons_data *d;
110 
111  /* TODO for monitor perhaps? */
112  if (gtid < 0)
113  __kmp_check_null_func();
114 
115  KE_TRACE( 10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid() ) );
116 
117  d = p->stack_data;
118 
119  p->stack_size = (p->stack_size * 2) + 100;
120 
121  /* TODO free the old data */
122  p->stack_data = (struct cons_data *) __kmp_allocate( sizeof( struct cons_data ) * (p->stack_size+1) );
123 
124  for (i = p->stack_top; i >= 0; --i)
125  p->stack_data[i] = d[i];
126 
127  /* NOTE: we do not free the old stack_data */
128 }
129 
130 // NOTE: Function returns allocated memory, caller must free it!
131 static char const *
132 __kmp_pragma(
133  int ct,
134  ident_t const * ident
135 ) {
136  char const * cons = NULL; // Construct name.
137  char * file = NULL; // File name.
138  char * func = NULL; // Function (routine) name.
139  char * line = NULL; // Line number.
140  kmp_str_buf_t buffer;
141  kmp_msg_t prgm;
142  __kmp_str_buf_init( & buffer );
143  if ( 0 < ct && ct < cons_text_c_num ) {
144  cons = cons_text_c[ ct ];
145  } else {
146  KMP_DEBUG_ASSERT( 0 );
147  };
148  if ( ident != NULL && ident->psource != NULL ) {
149  char * tail = NULL;
150  __kmp_str_buf_print( & buffer, "%s", ident->psource ); // Copy source to buffer.
151  // Split string in buffer to file, func, and line.
152  tail = buffer.str;
153  __kmp_str_split( tail, ';', NULL, & tail );
154  __kmp_str_split( tail, ';', & file, & tail );
155  __kmp_str_split( tail, ';', & func, & tail );
156  __kmp_str_split( tail, ';', & line, & tail );
157  }; // if
158  prgm = __kmp_msg_format( kmp_i18n_fmt_Pragma, cons, file, func, line );
159  __kmp_str_buf_free( & buffer );
160  return prgm.str;
161 } // __kmp_pragma
162 
163 /* ------------------------------------------------------------------------ */
164 /* ----------------- END OF STATIC LOCAL ROUTINES ------------------------- */
165 /* ------------------------------------------------------------------------ */
166 
167 
168 void
169 __kmp_error_construct(
170  kmp_i18n_id_t id, // Message identifier.
171  enum cons_type ct, // Construct type.
172  ident_t const * ident // Construct ident.
173 ) {
174  char const * construct = __kmp_pragma( ct, ident );
175  __kmp_msg( kmp_ms_fatal, __kmp_msg_format( id, construct ), __kmp_msg_null );
176  KMP_INTERNAL_FREE( (void *) construct );
177 }
178 
179 void
180 __kmp_error_construct2(
181  kmp_i18n_id_t id, // Message identifier.
182  enum cons_type ct, // First construct type.
183  ident_t const * ident, // First construct ident.
184  struct cons_data const * cons // Second construct.
185 ) {
186  char const * construct1 = __kmp_pragma( ct, ident );
187  char const * construct2 = __kmp_pragma( cons->type, cons->ident );
188  __kmp_msg( kmp_ms_fatal, __kmp_msg_format( id, construct1, construct2 ), __kmp_msg_null );
189  KMP_INTERNAL_FREE( (void *) construct1 );
190  KMP_INTERNAL_FREE( (void *) construct2 );
191 }
192 
193 
194 struct cons_header *
195 __kmp_allocate_cons_stack( int gtid )
196 {
197  struct cons_header *p;
198 
199  /* TODO for monitor perhaps? */
200  if ( gtid < 0 ) {
201  __kmp_check_null_func();
202  }; // if
203  KE_TRACE( 10, ("allocate cons_stack (%d)\n", gtid ) );
204  p = (struct cons_header *) __kmp_allocate( sizeof( struct cons_header ) );
205  p->p_top = p->w_top = p->s_top = 0;
206  p->stack_data = (struct cons_data *) __kmp_allocate( sizeof( struct cons_data ) * (MIN_STACK+1) );
207  p->stack_size = MIN_STACK;
208  p->stack_top = 0;
209  p->stack_data[ 0 ].type = ct_none;
210  p->stack_data[ 0 ].prev = 0;
211  p->stack_data[ 0 ].ident = NULL;
212  return p;
213 }
214 
215 void
216 __kmp_free_cons_stack( void * ptr ) {
217  struct cons_header * p = (struct cons_header *) ptr;
218  if ( p != NULL ) {
219  if ( p->stack_data != NULL ) {
220  __kmp_free( p->stack_data );
221  p->stack_data = NULL;
222  }; // if
223  __kmp_free( p );
224  }; // if
225 }
226 
227 
228 static void
229 dump_cons_stack( int gtid, struct cons_header * p ) {
230  int i;
231  int tos = p->stack_top;
232  kmp_str_buf_t buffer;
233  __kmp_str_buf_init( & buffer );
234  __kmp_str_buf_print( & buffer, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n" );
235  __kmp_str_buf_print( & buffer, "Begin construct stack with %d items for thread %d\n", tos, gtid );
236  __kmp_str_buf_print( & buffer, " stack_top=%d { P=%d, W=%d, S=%d }\n", tos, p->p_top, p->w_top, p->s_top );
237  for ( i = tos; i > 0; i-- ) {
238  struct cons_data * c = & ( p->stack_data[ i ] );
239  __kmp_str_buf_print( & buffer, " stack_data[%2d] = { %s (%s) %d %p }\n", i, cons_text_c[ c->type ], get_src( c->ident ), c->prev, c->name );
240  }; // for i
241  __kmp_str_buf_print( & buffer, "End construct stack for thread %d\n", gtid );
242  __kmp_str_buf_print( & buffer, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n" );
243  __kmp_debug_printf( "%s", buffer.str );
244  __kmp_str_buf_free( & buffer );
245 }
246 
247 void
248 __kmp_push_parallel( int gtid, ident_t const * ident )
249 {
250  int tos;
251  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
252 
253  KMP_DEBUG_ASSERT( __kmp_threads[ gtid ]-> th.th_cons );
254  KE_TRACE( 10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid() ) );
255  KE_TRACE( 100, ( PUSH_MSG( ct_parallel, ident ) ) );
256  if ( p->stack_top >= p->stack_size ) {
257  __kmp_expand_cons_stack( gtid, p );
258  }; // if
259  tos = ++p->stack_top;
260  p->stack_data[ tos ].type = ct_parallel;
261  p->stack_data[ tos ].prev = p->p_top;
262  p->stack_data[ tos ].ident = ident;
263  p->stack_data[ tos ].name = NULL;
264  p->p_top = tos;
265  KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
266 }
267 
268 void
269 __kmp_check_workshare( int gtid, enum cons_type ct, ident_t const * ident )
270 {
271  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
272 
273  KMP_DEBUG_ASSERT( __kmp_threads[ gtid ]-> th.th_cons );
274  KE_TRACE( 10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) );
275 
276 
277  if ( p->stack_top >= p->stack_size ) {
278  __kmp_expand_cons_stack( gtid, p );
279  }; // if
280  if ( p->w_top > p->p_top &&
281  !(IS_CONS_TYPE_TASKQ(p->stack_data[ p->w_top ].type) && IS_CONS_TYPE_TASKQ(ct))) {
282  // We are already in a WORKSHARE construct for this PARALLEL region.
283  __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->w_top ] );
284  }; // if
285  if ( p->s_top > p->p_top ) {
286  // We are already in a SYNC construct for this PARALLEL region.
287  __kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->s_top ] );
288  }; // if
289 }
290 
291 void
292 __kmp_push_workshare( int gtid, enum cons_type ct, ident_t const * ident )
293 {
294  int tos;
295  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
296  KE_TRACE( 10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) );
297  __kmp_check_workshare( gtid, ct, ident );
298  KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) );
299  tos = ++p->stack_top;
300  p->stack_data[ tos ].type = ct;
301  p->stack_data[ tos ].prev = p->w_top;
302  p->stack_data[ tos ].ident = ident;
303  p->stack_data[ tos ].name = NULL;
304  p->w_top = tos;
305  KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
306 }
307 
308 void
309 #if KMP_USE_DYNAMIC_LOCK
310 __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq )
311 #else
312 __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
313 #endif
314 {
315  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
316 
317  KE_TRACE( 10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid() ) );
318 
319  if (p->stack_top >= p->stack_size)
320  __kmp_expand_cons_stack( gtid, p );
321 
322  if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo || ct == ct_ordered_in_taskq ) {
323  if (p->w_top <= p->p_top) {
324  /* we are not in a worksharing construct */
325  #ifdef BUILD_PARALLEL_ORDERED
326  /* do not report error messages for PARALLEL ORDERED */
327  KMP_ASSERT( ct == ct_ordered_in_parallel );
328  #else
329  __kmp_error_construct( kmp_i18n_msg_CnsBoundToWorksharing, ct, ident );
330  #endif /* BUILD_PARALLEL_ORDERED */
331  } else {
332  /* inside a WORKSHARING construct for this PARALLEL region */
333  if (!IS_CONS_TYPE_ORDERED(p->stack_data[ p->w_top ].type)) {
334  if (p->stack_data[ p->w_top ].type == ct_taskq) {
335  __kmp_error_construct2(
336  kmp_i18n_msg_CnsNotInTaskConstruct,
337  ct, ident,
338  & p->stack_data[ p->w_top ]
339  );
340  } else {
341  __kmp_error_construct2(
342  kmp_i18n_msg_CnsNoOrderedClause,
343  ct, ident,
344  & p->stack_data[ p->w_top ]
345  );
346  }
347  }
348  }
349  if (p->s_top > p->p_top && p->s_top > p->w_top) {
350  /* inside a sync construct which is inside a worksharing construct */
351  int index = p->s_top;
352  enum cons_type stack_type;
353 
354  stack_type = p->stack_data[ index ].type;
355 
356  if (stack_type == ct_critical ||
357  ( ( stack_type == ct_ordered_in_parallel ||
358  stack_type == ct_ordered_in_pdo ||
359  stack_type == ct_ordered_in_taskq ) && /* C doesn't allow named ordered; ordered in ordered gets error */
360  p->stack_data[ index ].ident != NULL &&
361  (p->stack_data[ index ].ident->flags & KMP_IDENT_KMPC ))) {
362  /* we are in ORDERED which is inside an ORDERED or CRITICAL construct */
363  __kmp_error_construct2(
364  kmp_i18n_msg_CnsInvalidNesting,
365  ct, ident,
366  & p->stack_data[ index ]
367  );
368  }
369  }
370  } else if ( ct == ct_critical ) {
371 #if KMP_USE_DYNAMIC_LOCK
372  if ( lck != NULL && __kmp_get_user_lock_owner( lck, seq ) == gtid ) { /* this same thread already has lock for this critical section */
373 #else
374  if ( lck != NULL && __kmp_get_user_lock_owner( lck ) == gtid ) { /* this same thread already has lock for this critical section */
375 #endif
376  int index = p->s_top;
377  struct cons_data cons = { NULL, ct_critical, 0, NULL };
378  /* walk up construct stack and try to find critical with matching name */
379  while ( index != 0 && p->stack_data[ index ].name != lck ) {
380  index = p->stack_data[ index ].prev;
381  }
382  if ( index != 0 ) {
383  /* found match on the stack (may not always because of interleaved critical for Fortran) */
384  cons = p->stack_data[ index ];
385  }
386  /* we are in CRITICAL which is inside a CRITICAL construct of the same name */
387  __kmp_error_construct2( kmp_i18n_msg_CnsNestingSameName, ct, ident, & cons );
388  }
389  } else if ( ct == ct_master || ct == ct_reduce ) {
390  if (p->w_top > p->p_top) {
391  /* inside a WORKSHARING construct for this PARALLEL region */
392  __kmp_error_construct2(
393  kmp_i18n_msg_CnsInvalidNesting,
394  ct, ident,
395  & p->stack_data[ p->w_top ]
396  );
397  }
398  if (ct == ct_reduce && p->s_top > p->p_top) {
399  /* inside a another SYNC construct for this PARALLEL region */
400  __kmp_error_construct2(
401  kmp_i18n_msg_CnsInvalidNesting,
402  ct, ident,
403  & p->stack_data[ p->s_top ]
404  );
405  }; // if
406  }; // if
407 }
408 
409 void
410 #if KMP_USE_DYNAMIC_LOCK
411 __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq )
412 #else
413 __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
414 #endif
415 {
416  int tos;
417  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
418 
419  KMP_ASSERT( gtid == __kmp_get_gtid() );
420  KE_TRACE( 10, ("__kmp_push_sync (gtid=%d)\n", gtid ) );
421 #if KMP_USE_DYNAMIC_LOCK
422  __kmp_check_sync( gtid, ct, ident, lck, seq );
423 #else
424  __kmp_check_sync( gtid, ct, ident, lck );
425 #endif
426  KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) );
427  tos = ++ p->stack_top;
428  p->stack_data[ tos ].type = ct;
429  p->stack_data[ tos ].prev = p->s_top;
430  p->stack_data[ tos ].ident = ident;
431  p->stack_data[ tos ].name = lck;
432  p->s_top = tos;
433  KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
434 }
435 
436 /* ------------------------------------------------------------------------ */
437 
438 void
439 __kmp_pop_parallel( int gtid, ident_t const * ident )
440 {
441  int tos;
442  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
443  tos = p->stack_top;
444  KE_TRACE( 10, ("__kmp_pop_parallel (%d %d)\n", gtid, __kmp_get_gtid() ) );
445  if ( tos == 0 || p->p_top == 0 ) {
446  __kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct_parallel, ident );
447  }
448  if ( tos != p->p_top || p->stack_data[ tos ].type != ct_parallel ) {
449  __kmp_error_construct2(
450  kmp_i18n_msg_CnsExpectedEnd,
451  ct_parallel, ident,
452  & p->stack_data[ tos ]
453  );
454  }
455  KE_TRACE( 100, ( POP_MSG( p ) ) );
456  p->p_top = p->stack_data[ tos ].prev;
457  p->stack_data[ tos ].type = ct_none;
458  p->stack_data[ tos ].ident = NULL;
459  p->stack_top = tos - 1;
460  KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
461 }
462 
463 enum cons_type
464 __kmp_pop_workshare( int gtid, enum cons_type ct, ident_t const * ident )
465 {
466  int tos;
467  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
468 
469  tos = p->stack_top;
470  KE_TRACE( 10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) );
471  if ( tos == 0 || p->w_top == 0 ) {
472  __kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct, ident );
473  }
474 
475  if ( tos != p->w_top ||
476  ( p->stack_data[ tos ].type != ct &&
477  /* below are two exceptions to the rule that construct types must match */
478  ! ( p->stack_data[ tos ].type == ct_pdo_ordered && ct == ct_pdo ) &&
479  ! ( p->stack_data[ tos ].type == ct_task_ordered && ct == ct_task )
480  )
481  ) {
482  __kmp_check_null_func();
483  __kmp_error_construct2(
484  kmp_i18n_msg_CnsExpectedEnd,
485  ct, ident,
486  & p->stack_data[ tos ]
487  );
488  }
489  KE_TRACE( 100, ( POP_MSG( p ) ) );
490  p->w_top = p->stack_data[ tos ].prev;
491  p->stack_data[ tos ].type = ct_none;
492  p->stack_data[ tos ].ident = NULL;
493  p->stack_top = tos - 1;
494  KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
495  return p->stack_data[ p->w_top ].type;
496 }
497 
498 void
499 __kmp_pop_sync( int gtid, enum cons_type ct, ident_t const * ident )
500 {
501  int tos;
502  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
503  tos = p->stack_top;
504  KE_TRACE( 10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid() ) );
505  if ( tos == 0 || p->s_top == 0 ) {
506  __kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct, ident );
507  };
508  if ( tos != p->s_top || p->stack_data[ tos ].type != ct ) {
509  __kmp_check_null_func();
510  __kmp_error_construct2(
511  kmp_i18n_msg_CnsExpectedEnd,
512  ct, ident,
513  & p->stack_data[ tos ]
514  );
515  };
516  if ( gtid < 0 ) {
517  __kmp_check_null_func();
518  };
519  KE_TRACE( 100, ( POP_MSG( p ) ) );
520  p->s_top = p->stack_data[ tos ].prev;
521  p->stack_data[ tos ].type = ct_none;
522  p->stack_data[ tos ].ident = NULL;
523  p->stack_top = tos - 1;
524  KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
525 }
526 
527 /* ------------------------------------------------------------------------ */
528 
529 void
530 __kmp_check_barrier( int gtid, enum cons_type ct, ident_t const * ident )
531 {
532  struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
533  KE_TRACE( 10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid, __kmp_get_gtid() ) );
534  if ( ident != 0 ) {
535  __kmp_check_null_func();
536  }
537  if ( p->w_top > p->p_top ) {
538  /* we are already in a WORKSHARING construct for this PARALLEL region */
539  __kmp_error_construct2(
540  kmp_i18n_msg_CnsInvalidNesting,
541  ct, ident,
542  & p->stack_data[ p->w_top ]
543  );
544  }
545  if (p->s_top > p->p_top) {
546  /* we are already in a SYNC construct for this PARALLEL region */
547  __kmp_error_construct2(
548  kmp_i18n_msg_CnsInvalidNesting,
549  ct, ident,
550  & p->stack_data[ p->s_top ]
551  );
552  }
553 }
554 
555 /* ------------------------------------------------------------------------ */
556 
557 
558 /* ------------------------------------------------------------------------ */
559 /* ------------------------------------------------------------------------ */
Definition: kmp.h:218
#define KMP_IDENT_KMPC
Definition: kmp.h:198
char const * psource
Definition: kmp.h:227