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
28int main()
29{
30 int i;
31 int block = 1;
32 int throttling = strcmp(s1: getenv(name: "KMP_ENABLE_TASK_THROTTLING"), s2: "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

source code of openmp/runtime/test/tasking/omp_fill_taskqueue.c