blob: 5dc792aee42d43a27d21e5f82c6641efc4853f20 [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001/*
2 * kmp_ftn_entry.h -- Fortran entry linkage support for OpenMP.
Jim Cownie181b4bb2013-12-23 17:28:57 +00003 * $Revision: 42798 $
4 * $Date: 2013-10-30 16:39:54 -0500 (Wed, 30 Oct 2013) $
Jim Cownie5e8470a2013-09-27 10:38:44 +00005 */
6
7
8//===----------------------------------------------------------------------===//
9//
10// The LLVM Compiler Infrastructure
11//
12// This file is dual licensed under the MIT and the University of Illinois Open
13// Source Licenses. See LICENSE.txt for details.
14//
15//===----------------------------------------------------------------------===//
16
17
18#ifndef FTN_STDCALL
19# error The support file kmp_ftn_entry.h should not be compiled by itself.
20#endif
21
22#ifdef KMP_STUB
23 #include "kmp_stub.h"
24#endif
25
26#include "kmp_i18n.h"
27
28#ifdef __cplusplus
29 extern "C" {
30#endif // __cplusplus
31
32/*
Alp Toker8f2d3f02014-02-24 10:40:15 +000033 * For compatibility with the Gnu/MS Open MP codegen, omp_set_num_threads(),
Jim Cownie5e8470a2013-09-27 10:38:44 +000034 * omp_set_nested(), and omp_set_dynamic() [in lowercase on MS, and w/o
35 * a trailing underscore on Linux* OS] take call by value integer arguments.
36 * + omp_set_max_active_levels()
37 * + omp_set_schedule()
38 *
Alp Toker8f2d3f02014-02-24 10:40:15 +000039 * For backward compatibility with 9.1 and previous Intel compiler, these
Jim Cownie5e8470a2013-09-27 10:38:44 +000040 * entry points take call by reference integer arguments.
41 */
42#ifdef KMP_GOMP_COMPAT
43# if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_UPPER)
44# define PASS_ARGS_BY_VALUE 1
45# endif
46#endif
47#if KMP_OS_WINDOWS
48# if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_APPEND)
49# define PASS_ARGS_BY_VALUE 1
50# endif
51#endif
52
53// This macro helps to reduce code duplication.
54#ifdef PASS_ARGS_BY_VALUE
55 #define KMP_DEREF
56#else
57 #define KMP_DEREF *
58#endif
59
60void FTN_STDCALL
61FTN_SET_STACKSIZE( int KMP_DEREF arg )
62{
63 #ifdef KMP_STUB
64 __kmps_set_stacksize( KMP_DEREF arg );
65 #else
66 // __kmp_aux_set_stacksize initializes the library if needed
67 __kmp_aux_set_stacksize( (size_t) KMP_DEREF arg );
68 #endif
69}
70
71void FTN_STDCALL
72FTN_SET_STACKSIZE_S( size_t KMP_DEREF arg )
73{
74 #ifdef KMP_STUB
75 __kmps_set_stacksize( KMP_DEREF arg );
76 #else
77 // __kmp_aux_set_stacksize initializes the library if needed
78 __kmp_aux_set_stacksize( KMP_DEREF arg );
79 #endif
80}
81
82int FTN_STDCALL
83FTN_GET_STACKSIZE( void )
84{
85 #ifdef KMP_STUB
86 return __kmps_get_stacksize();
87 #else
88 if ( ! __kmp_init_serial ) {
89 __kmp_serial_initialize();
90 };
91 return (int)__kmp_stksize;
92 #endif
93}
94
95size_t FTN_STDCALL
96FTN_GET_STACKSIZE_S( void )
97{
98 #ifdef KMP_STUB
99 return __kmps_get_stacksize();
100 #else
101 if ( ! __kmp_init_serial ) {
102 __kmp_serial_initialize();
103 };
104 return __kmp_stksize;
105 #endif
106}
107
108void FTN_STDCALL
109FTN_SET_BLOCKTIME( int KMP_DEREF arg )
110{
111 #ifdef KMP_STUB
112 __kmps_set_blocktime( KMP_DEREF arg );
113 #else
114 int gtid, tid;
115 kmp_info_t *thread;
116
117 gtid = __kmp_entry_gtid();
118 tid = __kmp_tid_from_gtid(gtid);
119 thread = __kmp_thread_from_gtid(gtid);
120
121 __kmp_aux_set_blocktime( KMP_DEREF arg, thread, tid );
122 #endif
123}
124
125int FTN_STDCALL
126FTN_GET_BLOCKTIME( void )
127{
128 #ifdef KMP_STUB
129 return __kmps_get_blocktime();
130 #else
131 int gtid, tid;
132 kmp_info_t *thread;
133 kmp_team_p *team;
134
135 gtid = __kmp_entry_gtid();
136 tid = __kmp_tid_from_gtid(gtid);
137 thread = __kmp_thread_from_gtid(gtid);
138 team = __kmp_threads[ gtid ] -> th.th_team;
139
140 /* These must match the settings used in __kmp_wait_sleep() */
141 if ( __kmp_dflt_blocktime == KMP_MAX_BLOCKTIME ) {
142 KF_TRACE(10, ( "kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n",
143 gtid, team->t.t_id, tid, KMP_MAX_BLOCKTIME) );
144 return KMP_MAX_BLOCKTIME;
145 }
146#ifdef KMP_ADJUST_BLOCKTIME
147 else if ( __kmp_zero_bt && !get__bt_set( team, tid ) ) {
148 KF_TRACE(10, ( "kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n",
149 gtid, team->t.t_id, tid, 0) );
150 return 0;
151 }
152#endif /* KMP_ADJUST_BLOCKTIME */
153 else {
154 KF_TRACE(10, ( "kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n",
155 gtid, team->t.t_id, tid, get__blocktime( team, tid ) ) );
156 return get__blocktime( team, tid );
157 };
158 #endif
159}
160
161void FTN_STDCALL
162FTN_SET_LIBRARY_SERIAL( void )
163{
164 #ifdef KMP_STUB
165 __kmps_set_library( library_serial );
166 #else
167 // __kmp_user_set_library initializes the library if needed
168 __kmp_user_set_library( library_serial );
169 #endif
170}
171
172void FTN_STDCALL
173FTN_SET_LIBRARY_TURNAROUND( void )
174{
175 #ifdef KMP_STUB
176 __kmps_set_library( library_turnaround );
177 #else
178 // __kmp_user_set_library initializes the library if needed
179 __kmp_user_set_library( library_turnaround );
180 #endif
181}
182
183void FTN_STDCALL
184FTN_SET_LIBRARY_THROUGHPUT( void )
185{
186 #ifdef KMP_STUB
187 __kmps_set_library( library_throughput );
188 #else
189 // __kmp_user_set_library initializes the library if needed
190 __kmp_user_set_library( library_throughput );
191 #endif
192}
193
194void FTN_STDCALL
195FTN_SET_LIBRARY( int KMP_DEREF arg )
196{
197 #ifdef KMP_STUB
198 __kmps_set_library( KMP_DEREF arg );
199 #else
200 enum library_type lib;
201 lib = (enum library_type) KMP_DEREF arg;
202 // __kmp_user_set_library initializes the library if needed
203 __kmp_user_set_library( lib );
204 #endif
205}
206
207int FTN_STDCALL
208FTN_GET_LIBRARY (void)
209{
210 #ifdef KMP_STUB
211 return __kmps_get_library();
212 #else
213 if ( ! __kmp_init_serial ) {
214 __kmp_serial_initialize();
215 }
216 return ((int) __kmp_library);
217 #endif
218}
219
220#if OMP_30_ENABLED
221
222int FTN_STDCALL
223FTN_SET_AFFINITY( void **mask )
224{
225 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
226 return -1;
227 #else
228 if ( ! TCR_4(__kmp_init_middle) ) {
229 __kmp_middle_initialize();
230 }
231 return __kmp_aux_set_affinity( mask );
232 #endif
233}
234
235int FTN_STDCALL
236FTN_GET_AFFINITY( void **mask )
237{
238 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
239 return -1;
240 #else
241 if ( ! TCR_4(__kmp_init_middle) ) {
242 __kmp_middle_initialize();
243 }
244 return __kmp_aux_get_affinity( mask );
245 #endif
246}
247
248int FTN_STDCALL
249FTN_GET_AFFINITY_MAX_PROC( void )
250{
251 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
252 return 0;
253 #else
254 //
255 // We really only NEED serial initialization here.
256 //
257 if ( ! TCR_4(__kmp_init_middle) ) {
258 __kmp_middle_initialize();
259 }
260 if ( ! ( KMP_AFFINITY_CAPABLE() ) ) {
261 return 0;
262 }
263
264 #if KMP_OS_WINDOWS && KMP_ARCH_X86_64
265 if ( __kmp_num_proc_groups <= 1 ) {
266 return KMP_CPU_SETSIZE;
267 }
268 #endif /* KMP_OS_WINDOWS && KMP_ARCH_X86_64 */
269 return __kmp_xproc;
270 #endif
271}
272
273void FTN_STDCALL
274FTN_CREATE_AFFINITY_MASK( void **mask )
275{
276 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
277 *mask = NULL;
278 #else
279 //
280 // We really only NEED serial initialization here.
281 //
282 if ( ! TCR_4(__kmp_init_middle) ) {
283 __kmp_middle_initialize();
284 }
285 *mask = kmpc_malloc( __kmp_affin_mask_size );
286 KMP_CPU_ZERO( (kmp_affin_mask_t *)(*mask) );
287 #endif
288}
289
290void FTN_STDCALL
291FTN_DESTROY_AFFINITY_MASK( void **mask )
292{
293 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
294 // Nothing
295 #else
296 //
297 // We really only NEED serial initialization here.
298 //
299 if ( ! TCR_4(__kmp_init_middle) ) {
300 __kmp_middle_initialize();
301 }
302 if ( __kmp_env_consistency_check ) {
303 if ( *mask == NULL ) {
304 KMP_FATAL( AffinityInvalidMask, "kmp_destroy_affinity_mask" );
305 }
306 }
307 kmpc_free( *mask );
308 *mask = NULL;
309 #endif
310}
311
312int FTN_STDCALL
313FTN_SET_AFFINITY_MASK_PROC( int KMP_DEREF proc, void **mask )
314{
315 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
316 return -1;
317 #else
318 if ( ! TCR_4(__kmp_init_middle) ) {
319 __kmp_middle_initialize();
320 }
321 return __kmp_aux_set_affinity_mask_proc( KMP_DEREF proc, mask );
322 #endif
323}
324
325int FTN_STDCALL
326FTN_UNSET_AFFINITY_MASK_PROC( int KMP_DEREF proc, void **mask )
327{
328 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
329 return -1;
330 #else
331 if ( ! TCR_4(__kmp_init_middle) ) {
332 __kmp_middle_initialize();
333 }
334 return __kmp_aux_unset_affinity_mask_proc( KMP_DEREF proc, mask );
335 #endif
336}
337
338int FTN_STDCALL
339FTN_GET_AFFINITY_MASK_PROC( int KMP_DEREF proc, void **mask )
340{
341 #if defined(KMP_STUB) || !(KMP_OS_WINDOWS || KMP_OS_LINUX)
342 return -1;
343 #else
344 if ( ! TCR_4(__kmp_init_middle) ) {
345 __kmp_middle_initialize();
346 }
347 return __kmp_aux_get_affinity_mask_proc( KMP_DEREF proc, mask );
348 #endif
349}
350
351#endif /* OMP_30_ENABLED */
352
353
354/* ------------------------------------------------------------------------ */
355
356/* sets the requested number of threads for the next parallel region */
357
358void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000359xexpand(FTN_SET_NUM_THREADS)( int KMP_DEREF arg )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000360{
361 #ifdef KMP_STUB
362 // Nothing.
363 #else
364 __kmp_set_num_threads( KMP_DEREF arg, __kmp_entry_gtid() );
365 #endif
366}
367
368
369/* returns the number of threads in current team */
370int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000371xexpand(FTN_GET_NUM_THREADS)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000372{
373 #ifdef KMP_STUB
374 return 1;
375 #else
376 // __kmpc_bound_num_threads initializes the library if needed
377 return __kmpc_bound_num_threads(NULL);
378 #endif
379}
380
381int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000382xexpand(FTN_GET_MAX_THREADS)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000383{
384 #ifdef KMP_STUB
385 return 1;
386 #else
387 int gtid;
388 kmp_info_t *thread;
389 if ( ! TCR_4(__kmp_init_middle) ) {
390 __kmp_middle_initialize();
391 }
392 gtid = __kmp_entry_gtid();
393 thread = __kmp_threads[ gtid ];
394 #if OMP_30_ENABLED
395 //return thread -> th.th_team -> t.t_current_task[ thread->th.th_info.ds.ds_tid ] -> icvs.nproc;
396 return thread -> th.th_current_task -> td_icvs.nproc;
397 #else
398 return thread -> th.th_team -> t.t_set_nproc[ thread->th.th_info.ds.ds_tid ];
399 #endif
400 #endif
401}
402
403int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000404xexpand(FTN_GET_THREAD_NUM)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000405{
406 #ifdef KMP_STUB
407 return 0;
408 #else
409 int gtid;
410
411 #if KMP_OS_DARWIN
412 gtid = __kmp_entry_gtid();
413 #elif KMP_OS_WINDOWS
414 if (!__kmp_init_parallel ||
415 (gtid = ((kmp_intptr_t)TlsGetValue( __kmp_gtid_threadprivate_key ))) == 0) {
416 // Either library isn't initialized or thread is not registered
417 // 0 is the correct TID in this case
418 return 0;
419 }
420 --gtid; // We keep (gtid+1) in TLS
421 #elif KMP_OS_LINUX
422 #ifdef KMP_TDATA_GTID
423 if ( __kmp_gtid_mode >= 3 ) {
424 if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {
425 return 0;
426 }
427 } else {
428 #endif
429 if (!__kmp_init_parallel ||
430 (gtid = (kmp_intptr_t)(pthread_getspecific( __kmp_gtid_threadprivate_key ))) == 0) {
431 return 0;
432 }
433 --gtid;
434 #ifdef KMP_TDATA_GTID
435 }
436 #endif
437 #else
438 #error Unknown or unsupported OS
439 #endif
440
441 return __kmp_tid_from_gtid( gtid );
442 #endif
443}
444
445int FTN_STDCALL
446FTN_GET_NUM_KNOWN_THREADS( void )
447{
448 #ifdef KMP_STUB
449 return 1;
450 #else
451 if ( ! __kmp_init_serial ) {
452 __kmp_serial_initialize();
453 }
454 /* NOTE: this is not syncronized, so it can change at any moment */
455 /* NOTE: this number also includes threads preallocated in hot-teams */
456 return TCR_4(__kmp_nth);
457 #endif
458}
459
460int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000461xexpand(FTN_GET_NUM_PROCS)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000462{
463 #ifdef KMP_STUB
464 return 1;
465 #else
466 int gtid;
467 if ( ! TCR_4(__kmp_init_middle) ) {
468 __kmp_middle_initialize();
469 }
470 return __kmp_avail_proc;
471 #endif
472}
473
474void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000475xexpand(FTN_SET_NESTED)( int KMP_DEREF flag )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000476{
477 #ifdef KMP_STUB
478 __kmps_set_nested( KMP_DEREF flag );
479 #else
480 kmp_info_t *thread;
481 /* For the thread-private internal controls implementation */
482 thread = __kmp_entry_thread();
483 __kmp_save_internal_controls( thread );
484 set__nested( thread, ( (KMP_DEREF flag) ? TRUE : FALSE ) );
485 #endif
486}
487
488
489int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000490xexpand(FTN_GET_NESTED)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000491{
492 #ifdef KMP_STUB
493 return __kmps_get_nested();
494 #else
495 kmp_info_t *thread;
496 thread = __kmp_entry_thread();
497 return get__nested( thread );
498 #endif
499}
500
501void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000502xexpand(FTN_SET_DYNAMIC)( int KMP_DEREF flag )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000503{
504 #ifdef KMP_STUB
505 __kmps_set_dynamic( KMP_DEREF flag ? TRUE : FALSE );
506 #else
507 kmp_info_t *thread;
508 /* For the thread-private implementation of the internal controls */
509 thread = __kmp_entry_thread();
510 // !!! What if foreign thread calls it?
511 __kmp_save_internal_controls( thread );
512 set__dynamic( thread, KMP_DEREF flag ? TRUE : FALSE );
513 #endif
514}
515
516
517int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000518xexpand(FTN_GET_DYNAMIC)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000519{
520 #ifdef KMP_STUB
521 return __kmps_get_dynamic();
522 #else
523 kmp_info_t *thread;
524 thread = __kmp_entry_thread();
525 return get__dynamic( thread );
526 #endif
527}
528
529int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000530xexpand(FTN_IN_PARALLEL)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000531{
532 #ifdef KMP_STUB
533 return 0;
534 #else
535 kmp_info_t *th = __kmp_entry_thread();
536#if OMP_40_ENABLED
537 if ( th->th.th_team_microtask ) {
538 // AC: r_in_parallel does not work inside teams construct
539 // where real parallel is inactive, but all threads have same root,
540 // so setting it in one team affects other teams.
541 // The solution is to use per-team nesting level
542 return ( th->th.th_team->t.t_active_level ? 1 : 0 );
543 }
544 else
545#endif /* OMP_40_ENABLED */
546 return ( th->th.th_root->r.r_in_parallel ? FTN_TRUE : FTN_FALSE );
547 #endif
548}
549
550#if OMP_30_ENABLED
551
552void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000553xexpand(FTN_SET_SCHEDULE)( kmp_sched_t KMP_DEREF kind, int KMP_DEREF modifier )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000554{
555 #ifdef KMP_STUB
556 __kmps_set_schedule( KMP_DEREF kind, KMP_DEREF modifier );
557 #else
558 /* TO DO */
559 /* For the per-task implementation of the internal controls */
560 __kmp_set_schedule( __kmp_entry_gtid(), KMP_DEREF kind, KMP_DEREF modifier );
561 #endif
562}
563
564void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000565xexpand(FTN_GET_SCHEDULE)( kmp_sched_t * kind, int * modifier )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000566{
567 #ifdef KMP_STUB
568 __kmps_get_schedule( kind, modifier );
569 #else
570 /* TO DO */
571 /* For the per-task implementation of the internal controls */
572 __kmp_get_schedule( __kmp_entry_gtid(), kind, modifier );
573 #endif
574}
575
576void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000577xexpand(FTN_SET_MAX_ACTIVE_LEVELS)( int KMP_DEREF arg )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000578{
579 #ifdef KMP_STUB
580 // Nothing.
581 #else
582 /* TO DO */
583 /* We want per-task implementation of this internal control */
584 __kmp_set_max_active_levels( __kmp_entry_gtid(), KMP_DEREF arg );
585 #endif
586}
587
588int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000589xexpand(FTN_GET_MAX_ACTIVE_LEVELS)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000590{
591 #ifdef KMP_STUB
592 return 0;
593 #else
594 /* TO DO */
595 /* We want per-task implementation of this internal control */
596 return __kmp_get_max_active_levels( __kmp_entry_gtid() );
597 #endif
598}
599
600int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000601xexpand(FTN_GET_ACTIVE_LEVEL)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000602{
603 #ifdef KMP_STUB
604 return 0; // returns 0 if it is called from the sequential part of the program
605 #else
606 /* TO DO */
607 /* For the per-task implementation of the internal controls */
608 return __kmp_entry_thread() -> th.th_team -> t.t_active_level;
609 #endif
610}
611
612int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000613xexpand(FTN_GET_LEVEL)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000614{
615 #ifdef KMP_STUB
616 return 0; // returns 0 if it is called from the sequential part of the program
617 #else
618 /* TO DO */
619 /* For the per-task implementation of the internal controls */
620 return __kmp_entry_thread() -> th.th_team -> t.t_level;
621 #endif
622}
623
624int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000625xexpand(FTN_GET_ANCESTOR_THREAD_NUM)( int KMP_DEREF level )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000626{
627 #ifdef KMP_STUB
628 return ( KMP_DEREF level ) ? ( -1 ) : ( 0 );
629 #else
630 return __kmp_get_ancestor_thread_num( __kmp_entry_gtid(), KMP_DEREF level );
631 #endif
632}
633
634int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000635xexpand(FTN_GET_TEAM_SIZE)( int KMP_DEREF level )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000636{
637 #ifdef KMP_STUB
638 return ( KMP_DEREF level ) ? ( -1 ) : ( 1 );
639 #else
640 return __kmp_get_team_size( __kmp_entry_gtid(), KMP_DEREF level );
641 #endif
642}
643
644int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000645xexpand(FTN_GET_THREAD_LIMIT)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000646{
647 #ifdef KMP_STUB
648 return 1; // TO DO: clarify whether it returns 1 or 0?
649 #else
650 if ( ! __kmp_init_serial ) {
651 __kmp_serial_initialize();
652 };
653 /* global ICV */
654 return __kmp_max_nth;
655 #endif
656}
657
658int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000659xexpand(FTN_IN_FINAL)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000660{
661 #ifdef KMP_STUB
662 return 0; // TO DO: clarify whether it returns 1 or 0?
663 #else
664 if ( ! TCR_4(__kmp_init_parallel) ) {
665 return 0;
666 }
667 return __kmp_entry_thread() -> th.th_current_task -> td_flags.final;
668 #endif
669}
670
671#endif // OMP_30_ENABLED
672
673#if OMP_40_ENABLED
674
675
676kmp_proc_bind_t FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000677xexpand(FTN_GET_PROC_BIND)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000678{
679 #ifdef KMP_STUB
680 return __kmps_get_proc_bind();
681 #else
682 return get__proc_bind( __kmp_entry_thread() );
683 #endif
684}
685
686int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000687xexpand(FTN_GET_NUM_TEAMS)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000688{
689 #ifdef KMP_STUB
690 return 1;
691 #else
692 kmp_info_t *thr = __kmp_entry_thread();
693 if ( thr->th.th_team_microtask ) {
694 kmp_team_t *team = thr->th.th_team;
695 int tlevel = thr->th.th_teams_level;
696 int ii = team->t.t_level; // the level of the teams construct
697 int dd = team -> t.t_serialized;
698 int level = tlevel + 1;
699 KMP_DEBUG_ASSERT( ii >= tlevel );
700 while( ii > level )
701 {
702 for( dd = team -> t.t_serialized; ( dd > 0 ) && ( ii > level ); dd--, ii-- )
703 {
704 }
705 if( team -> t.t_serialized && ( !dd ) ) {
706 team = team->t.t_parent;
707 continue;
708 }
709 if( ii > level ) {
710 team = team->t.t_parent;
711 ii--;
712 }
713 }
714 if ( dd > 1 ) {
715 return 1; // teams region is serialized ( 1 team of 1 thread ).
716 } else {
717 return team->t.t_parent->t.t_nproc;
718 }
719 } else {
720 return 1;
721 }
722 #endif
723}
724
725int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000726xexpand(FTN_GET_TEAM_NUM)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000727{
728 #ifdef KMP_STUB
729 return 0;
730 #else
731 kmp_info_t *thr = __kmp_entry_thread();
732 if ( thr->th.th_team_microtask ) {
733 kmp_team_t *team = thr->th.th_team;
734 int tlevel = thr->th.th_teams_level; // the level of the teams construct
735 int ii = team->t.t_level;
736 int dd = team -> t.t_serialized;
737 int level = tlevel + 1;
738 KMP_DEBUG_ASSERT( ii >= tlevel );
739 while( ii > level )
740 {
741 for( dd = team -> t.t_serialized; ( dd > 0 ) && ( ii > level ); dd--, ii-- )
742 {
743 }
744 if( team -> t.t_serialized && ( !dd ) ) {
745 team = team->t.t_parent;
746 continue;
747 }
748 if( ii > level ) {
749 team = team->t.t_parent;
750 ii--;
751 }
752 }
753 if ( dd > 1 ) {
754 return 0; // teams region is serialized ( 1 team of 1 thread ).
755 } else {
756 return team->t.t_master_tid;
757 }
758 } else {
759 return 0;
760 }
761 #endif
762}
763
764#if KMP_MIC || KMP_OS_DARWIN
765
766static int __kmp_default_device = 0;
767
768int FTN_STDCALL
769FTN_GET_DEFAULT_DEVICE( void )
770{
771 return __kmp_default_device;
772}
773
774void FTN_STDCALL
775FTN_SET_DEFAULT_DEVICE( int KMP_DEREF arg )
776{
777 __kmp_default_device = KMP_DEREF arg;
778}
779
780int FTN_STDCALL
781FTN_GET_NUM_DEVICES( void )
782{
783 return 0;
784}
785
786#endif // KMP_MIC || KMP_OS_DARWIN
787
788#endif // OMP_40_ENABLED
789
790#ifdef KMP_STUB
791typedef enum { UNINIT = -1, UNLOCKED, LOCKED } kmp_stub_lock_t;
792#endif /* KMP_STUB */
793
794/* initialize the lock */
795void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000796xexpand(FTN_INIT_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000797{
798 #ifdef KMP_STUB
799 *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
800 #else
801 __kmpc_init_lock( NULL, __kmp_entry_gtid(), user_lock );
802 #endif
803}
804
805/* initialize the lock */
806void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000807xexpand(FTN_INIT_NEST_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000808{
809 #ifdef KMP_STUB
810 *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
811 #else
812 __kmpc_init_nest_lock( NULL, __kmp_entry_gtid(), user_lock );
813 #endif
814}
815
816void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000817xexpand(FTN_DESTROY_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000818{
819 #ifdef KMP_STUB
820 *((kmp_stub_lock_t *)user_lock) = UNINIT;
821 #else
822 __kmpc_destroy_lock( NULL, __kmp_entry_gtid(), user_lock );
823 #endif
824}
825
826void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000827xexpand(FTN_DESTROY_NEST_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000828{
829 #ifdef KMP_STUB
830 *((kmp_stub_lock_t *)user_lock) = UNINIT;
831 #else
832 __kmpc_destroy_nest_lock( NULL, __kmp_entry_gtid(), user_lock );
833 #endif
834}
835
836void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000837xexpand(FTN_SET_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000838{
839 #ifdef KMP_STUB
840 if ( *((kmp_stub_lock_t *)user_lock) == UNINIT ) {
841 // TODO: Issue an error.
842 }; // if
843 if ( *((kmp_stub_lock_t *)user_lock) != UNLOCKED ) {
844 // TODO: Issue an error.
845 }; // if
846 *((kmp_stub_lock_t *)user_lock) = LOCKED;
847 #else
848 __kmpc_set_lock( NULL, __kmp_entry_gtid(), user_lock );
849 #endif
850}
851
852void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000853xexpand(FTN_SET_NEST_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000854{
855 #ifdef KMP_STUB
856 if ( *((kmp_stub_lock_t *)user_lock) == UNINIT ) {
857 // TODO: Issue an error.
858 }; // if
859 (*((int *)user_lock))++;
860 #else
861 __kmpc_set_nest_lock( NULL, __kmp_entry_gtid(), user_lock );
862 #endif
863}
864
865void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000866xexpand(FTN_UNSET_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000867{
868 #ifdef KMP_STUB
869 if ( *((kmp_stub_lock_t *)user_lock) == UNINIT ) {
870 // TODO: Issue an error.
871 }; // if
872 if ( *((kmp_stub_lock_t *)user_lock) == UNLOCKED ) {
873 // TODO: Issue an error.
874 }; // if
875 *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
876 #else
877 __kmpc_unset_lock( NULL, __kmp_entry_gtid(), user_lock );
878 #endif
879}
880
881void FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000882xexpand(FTN_UNSET_NEST_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000883{
884 #ifdef KMP_STUB
885 if ( *((kmp_stub_lock_t *)user_lock) == UNINIT ) {
886 // TODO: Issue an error.
887 }; // if
888 if ( *((kmp_stub_lock_t *)user_lock) == UNLOCKED ) {
889 // TODO: Issue an error.
890 }; // if
891 (*((int *)user_lock))--;
892 #else
893 __kmpc_unset_nest_lock( NULL, __kmp_entry_gtid(), user_lock );
894 #endif
895}
896
897int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000898xexpand(FTN_TEST_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000899{
900 #ifdef KMP_STUB
901 if ( *((kmp_stub_lock_t *)user_lock) == UNINIT ) {
902 // TODO: Issue an error.
903 }; // if
904 if ( *((kmp_stub_lock_t *)user_lock) == LOCKED ) {
905 return 0;
906 }; // if
907 *((kmp_stub_lock_t *)user_lock) = LOCKED;
908 return 1;
909 #else
910 return __kmpc_test_lock( NULL, __kmp_entry_gtid(), user_lock );
911 #endif
912}
913
914int FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000915xexpand(FTN_TEST_NEST_LOCK)( void **user_lock )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000916{
917 #ifdef KMP_STUB
918 if ( *((kmp_stub_lock_t *)user_lock) == UNINIT ) {
919 // TODO: Issue an error.
920 }; // if
921 return ++(*((int *)user_lock));
922 #else
923 return __kmpc_test_nest_lock( NULL, __kmp_entry_gtid(), user_lock );
924 #endif
925}
926
927double FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000928xexpand(FTN_GET_WTIME)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000929{
930 #ifdef KMP_STUB
931 return __kmps_get_wtime();
932 #else
933 double data;
934 #if ! KMP_OS_LINUX
935 // We don't need library initialization to get the time on Linux* OS.
936 // The routine can be used to measure library initialization time on Linux* OS now.
937 if ( ! __kmp_init_serial ) {
938 __kmp_serial_initialize();
939 };
940 #endif
941 __kmp_elapsed( & data );
942 return data;
943 #endif
944}
945
946double FTN_STDCALL
Jim Cownie181b4bb2013-12-23 17:28:57 +0000947xexpand(FTN_GET_WTICK)( void )
Jim Cownie5e8470a2013-09-27 10:38:44 +0000948{
949 #ifdef KMP_STUB
950 return __kmps_get_wtick();
951 #else
952 double data;
953 if ( ! __kmp_init_serial ) {
954 __kmp_serial_initialize();
955 };
956 __kmp_elapsed_tick( & data );
957 return data;
958 #endif
959}
960
961/* ------------------------------------------------------------------------ */
962
963void * FTN_STDCALL
964FTN_MALLOC( size_t KMP_DEREF size )
965{
966 // kmpc_malloc initializes the library if needed
967 return kmpc_malloc( KMP_DEREF size );
968}
969
970void * FTN_STDCALL
971FTN_CALLOC( size_t KMP_DEREF nelem, size_t KMP_DEREF elsize )
972{
973 // kmpc_calloc initializes the library if needed
974 return kmpc_calloc( KMP_DEREF nelem, KMP_DEREF elsize );
975}
976
977void * FTN_STDCALL
978FTN_REALLOC( void * KMP_DEREF ptr, size_t KMP_DEREF size )
979{
980 // kmpc_realloc initializes the library if needed
981 return kmpc_realloc( KMP_DEREF ptr, KMP_DEREF size );
982}
983
984void FTN_STDCALL
985FTN_FREE( void * KMP_DEREF ptr )
986{
987 // does nothing if the library is not initialized
988 kmpc_free( KMP_DEREF ptr );
989}
990
991void FTN_STDCALL
992FTN_SET_WARNINGS_ON( void )
993{
994 #ifndef KMP_STUB
995 __kmp_generate_warnings = kmp_warnings_explicit;
996 #endif
997}
998
999void FTN_STDCALL
1000FTN_SET_WARNINGS_OFF( void )
1001{
1002 #ifndef KMP_STUB
1003 __kmp_generate_warnings = FALSE;
1004 #endif
1005}
1006
1007void FTN_STDCALL
1008FTN_SET_DEFAULTS( char const * str
1009 #ifndef PASS_ARGS_BY_VALUE
1010 , int len
1011 #endif
1012)
1013{
1014 #ifndef KMP_STUB
1015 #ifdef PASS_ARGS_BY_VALUE
1016 int len = strlen( str );
1017 #endif
1018 __kmp_aux_set_defaults( str, len );
1019 #endif
1020}
1021
1022/* ------------------------------------------------------------------------ */
1023
1024
Jim Cownie181b4bb2013-12-23 17:28:57 +00001025#if OMP_40_ENABLED
1026/* returns the status of cancellation */
1027int FTN_STDCALL
1028xexpand(FTN_GET_CANCELLATION)(void) {
1029#ifdef KMP_STUB
1030 return 0 /* false */;
1031#else
1032 // initialize the library if needed
1033 if ( ! __kmp_init_serial ) {
1034 __kmp_serial_initialize();
1035 }
1036 return __kmp_omp_cancellation;
1037#endif
1038}
1039
1040int FTN_STDCALL
1041FTN_GET_CANCELLATION_STATUS(int cancel_kind) {
1042#ifdef KMP_STUB
1043 return 0 /* false */;
1044#else
1045 return __kmp_get_cancellation_status(cancel_kind);
1046#endif
1047}
1048
1049#endif // OMP_40_ENABLED
1050
1051// GCC compatibility (versioned symbols)
1052#if KMP_OS_LINUX
1053
1054/*
1055 These following sections create function aliases (dummy symbols) for the omp_* routines.
1056 These aliases will then be versioned according to how libgomp ``versions'' its
1057 symbols (OMP_1.0, OMP_2.0, OMP_3.0, ...) while also retaining the
1058 default version which libiomp5 uses: VERSION (defined in exports_so.txt)
1059 If you want to see the versioned symbols for libgomp.so.1 then just type:
1060
1061 objdump -T /path/to/libgomp.so.1 | grep omp_
1062
1063 Example:
1064 Step 1) Create __kmp_api_omp_set_num_threads_10_alias
1065 which is alias of __kmp_api_omp_set_num_threads
1066 Step 2) Set __kmp_api_omp_set_num_threads_10_alias to version: omp_set_num_threads@OMP_1.0
1067 Step 2B) Set __kmp_api_omp_set_num_threads to default version : omp_set_num_threads@@VERSION
1068*/
1069
1070// OMP_1.0 aliases
1071xaliasify(FTN_SET_NUM_THREADS, 10);
1072xaliasify(FTN_GET_NUM_THREADS, 10);
1073xaliasify(FTN_GET_MAX_THREADS, 10);
1074xaliasify(FTN_GET_THREAD_NUM, 10);
1075xaliasify(FTN_GET_NUM_PROCS, 10);
1076xaliasify(FTN_IN_PARALLEL, 10);
1077xaliasify(FTN_SET_DYNAMIC, 10);
1078xaliasify(FTN_GET_DYNAMIC, 10);
1079xaliasify(FTN_SET_NESTED, 10);
1080xaliasify(FTN_GET_NESTED, 10);
1081xaliasify(FTN_INIT_LOCK, 10);
1082xaliasify(FTN_INIT_NEST_LOCK, 10);
1083xaliasify(FTN_DESTROY_LOCK, 10);
1084xaliasify(FTN_DESTROY_NEST_LOCK, 10);
1085xaliasify(FTN_SET_LOCK, 10);
1086xaliasify(FTN_SET_NEST_LOCK, 10);
1087xaliasify(FTN_UNSET_LOCK, 10);
1088xaliasify(FTN_UNSET_NEST_LOCK, 10);
1089xaliasify(FTN_TEST_LOCK, 10);
1090xaliasify(FTN_TEST_NEST_LOCK, 10);
1091
1092// OMP_2.0 aliases
1093xaliasify(FTN_GET_WTICK, 20);
1094xaliasify(FTN_GET_WTIME, 20);
1095
1096#if OMP_30_ENABLED
1097// OMP_3.0 aliases
1098xaliasify(FTN_SET_SCHEDULE, 30);
1099xaliasify(FTN_GET_SCHEDULE, 30);
1100xaliasify(FTN_GET_THREAD_LIMIT, 30);
1101xaliasify(FTN_SET_MAX_ACTIVE_LEVELS, 30);
1102xaliasify(FTN_GET_MAX_ACTIVE_LEVELS, 30);
1103xaliasify(FTN_GET_LEVEL, 30);
1104xaliasify(FTN_GET_ANCESTOR_THREAD_NUM, 30);
1105xaliasify(FTN_GET_TEAM_SIZE, 30);
1106xaliasify(FTN_GET_ACTIVE_LEVEL, 30);
1107xaliasify(FTN_INIT_LOCK, 30);
1108xaliasify(FTN_INIT_NEST_LOCK, 30);
1109xaliasify(FTN_DESTROY_LOCK, 30);
1110xaliasify(FTN_DESTROY_NEST_LOCK, 30);
1111xaliasify(FTN_SET_LOCK, 30);
1112xaliasify(FTN_SET_NEST_LOCK, 30);
1113xaliasify(FTN_UNSET_LOCK, 30);
1114xaliasify(FTN_UNSET_NEST_LOCK, 30);
1115xaliasify(FTN_TEST_LOCK, 30);
1116xaliasify(FTN_TEST_NEST_LOCK, 30);
1117
1118// OMP_3.1 aliases
1119xaliasify(FTN_IN_FINAL, 31);
1120#endif /* OMP_30_ENABLED */
1121
1122#if OMP_40_ENABLED
1123// OMP_4.0 aliases
1124xaliasify(FTN_GET_PROC_BIND, 40);
1125xaliasify(FTN_GET_NUM_TEAMS, 40);
1126xaliasify(FTN_GET_TEAM_NUM, 40);
1127xaliasify(FTN_GET_CANCELLATION, 40);
1128#endif /* OMP_40_ENABLED */
1129
1130#if OMP_41_ENABLED
1131// OMP_4.1 aliases
1132#endif
1133
1134#if OMP_50_ENABLED
1135// OMP_5.0 aliases
1136#endif
1137
1138// OMP_1.0 versioned symbols
1139xversionify(FTN_SET_NUM_THREADS, 10, "OMP_1.0");
1140xversionify(FTN_GET_NUM_THREADS, 10, "OMP_1.0");
1141xversionify(FTN_GET_MAX_THREADS, 10, "OMP_1.0");
1142xversionify(FTN_GET_THREAD_NUM, 10, "OMP_1.0");
1143xversionify(FTN_GET_NUM_PROCS, 10, "OMP_1.0");
1144xversionify(FTN_IN_PARALLEL, 10, "OMP_1.0");
1145xversionify(FTN_SET_DYNAMIC, 10, "OMP_1.0");
1146xversionify(FTN_GET_DYNAMIC, 10, "OMP_1.0");
1147xversionify(FTN_SET_NESTED, 10, "OMP_1.0");
1148xversionify(FTN_GET_NESTED, 10, "OMP_1.0");
1149xversionify(FTN_INIT_LOCK, 10, "OMP_1.0");
1150xversionify(FTN_INIT_NEST_LOCK, 10, "OMP_1.0");
1151xversionify(FTN_DESTROY_LOCK, 10, "OMP_1.0");
1152xversionify(FTN_DESTROY_NEST_LOCK, 10, "OMP_1.0");
1153xversionify(FTN_SET_LOCK, 10, "OMP_1.0");
1154xversionify(FTN_SET_NEST_LOCK, 10, "OMP_1.0");
1155xversionify(FTN_UNSET_LOCK, 10, "OMP_1.0");
1156xversionify(FTN_UNSET_NEST_LOCK, 10, "OMP_1.0");
1157xversionify(FTN_TEST_LOCK, 10, "OMP_1.0");
1158xversionify(FTN_TEST_NEST_LOCK, 10, "OMP_1.0");
1159
1160// OMP_2.0 versioned symbols
1161xversionify(FTN_GET_WTICK, 20, "OMP_2.0");
1162xversionify(FTN_GET_WTIME, 20, "OMP_2.0");
1163
1164#if OMP_30_ENABLED
1165// OMP_3.0 versioned symbols
1166xversionify(FTN_SET_SCHEDULE, 30, "OMP_3.0");
1167xversionify(FTN_GET_SCHEDULE, 30, "OMP_3.0");
1168xversionify(FTN_GET_THREAD_LIMIT, 30, "OMP_3.0");
1169xversionify(FTN_SET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
1170xversionify(FTN_GET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
1171xversionify(FTN_GET_ANCESTOR_THREAD_NUM, 30, "OMP_3.0");
1172xversionify(FTN_GET_LEVEL, 30, "OMP_3.0");
1173xversionify(FTN_GET_TEAM_SIZE, 30, "OMP_3.0");
1174xversionify(FTN_GET_ACTIVE_LEVEL, 30, "OMP_3.0");
1175
1176// the lock routines have a 1.0 and 3.0 version
1177xversionify(FTN_INIT_LOCK, 30, "OMP_3.0");
1178xversionify(FTN_INIT_NEST_LOCK, 30, "OMP_3.0");
1179xversionify(FTN_DESTROY_LOCK, 30, "OMP_3.0");
1180xversionify(FTN_DESTROY_NEST_LOCK, 30, "OMP_3.0");
1181xversionify(FTN_SET_LOCK, 30, "OMP_3.0");
1182xversionify(FTN_SET_NEST_LOCK, 30, "OMP_3.0");
1183xversionify(FTN_UNSET_LOCK, 30, "OMP_3.0");
1184xversionify(FTN_UNSET_NEST_LOCK, 30, "OMP_3.0");
1185xversionify(FTN_TEST_LOCK, 30, "OMP_3.0");
1186xversionify(FTN_TEST_NEST_LOCK, 30, "OMP_3.0");
1187
1188// OMP_3.1 versioned symbol
1189xversionify(FTN_IN_FINAL, 31, "OMP_3.1");
1190#endif /* OMP_30_ENABLED */
1191
1192#if OMP_40_ENABLED
1193// OMP_4.0 versioned symbols
1194xversionify(FTN_GET_PROC_BIND, 40, "OMP_4.0");
1195xversionify(FTN_GET_NUM_TEAMS, 40, "OMP_4.0");
1196xversionify(FTN_GET_TEAM_NUM, 40, "OMP_4.0");
1197xversionify(FTN_GET_CANCELLATION, 40, "OMP_4.0");
1198#endif /* OMP_40_ENABLED */
1199
1200#if OMP_41_ENABLED
1201// OMP_4.1 versioned symbols
1202#endif
1203
1204#if OMP_50_ENABLED
1205// OMP_5.0 versioned symbols
1206#endif
1207
1208#endif /* KMP_OS_LINUX */
1209
Jim Cownie5e8470a2013-09-27 10:38:44 +00001210#ifdef __cplusplus
1211 } //extern "C"
1212#endif // __cplusplus
1213
1214// end of file //