1// RUN: %libomp-compile-and-run
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <omp.h>
7
8#define XSTR(x) #x
9#define STR(x) XSTR(x)
10
11#define streqls(s1, s2) (!strcmp(s1, s2))
12
13#define check(condition) \
14 if (!(condition)) { \
15 fprintf(stderr, "error: %s: %d: " STR(condition) "\n", __FILE__, \
16 __LINE__); \
17 exit(1); \
18 }
19
20#if defined(_WIN32)
21#include <windows.h>
22#include <process.h>
23#define getpid _getpid
24#ifndef __MINGW32__
25typedef int pid_t;
26#endif
27#define gettid GetCurrentThreadId
28#define my_gethostname(buf, sz) GetComputerNameA(buf, &(sz))
29#else
30#include <unistd.h>
31#include <sys/types.h>
32#define my_gethostname(buf, sz) gethostname(buf, sz)
33#endif
34
35#define BUFFER_SIZE 256
36
37int get_integer() {
38 int n, retval;
39 char buf[BUFFER_SIZE];
40 size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL);
41 check(needed < BUFFER_SIZE);
42 n = sscanf(s: buf, format: "%d", &retval);
43 check(n == 1);
44 return retval;
45}
46
47char* get_string() {
48 int n, retval;
49 char buf[BUFFER_SIZE];
50 size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL);
51 check(needed < BUFFER_SIZE);
52 return strdup(s: buf);
53}
54
55void check_integer(const char* formats[2], int(*func)()) {
56 int i;
57 for (i = 0; i < 2; ++i) {
58 omp_set_affinity_format(formats[i]);
59 #pragma omp parallel num_threads(8)
60 {
61 check(get_integer() == func());
62 #pragma omp parallel num_threads(3)
63 {
64 check(get_integer() == func());
65 }
66 check(get_integer() == func());
67 }
68 }
69}
70
71void check_nesting_level() {
72 // Check %{nesting_level} and %L
73 const char* formats[2] = {"%{nesting_level}", "%L"};
74 check_integer(formats, omp_get_level);
75}
76
77void check_thread_num() {
78 // Check %{thread_num} and %n
79 const char* formats[2] = {"%{thread_num}", "%n"};
80 check_integer(formats, omp_get_thread_num);
81}
82
83void check_num_threads() {
84 // Check %{num_threads} and %N
85 const char* formats[2] = {"%{num_threads}", "%N"};
86 check_integer(formats, omp_get_num_threads);
87}
88
89int ancestor_helper() {
90 return omp_get_ancestor_thread_num(omp_get_level() - 1);
91}
92void check_ancestor_tnum() {
93 // Check %{ancestor_tnum} and %a
94 const char* formats[2] = {"%{ancestor_tnum}", "%a"};
95 check_integer(formats, func: ancestor_helper);
96}
97
98int my_get_pid() { return (int)getpid(); }
99void check_process_id() {
100 // Check %{process_id} and %P
101 const char* formats[2] = {"%{process_id}", "%P"};
102 check_integer(formats, func: my_get_pid);
103}
104
105/*
106int my_get_tid() { return (int)gettid(); }
107void check_native_thread_id() {
108 // Check %{native_thread_id} and %i
109 const char* formats[2] = {"%{native_thread_id}", "%i"};
110 check_integer(formats, my_get_tid);
111}
112*/
113
114void check_host() {
115 int i;
116 int buffer_size = 256;
117 const char* formats[2] = {"%{host}", "%H"};
118 char hostname[256];
119 my_gethostname(hostname, buffer_size);
120 for (i = 0; i < 2; ++i) {
121 omp_set_affinity_format(formats[i]);
122 #pragma omp parallel num_threads(8)
123 {
124 char* host = get_string();
125 check(streqls(host, hostname));
126 free(ptr: host);
127 }
128 }
129}
130
131void check_undefined() {
132 int i;
133 const char* formats[2] = {"%{foobar}", "%X"};
134 for (i = 0; i < 2; ++i) {
135 omp_set_affinity_format(formats[i]);
136 #pragma omp parallel num_threads(8)
137 {
138 char* undef = get_string();
139 check(streqls(undef, "undefined"));
140 free(ptr: undef);
141 }
142 }
143}
144
145int main(int argc, char** argv) {
146 omp_set_nested(1);
147 check_nesting_level();
148 check_num_threads();
149 check_ancestor_tnum();
150 check_process_id();
151 //check_native_thread_id();
152 check_host();
153 check_undefined();
154 return 0;
155}
156

source code of openmp/runtime/test/affinity/format/fields_values.c