LLVM OpenMP* Runtime Library
kmp_stub.cpp
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 //