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 #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 //