| // RUN: %libomp-compile-and-run | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <omp.h> | |
| #define XSTR(x) #x | |
| #define STR(x) XSTR(x) | |
| #define streqls(s1, s2) (!strcmp(s1, s2)) | |
| #define check(condition) \ | |
| if (!(condition)) { \ | |
| fprintf(stderr, "error: %s: %d: " STR(condition) "\n", __FILE__, \ | |
| __LINE__); \ | |
| exit(1); \ | |
| } | |
| #if defined(_WIN32) | |
| #include <windows.h> | |
| #include <process.h> | |
| #define getpid _getpid | |
| #ifndef __MINGW32__ | |
| typedef int pid_t; | |
| #endif | |
| #define gettid GetCurrentThreadId | |
| #define my_gethostname(buf, sz) GetComputerNameA(buf, &(sz)) | |
| #else | |
| #include <unistd.h> | |
| #include <sys/types.h> | |
| #define my_gethostname(buf, sz) gethostname(buf, sz) | |
| #endif | |
| #define BUFFER_SIZE 256 | |
| int get_integer() { | |
| int n, retval; | |
| char buf[BUFFER_SIZE]; | |
| size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL); | |
| check(needed < BUFFER_SIZE); | |
| n = sscanf(buf, "%d", &retval); | |
| check(n == 1); | |
| return retval; | |
| } | |
| char* get_string() { | |
| int n, retval; | |
| char buf[BUFFER_SIZE]; | |
| size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL); | |
| check(needed < BUFFER_SIZE); | |
| return strdup(buf); | |
| } | |
| void check_integer(const char* formats[2], int(*func)()) { | |
| int i; | |
| for (i = 0; i < 2; ++i) { | |
| omp_set_affinity_format(formats[i]); | |
| #pragma omp parallel num_threads(8) | |
| { | |
| check(get_integer() == func()); | |
| #pragma omp parallel num_threads(3) | |
| { | |
| check(get_integer() == func()); | |
| } | |
| check(get_integer() == func()); | |
| } | |
| } | |
| } | |
| void check_nesting_level() { | |
| // Check %{nesting_level} and %L | |
| const char* formats[2] = {"%{nesting_level}", "%L"}; | |
| check_integer(formats, omp_get_level); | |
| } | |
| void check_thread_num() { | |
| // Check %{thread_num} and %n | |
| const char* formats[2] = {"%{thread_num}", "%n"}; | |
| check_integer(formats, omp_get_thread_num); | |
| } | |
| void check_num_threads() { | |
| // Check %{num_threads} and %N | |
| const char* formats[2] = {"%{num_threads}", "%N"}; | |
| check_integer(formats, omp_get_num_threads); | |
| } | |
| int ancestor_helper() { | |
| return omp_get_ancestor_thread_num(omp_get_level() - 1); | |
| } | |
| void check_ancestor_tnum() { | |
| // Check %{ancestor_tnum} and %a | |
| const char* formats[2] = {"%{ancestor_tnum}", "%a"}; | |
| check_integer(formats, ancestor_helper); | |
| } | |
| int my_get_pid() { return (int)getpid(); } | |
| void check_process_id() { | |
| // Check %{process_id} and %P | |
| const char* formats[2] = {"%{process_id}", "%P"}; | |
| check_integer(formats, my_get_pid); | |
| } | |
| /* | |
| int my_get_tid() { return (int)gettid(); } | |
| void check_native_thread_id() { | |
| // Check %{native_thread_id} and %i | |
| const char* formats[2] = {"%{native_thread_id}", "%i"}; | |
| check_integer(formats, my_get_tid); | |
| } | |
| */ | |
| void check_host() { | |
| #ifdef _WIN32 | |
| typedef DWORD buffer_size_t; | |
| #else | |
| typedef int buffer_size_t; | |
| #endif | |
| int i; | |
| buffer_size_t buffer_size = 256; | |
| const char* formats[2] = {"%{host}", "%H"}; | |
| char hostname[256]; | |
| my_gethostname(hostname, buffer_size); | |
| for (i = 0; i < 2; ++i) { | |
| omp_set_affinity_format(formats[i]); | |
| #pragma omp parallel num_threads(8) | |
| { | |
| char* host = get_string(); | |
| check(streqls(host, hostname)); | |
| free(host); | |
| } | |
| } | |
| } | |
| void check_undefined() { | |
| int i; | |
| const char* formats[2] = {"%{foobar}", "%X"}; | |
| for (i = 0; i < 2; ++i) { | |
| omp_set_affinity_format(formats[i]); | |
| #pragma omp parallel num_threads(8) | |
| { | |
| char* undef = get_string(); | |
| check(streqls(undef, "undefined")); | |
| free(undef); | |
| } | |
| } | |
| } | |
| int main(int argc, char** argv) { | |
| omp_set_nested(1); | |
| check_nesting_level(); | |
| check_num_threads(); | |
| check_ancestor_tnum(); | |
| check_process_id(); | |
| //check_native_thread_id(); | |
| check_host(); | |
| check_undefined(); | |
| return 0; | |
| } |