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