1 /* 2 * kmp_stub.cpp -- stub versions of user-callable OpenMP RT functions. 3 */ 4 5 //===----------------------------------------------------------------------===// 6 // 7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 8 // See https://llvm.org/LICENSE.txt for license information. 9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include <errno.h> 14 #include <limits.h> 15 #include <stdlib.h> 16 17 #define __KMP_IMP 18 #include "omp.h" // omp_* declarations, must be included before "kmp.h" 19 #include "kmp.h" // KMP_DEFAULT_STKSIZE 20 #include "kmp_stub.h" 21 22 #if KMP_OS_WINDOWS 23 #include <windows.h> 24 #else 25 #include <sys/time.h> 26 #endif 27 28 // Moved from omp.h 29 #define omp_set_max_active_levels ompc_set_max_active_levels 30 #define omp_set_schedule ompc_set_schedule 31 #define omp_get_ancestor_thread_num ompc_get_ancestor_thread_num 32 #define omp_get_team_size ompc_get_team_size 33 34 #define omp_set_num_threads ompc_set_num_threads 35 #define omp_set_dynamic ompc_set_dynamic 36 #define omp_set_nested ompc_set_nested 37 #define omp_set_affinity_format ompc_set_affinity_format 38 #define omp_get_affinity_format ompc_get_affinity_format 39 #define omp_display_affinity ompc_display_affinity 40 #define omp_capture_affinity ompc_capture_affinity 41 #define kmp_set_stacksize kmpc_set_stacksize 42 #define kmp_set_stacksize_s kmpc_set_stacksize_s 43 #define kmp_set_blocktime kmpc_set_blocktime 44 #define kmp_set_library kmpc_set_library 45 #define kmp_set_defaults kmpc_set_defaults 46 #define kmp_set_disp_num_buffers kmpc_set_disp_num_buffers 47 #define kmp_malloc kmpc_malloc 48 #define kmp_aligned_malloc kmpc_aligned_malloc 49 #define kmp_calloc kmpc_calloc 50 #define kmp_realloc kmpc_realloc 51 #define kmp_free kmpc_free 52 53 #if KMP_OS_WINDOWS 54 static double frequency = 0.0; 55 #endif 56 57 // Helper functions. 58 static size_t __kmps_init() { 59 static int initialized = 0; 60 static size_t dummy = 0; 61 if (!initialized) { 62 // TODO: Analyze KMP_VERSION environment variable, print 63 // __kmp_version_copyright and __kmp_version_build_time. 64 // WARNING: Do not use "fprintf(stderr, ...)" because it will cause 65 // unresolved "__iob" symbol (see C70080). We need to extract __kmp_printf() 66 // stuff from kmp_runtime.cpp and use it. 67 68 // Trick with dummy variable forces linker to keep __kmp_version_copyright 69 // and __kmp_version_build_time strings in executable file (in case of 70 // static linkage). When KMP_VERSION analysis is implemented, dummy 71 // variable should be deleted, function should return void. 72 dummy = __kmp_version_copyright - __kmp_version_build_time; 73 74 #if KMP_OS_WINDOWS 75 LARGE_INTEGER freq; 76 BOOL status = QueryPerformanceFrequency(&freq); 77 if (status) { 78 frequency = double(freq.QuadPart); 79 } 80 #endif 81 82 initialized = 1; 83 } 84 return dummy; 85 } // __kmps_init 86 87 #define i __kmps_init(); 88 89 /* set API functions */ 90 void omp_set_num_threads(omp_int_t num_threads) { i; } 91 void omp_set_dynamic(omp_int_t dynamic) { 92 i; 93 __kmps_set_dynamic(dynamic); 94 } 95 void omp_set_nested(omp_int_t nested) { 96 i; 97 __kmps_set_nested(nested); 98 } 99 void omp_set_max_active_levels(omp_int_t max_active_levels) { i; } 100 void omp_set_schedule(omp_sched_t kind, omp_int_t modifier) { 101 i; 102 __kmps_set_schedule((kmp_sched_t)kind, modifier); 103 } 104 int omp_get_ancestor_thread_num(omp_int_t level) { 105 i; 106 return (level) ? (-1) : (0); 107 } 108 int omp_get_team_size(omp_int_t level) { 109 i; 110 return (level) ? (-1) : (1); 111 } 112 int kmpc_set_affinity_mask_proc(int proc, void **mask) { 113 i; 114 return -1; 115 } 116 int kmpc_unset_affinity_mask_proc(int proc, void **mask) { 117 i; 118 return -1; 119 } 120 int kmpc_get_affinity_mask_proc(int proc, void **mask) { 121 i; 122 return -1; 123 } 124 125 /* kmp API functions */ 126 void kmp_set_stacksize(omp_int_t arg) { 127 i; 128 __kmps_set_stacksize(arg); 129 } 130 void kmp_set_stacksize_s(size_t arg) { 131 i; 132 __kmps_set_stacksize(arg); 133 } 134 void kmp_set_blocktime(omp_int_t arg) { 135 i; 136 __kmps_set_blocktime(arg); 137 } 138 void kmp_set_library(omp_int_t arg) { 139 i; 140 __kmps_set_library(arg); 141 } 142 void kmp_set_defaults(char const *str) { i; } 143 void kmp_set_disp_num_buffers(omp_int_t arg) { i; } 144 145 /* KMP memory management functions. */ 146 void *kmp_malloc(size_t size) { 147 i; 148 void *res; 149 #if KMP_OS_WINDOWS 150 // If succesfull returns a pointer to the memory block, otherwise returns 151 // NULL. 152 // Sets errno to ENOMEM or EINVAL if memory allocation failed or parameter 153 // validation failed. 154 res = _aligned_malloc(size, 1); 155 #else 156 res = malloc(size); 157 #endif 158 return res; 159 } 160 void *kmp_aligned_malloc(size_t sz, size_t a) { 161 i; 162 int err; 163 void *res; 164 #if KMP_OS_WINDOWS 165 res = _aligned_malloc(sz, a); 166 #else 167 if (err = posix_memalign(&res, a, sz)) { 168 errno = err; // can be EINVAL or ENOMEM 169 res = NULL; 170 } 171 #endif 172 return res; 173 } 174 void *kmp_calloc(size_t nelem, size_t elsize) { 175 i; 176 void *res; 177 #if KMP_OS_WINDOWS 178 res = _aligned_recalloc(NULL, nelem, elsize, 1); 179 #else 180 res = calloc(nelem, elsize); 181 #endif 182 return res; 183 } 184 void *kmp_realloc(void *ptr, size_t size) { 185 i; 186 void *res; 187 #if KMP_OS_WINDOWS 188 res = _aligned_realloc(ptr, size, 1); 189 #else 190 res = realloc(ptr, size); 191 #endif 192 return res; 193 } 194 void kmp_free(void *ptr) { 195 i; 196 #if KMP_OS_WINDOWS 197 _aligned_free(ptr); 198 #else 199 free(ptr); 200 #endif 201 } 202 203 static int __kmps_blocktime = INT_MAX; 204 205 void __kmps_set_blocktime(int arg) { 206 i; 207 __kmps_blocktime = arg; 208 } // __kmps_set_blocktime 209 210 int __kmps_get_blocktime(void) { 211 i; 212 return __kmps_blocktime; 213 } // __kmps_get_blocktime 214 215 static int __kmps_dynamic = 0; 216 217 void __kmps_set_dynamic(int arg) { 218 i; 219 __kmps_dynamic = arg; 220 } // __kmps_set_dynamic 221 222 int __kmps_get_dynamic(void) { 223 i; 224 return __kmps_dynamic; 225 } // __kmps_get_dynamic 226 227 static int __kmps_library = 1000; 228 229 void __kmps_set_library(int arg) { 230 i; 231 __kmps_library = arg; 232 } // __kmps_set_library 233 234 int __kmps_get_library(void) { 235 i; 236 return __kmps_library; 237 } // __kmps_get_library 238 239 static int __kmps_nested = 0; 240 241 void __kmps_set_nested(int arg) { 242 i; 243 __kmps_nested = arg; 244 } // __kmps_set_nested 245 246 int __kmps_get_nested(void) { 247 i; 248 return __kmps_nested; 249 } // __kmps_get_nested 250 251 static size_t __kmps_stacksize = KMP_DEFAULT_STKSIZE; 252 253 void __kmps_set_stacksize(int arg) { 254 i; 255 __kmps_stacksize = arg; 256 } // __kmps_set_stacksize 257 258 int __kmps_get_stacksize(void) { 259 i; 260 return __kmps_stacksize; 261 } // __kmps_get_stacksize 262 263 static kmp_sched_t __kmps_sched_kind = kmp_sched_default; 264 static int __kmps_sched_modifier = 0; 265 266 void __kmps_set_schedule(kmp_sched_t kind, int modifier) { 267 i; 268 __kmps_sched_kind = kind; 269 __kmps_sched_modifier = modifier; 270 } // __kmps_set_schedule 271 272 void __kmps_get_schedule(kmp_sched_t *kind, int *modifier) { 273 i; 274 *kind = __kmps_sched_kind; 275 *modifier = __kmps_sched_modifier; 276 } // __kmps_get_schedule 277 278 #if OMP_40_ENABLED 279 280 kmp_proc_bind_t __kmps_get_proc_bind(void) { 281 i; 282 return 0; 283 } // __kmps_get_proc_bind 284 285 #endif /* OMP_40_ENABLED */ 286 287 double __kmps_get_wtime(void) { 288 // Elapsed wall clock time (in second) from "sometime in the past". 289 double wtime = 0.0; 290 i; 291 #if KMP_OS_WINDOWS 292 if (frequency > 0.0) { 293 LARGE_INTEGER now; 294 BOOL status = QueryPerformanceCounter(&now); 295 if (status) { 296 wtime = double(now.QuadPart) / frequency; 297 } 298 } 299 #else 300 // gettimeofday() returns seconds and microseconds since the Epoch. 301 struct timeval tval; 302 int rc; 303 rc = gettimeofday(&tval, NULL); 304 if (rc == 0) { 305 wtime = (double)(tval.tv_sec) + 1.0E-06 * (double)(tval.tv_usec); 306 } else { 307 // TODO: Assert or abort here. 308 } 309 #endif 310 return wtime; 311 } // __kmps_get_wtime 312 313 double __kmps_get_wtick(void) { 314 // Number of seconds between successive clock ticks. 315 double wtick = 0.0; 316 i; 317 #if KMP_OS_WINDOWS 318 { 319 DWORD increment; 320 DWORD adjustment; 321 BOOL disabled; 322 BOOL rc; 323 rc = GetSystemTimeAdjustment(&adjustment, &increment, &disabled); 324 if (rc) { 325 wtick = 1.0E-07 * (double)(disabled ? increment : adjustment); 326 } else { 327 // TODO: Assert or abort here. 328 wtick = 1.0E-03; 329 } 330 } 331 #else 332 // TODO: gettimeofday() returns in microseconds, but what the precision? 333 wtick = 1.0E-06; 334 #endif 335 return wtick; 336 } // __kmps_get_wtick 337 338 #if OMP_50_ENABLED 339 /* OpenMP 5.0 Memory Management */ 340 #if KMP_OS_WINDOWS 341 omp_allocator_handle_t const omp_null_allocator = 0; 342 omp_allocator_handle_t const omp_default_mem_alloc = 343 (omp_allocator_handle_t const)1; 344 omp_allocator_handle_t const omp_large_cap_mem_alloc = 345 (omp_allocator_handle_t const)2; 346 omp_allocator_handle_t const omp_const_mem_alloc = 347 (omp_allocator_handle_t const)3; 348 omp_allocator_handle_t const omp_high_bw_mem_alloc = 349 (omp_allocator_handle_t const)4; 350 omp_allocator_handle_t const omp_low_lat_mem_alloc = 351 (omp_allocator_handle_t const)5; 352 omp_allocator_handle_t const omp_cgroup_mem_alloc = 353 (omp_allocator_handle_t const)6; 354 omp_allocator_handle_t const omp_pteam_mem_alloc = 355 (omp_allocator_handle_t const)7; 356 omp_allocator_handle_t const omp_thread_mem_alloc = 357 (omp_allocator_handle_t const)8; 358 359 omp_memspace_handle_t const omp_default_mem_space = 360 (omp_memspace_handle_t const)0; 361 omp_memspace_handle_t const omp_large_cap_mem_space = 362 (omp_memspace_handle_t const)1; 363 omp_memspace_handle_t const omp_const_mem_space = 364 (omp_memspace_handle_t const)2; 365 omp_memspace_handle_t const omp_high_bw_mem_space = 366 (omp_memspace_handle_t const)3; 367 omp_memspace_handle_t const omp_low_lat_mem_space = 368 (omp_memspace_handle_t const)4; 369 #endif /* KMP_OS_WINDOWS */ 370 void *omp_alloc(size_t size, const omp_allocator_handle_t allocator) { 371 i; 372 return malloc(size); 373 } 374 void omp_free(void *ptr, const omp_allocator_handle_t allocator) { 375 i; 376 free(ptr); 377 } 378 /* OpenMP 5.0 Affinity Format */ 379 void omp_set_affinity_format(char const *format) { i; } 380 size_t omp_get_affinity_format(char *buffer, size_t size) { 381 i; 382 return 0; 383 } 384 void omp_display_affinity(char const *format) { i; } 385 size_t omp_capture_affinity(char *buffer, size_t buf_size, char const *format) { 386 i; 387 return 0; 388 } 389 #endif /* OMP_50_ENABLED */ 390 391 // end of file // 392