LLVM OpenMP
omp_flush_acquire_release.c
Go to the documentation of this file.
1// RUN: %libomp-compile-and-run
2// REQUIRES: clang
3
4// Test is based on OpenMP API Example (omp_5.0) acquire_release3.c
5// https://github.com/OpenMP/Examples/blob/main/synchronization/sources/acquire_release.3.c
6
7#include <stdio.h>
8#include <omp.h>
9
10typedef void ident_t;
11extern void __kmpc_flush_explicit(ident_t *, int order, int scope);
12
13int test_memorder(int write_order, int read_order) {
14 int x = 0, y = 0;
15 int num_fails = 0;
16#pragma omp parallel num_threads(2)
17 {
18 int thrd = omp_get_thread_num();
19 if (thrd == 0) {
20 x = 10;
21 __kmpc_flush_explicit(NULL, write_order, 0);
22#pragma omp atomic write // or with relaxed clause
23 y = 1;
24 } else {
25 int tmp = 0;
26 while (tmp == 0) {
27#pragma omp atomic read // or with relaxed clause
28 tmp = y;
29 }
30 __kmpc_flush_explicit(NULL, read_order, 0);
31 // printf("x = %d\n", x); // always "x = 10"
32 if (x != 10)
33 num_fails++;
34 }
35 }
36 return num_fails;
37}
38
39int main() {
40 // Clang-based compiler has predefined macro __ATOMIC_<memory_order>.
41 int write_order[3] = {__ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL, __ATOMIC_RELEASE};
42 int read_order[3] = {__ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE};
43
44 // Repeat 1000 times
45 for (int n = 0; n < 1000; n++) {
46 for (int i = 0; i < 3; i++) {
47 for (int j = 0; j < 3; j++) {
48 if (test_memorder(write_order[i], read_order[j])) {
49 printf("failed\n");
50 exit(EXIT_FAILURE);
51 }
52 }
53 }
54 }
55
56 printf("passed\n");
57 return EXIT_SUCCESS;
58}
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d __itt_event ITT_FORMAT __itt_group_mark d void const wchar_t const wchar_t int ITT_FORMAT __itt_group_sync __itt_group_fsync x void const wchar_t int const wchar_t int int ITT_FORMAT __itt_group_sync __itt_group_fsync x void ITT_FORMAT __itt_group_sync __itt_group_fsync p void ITT_FORMAT __itt_group_sync __itt_group_fsync p void size_t ITT_FORMAT lu no args __itt_obj_prop_t __itt_obj_state_t ITT_FORMAT d const char ITT_FORMAT s const char ITT_FORMAT s __itt_frame ITT_FORMAT p __itt_counter ITT_FORMAT p __itt_counter unsigned long long ITT_FORMAT lu __itt_counter unsigned long long ITT_FORMAT lu __itt_counter __itt_clock_domain unsigned long long void ITT_FORMAT p const wchar_t ITT_FORMAT S __itt_mark_type const wchar_t ITT_FORMAT S __itt_mark_type const char ITT_FORMAT s __itt_mark_type ITT_FORMAT d __itt_caller ITT_FORMAT p __itt_caller ITT_FORMAT p no args const __itt_domain __itt_clock_domain unsigned long long __itt_id ITT_FORMAT lu const __itt_domain __itt_clock_domain unsigned long long __itt_id __itt_id void ITT_FORMAT p const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_clock_domain unsigned long long __itt_id __itt_string_handle __itt_scope scope
#define i
Definition kmp_stub.cpp:88
int test_memorder(int write_order, int read_order)
void __kmpc_flush_explicit(ident_t *, int order, int scope)
int x[NDEPS]