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