1 // RUN: %libomp-compile-and-run
2 // RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run
6 #include "omp_my_sleep.h"
17 // Compiler-generated code (emulation)
18 typedef struct ident
{
30 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...
51 // OpenMP RTL interfaces
52 typedef unsigned long long kmp_uint64
;
53 typedef long long kmp_int64
;
59 __kmpc_taskloop_5(ident_t
*loc
, int gtid
, kmp_task_t
*task
, int if_val
,
60 kmp_uint64
*lb
, kmp_uint64
*ub
, kmp_int64 st
,
61 int nogroup
, int sched
, kmp_int64 grainsize
, int modifier
,
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
);
74 int task_entry(int gtid
, ptask task
)
76 pshareds pshar
= task
->shareds
;
77 __kmpc_atomic_fixed4_add(NULL
, gtid
, pshar
->ptask_count
, 1);
79 for (task
->i
= task
->lb
; task
->i
<= (int)task
->ub
; task
->i
+= task
->st
) {
80 task
->th
= omp_get_thread_num();
81 __kmpc_atomic_fixed4_add(NULL
,gtid
,pshar
->pcounter
,1);
84 my_sleep( 0.1 ); // sleep 100 ms in order to allow other threads to steal tasks
86 *(pshar
->pj
) = task
->j
; // lastprivate
91 void task_loop(int sched_type
, int sched_val
, int modifier
)
93 int i
, j
, gtid
= __kmpc_global_thread_num(NULL
);
99 #pragma omp parallel num_threads(N)
103 int gtid
= __kmpc_global_thread_num(NULL
);
104 task
= __kmpc_omp_task_alloc(NULL
, gtid
, 1, sizeof(struct task
),
105 sizeof(struct shar
), &task_entry
);
107 psh
->pcounter
= &counter
;
108 psh
->ptask_count
= &task_count
;
117 task
, // task structure
118 1, // if clause value
119 &task
->lb
, // lower bound
120 &task
->ub
, // upper bound
121 ST
, // loop increment
122 0, // 1 if nogroup specified
123 sched_type
, // schedule type: 0-none, 1-grainsize, 2-num_tasks
124 sched_val
, // schedule value (ignored for type 0)
125 modifier
, // strict modifier
126 (void*)&__task_dup_entry
// tasks duplication routine
132 if (ST
== 1) { // most common case
135 tc
= (LB
- UB
) / (-ST
) + 1;
137 tc
= (UB
- LB
) / ST
+ 1;
140 if (sched_type
== 1) {
141 count
= (sched_val
> tc
) ? 1 : (tc
+ sched_val
- 1) / sched_val
;
143 count
= (sched_val
> tc
) ? tc
: sched_val
;
145 if (j
!= LB
+ (tc
- 1) * ST
) {
146 printf("Error in lastprivate, %d != %d\n", j
, LB
+ (tc
- 1) * ST
);
150 printf("Error, counter %d != %d\n", counter
, tc
);
153 if (task_count
!= count
) {
154 printf("Error, task count %d != %d\n", task_count
, count
);
159 int main(int argc
, char *argv
[]) {
160 task_loop(1, 6, 1); // create 7 tasks
161 task_loop(2, 6, 1); // create 6 tasks
162 task_loop(1, 50, 1); // create 1 task
163 task_loop(2, 50, 1); // create 40 tasks
165 printf("Test passed\n");