1 // RUN: %libomp-compile-and-run
2 // RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run
5 #include "omp_my_sleep.h"
16 // Compiler-generated code (emulation)
17 typedef struct ident
{
29 int(* routine
)(int,struct task
*);
32 unsigned long long lb
; // library always uses ULONG
33 unsigned long long ub
;
41 typedef int(* task_entry_t
)( int, ptask
);
44 __task_dup_entry(ptask task_dst
, ptask task_src
, int lastpriv
)
46 // setup lastprivate flag
47 task_dst
->last
= lastpriv
;
48 // could be constructor calls here...
52 // OpenMP RTL interfaces
53 typedef unsigned long long kmp_uint64
;
54 typedef long long kmp_int64
;
60 __kmpc_taskloop(ident_t
*loc
, int gtid
, kmp_task_t
*task
, int if_val
,
61 kmp_uint64
*lb
, kmp_uint64
*ub
, kmp_int64 st
,
62 int nogroup
, int sched
, kmp_int64 grainsize
, void *task_dup
);
64 __kmpc_omp_task_alloc( ident_t
*loc
, int gtid
, int flags
,
65 size_t sizeof_kmp_task_t
, size_t sizeof_shareds
,
66 task_entry_t task_entry
);
67 void __kmpc_atomic_fixed4_add(void *id_ref
, int gtid
, int * lhs
, int rhs
);
68 int __kmpc_global_thread_num(void *id_ref
);
75 int task_entry(int gtid
, ptask task
)
77 pshareds pshar
= task
->shareds
;
78 for( task
->i
= task
->lb
; task
->i
<= (int)task
->ub
; task
->i
+= task
->st
) {
79 task
->th
= omp_get_thread_num();
80 __kmpc_atomic_fixed4_add(NULL
,gtid
,pshar
->pcounter
,1);
81 __kmpc_atomic_fixed4_add(NULL
,gtid
,&((*pshar
->pth_counter
)[task
->th
]),1);
84 my_sleep( 0.1 ); // sleep 100 ms in order to allow other threads to steal tasks
86 *(pshar
->pj
) = task
->j
; // lastprivate
93 int i
, j
, gtid
= __kmpc_global_thread_num(NULL
);
100 #pragma omp parallel num_threads(N)
104 int gtid
= __kmpc_global_thread_num(NULL
);
106 * This is what the OpenMP runtime calls correspond to:
107 #pragma omp taskloop num_tasks(N) lastprivate(j)
108 for( i=0; i<N*GRAIN*STRIDE-1; i+=STRIDE )
110 int th = omp_get_thread_num();
118 task
= __kmpc_omp_task_alloc(NULL
,gtid
,1,sizeof(struct task
),sizeof(struct shar
),&task_entry
);
120 psh
->pth_counter
= &th_counter
;
121 psh
->pcounter
= &counter
;
124 task
->ub
= N
*GRAIN
*STRIDE
-2;
130 task
, // task structure
131 1, // if clause value
132 &task
->lb
, // lower bound
133 &task
->ub
, // upper bound
134 STRIDE
, // loop increment
135 0, // 1 if nogroup specified
136 2, // schedule type: 0-none, 1-grainsize, 2-num_tasks
137 N
, // schedule value (ignored for type 0)
138 (void*)&__task_dup_entry
// tasks duplication routine
143 if( j
!= N
*GRAIN
*STRIDE
-STRIDE
) {
144 printf("Error in lastprivate, %d != %d\n",j
,N
*GRAIN
*STRIDE
-STRIDE
);
147 if( counter
!= N
*GRAIN
) {
148 printf("Error, counter %d != %d\n",counter
,N
*GRAIN
);
151 for( i
=0; i
<N
; ++i
) {
152 if( th_counter
[i
] % GRAIN
) {
153 printf("Error, th_counter[%d] = %d\n",i
,th_counter
[i
]);