168 lines · c
1// RUN: %libomp-compile-and-run2// RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run3 4#include <stdio.h>5#include <omp.h>6#include "omp_my_sleep.h"7 8#define N 49#define ST 310#define UB 11811#define LB 012 13// globals14int counter;15int task_count;16 17// Compiler-generated code (emulation)18typedef struct ident {19 void* dummy;20} ident_t;21 22typedef struct shar {23 int *pcounter;24 int *pj;25 int *ptask_count;26} *pshareds;27 28typedef struct task {29 pshareds shareds;30 int(* routine)(int,struct task*);31 int part_id;32 unsigned long long lb; // library always uses ULONG33 unsigned long long ub;34 int st;35 int last;36 int i;37 int j;38 int th;39} *ptask, kmp_task_t;40 41typedef int(* task_entry_t)( int, ptask );42 43void44__task_dup_entry(ptask task_dst, ptask task_src, int lastpriv)45{46// setup lastprivate flag47 task_dst->last = lastpriv;48// could be constructor calls here...49}50 51// OpenMP RTL interfaces52typedef unsigned long long kmp_uint64;53typedef long long kmp_int64;54 55#ifdef __cplusplus56extern "C" {57#endif58void59__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,62 void *task_dup);63ptask64__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);67void __kmpc_atomic_fixed4_add(void *id_ref, int gtid, int * lhs, int rhs);68int __kmpc_global_thread_num(void *id_ref);69#ifdef __cplusplus70}71#endif72 73// User's code74int task_entry(int gtid, ptask task)75{76 pshareds pshar = task->shareds;77 __kmpc_atomic_fixed4_add(NULL, gtid, pshar->ptask_count, 1);78 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);82 task->j = task->i;83 }84 my_sleep( 0.1 ); // sleep 100 ms in order to allow other threads to steal tasks85 if (task->last) {86 *(pshar->pj) = task->j; // lastprivate87 }88 return 0;89}90 91void task_loop(int sched_type, int sched_val, int modifier)92{93 int i, j, gtid = __kmpc_global_thread_num(NULL);94 ptask task;95 pshareds psh;96 omp_set_dynamic(0);97 counter = 0;98 task_count = 0;99 #pragma omp parallel num_threads(N)100 {101 #pragma omp master102 {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);106 psh = task->shareds;107 psh->pcounter = &counter;108 psh->ptask_count = &task_count;109 psh->pj = &j;110 task->lb = LB;111 task->ub = UB;112 task->st = ST;113 114 __kmpc_taskloop_5(115 NULL, // location116 gtid, // gtid117 task, // task structure118 1, // if clause value119 &task->lb, // lower bound120 &task->ub, // upper bound121 ST, // loop increment122 0, // 1 if nogroup specified123 sched_type, // schedule type: 0-none, 1-grainsize, 2-num_tasks124 sched_val, // schedule value (ignored for type 0)125 modifier, // strict modifier126 (void*)&__task_dup_entry // tasks duplication routine127 );128 } // end master129 } // end parallel130// check results131 int tc;132 if (ST == 1) { // most common case133 tc = UB - LB + 1;134 } else if (ST < 0) {135 tc = (LB - UB) / (-ST) + 1;136 } else { // ST > 0137 tc = (UB - LB) / ST + 1;138 }139 int count;140 if (sched_type == 1) {141 count = (sched_val > tc) ? 1 : (tc + sched_val - 1) / sched_val;142 } else {143 count = (sched_val > tc) ? tc : sched_val;144 }145 if (j != LB + (tc - 1) * ST) {146 printf("Error in lastprivate, %d != %d\n", j, LB + (tc - 1) * ST);147 exit(1);148 }149 if (counter != tc) {150 printf("Error, counter %d != %d\n", counter, tc);151 exit(1);152 }153 if (task_count != count) {154 printf("Error, task count %d != %d\n", task_count, count);155 exit(1);156 }157}158 159int main(int argc, char *argv[]) {160 task_loop(1, 6, 1); // create 7 tasks161 task_loop(2, 6, 1); // create 6 tasks162 task_loop(1, 50, 1); // create 1 task163 task_loop(2, 50, 1); // create 40 tasks164 165 printf("Test passed\n");166 return 0;167}168