65 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
| // RUN: %libomp-compile && env KMP_ENABLE_TASK_THROTTLING=0 %libomp-run
 | |
| // RUN: %libomp-compile && env KMP_ENABLE_TASK_THROTTLING=1 %libomp-run
 | |
| 
 | |
| #include<omp.h>
 | |
| #include<stdlib.h>
 | |
| #include<string.h>
 | |
| 
 | |
| /**
 | |
|  * Test the task throttling behavior of the runtime.
 | |
|  * Unless OMP_NUM_THREADS is 1, the master thread pushes tasks to its own tasks
 | |
|  * queue until either of the following happens:
 | |
|  *   - the task queue is full, and it starts serializing tasks
 | |
|  *   - all tasks have been pushed, and it can begin execution
 | |
|  * The idea is to create a huge number of tasks which execution are blocked
 | |
|  * until the master thread comes to execute tasks (they need to be blocking,
 | |
|  * otherwise the second thread will start emptying the queue).
 | |
|  * At this point we can check the number of enqueued tasks: iff all tasks have
 | |
|  * been enqueued, then there was no task throttling.
 | |
|  * Otherwise there has been some sort of task throttling.
 | |
|  * If what we detect doesn't match the value of the environment variable, the
 | |
|  * test is failed.
 | |
|  */
 | |
| 
 | |
| 
 | |
| #define NUM_TASKS 2000
 | |
| 
 | |
| 
 | |
| int main()
 | |
| {
 | |
|   int i;
 | |
|   int block = 1;
 | |
|   int throttling = strcmp(getenv("KMP_ENABLE_TASK_THROTTLING"), "1") == 0;
 | |
|   int enqueued = 0;
 | |
|   int failed = -1;
 | |
| 
 | |
|   #pragma omp parallel num_threads(2)
 | |
|   #pragma omp master
 | |
|   {
 | |
|     for (i = 0; i < NUM_TASKS; i++) {
 | |
|       enqueued++;
 | |
|       #pragma omp task
 | |
|       {
 | |
|         int tid;
 | |
|         tid = omp_get_thread_num();
 | |
|         if (tid == 0) {
 | |
|           // As soon as the master thread starts executing task we should unlock
 | |
|           // all tasks, and detect the test failure if it has not been done yet.
 | |
|           if (failed < 0)
 | |
|             failed = throttling ? enqueued == NUM_TASKS : enqueued < NUM_TASKS;
 | |
| #pragma omp atomic write
 | |
|           block = 0;
 | |
|         }
 | |
|         int wait = 0;
 | |
|         do {
 | |
| #pragma omp atomic read
 | |
|           wait = block;
 | |
|         } while (wait);
 | |
|       }
 | |
|     }
 | |
|     block = 0;
 | |
|   }
 | |
| 
 | |
|   return failed;
 | |
| }
 |