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