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