1 // RUN: %libomp-compile && env KMP_ENABLE_TASK_THROTTLING=0 %libomp-run 2 // RUN: %libomp-compile && env KMP_ENABLE_TASK_THROTTLING=1 %libomp-run 3 4 #include<omp.h> 5 #include<stdlib.h> 6 #include<string.h> 7 8 /** 9 * Test the task throttling behavior of the runtime. 10 * Unless OMP_NUM_THREADS is 1, the master thread pushes tasks to its own tasks 11 * queue until either of the following happens: 12 * - the task queue is full, and it starts serializing tasks 13 * - all tasks have been pushed, and it can begin execution 14 * The idea is to create a huge number of tasks which execution are blocked 15 * until the master thread comes to execute tasks (they need to be blocking, 16 * otherwise the second thread will start emptying the queue). 17 * At this point we can check the number of enqueued tasks: iff all tasks have 18 * been enqueued, then there was no task throttling. 19 * Otherwise there has been some sort of task throttling. 20 * If what we detect doesn't match the value of the environment variable, the 21 * test is failed. 22 */ 23 24 25 #define NUM_TASKS 2000 26 27 main()28int main() 29 { 30 int i; 31 int block = 1; 32 int throttling = strcmp(getenv("KMP_ENABLE_TASK_THROTTLING"), "1") == 0; 33 int enqueued = 0; 34 int failed = -1; 35 36 #pragma omp parallel num_threads(2) 37 #pragma omp master 38 { 39 for (i = 0; i < NUM_TASKS; i++) { 40 enqueued++; 41 #pragma omp task 42 { 43 int tid; 44 tid = omp_get_thread_num(); 45 if (tid == 0) { 46 // As soon as the master thread starts executing task we should unlock 47 // all tasks, and detect the test failure if it has not been done yet. 48 if (failed < 0) 49 failed = throttling ? enqueued == NUM_TASKS : enqueued < NUM_TASKS; 50 #pragma omp atomic write 51 block = 0; 52 } 53 int wait = 0; 54 do { 55 #pragma omp atomic read 56 wait = block; 57 } while (wait); 58 } 59 } 60 block = 0; 61 } 62 63 return failed; 64 } 65