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 "kmp.h" // KMP_DEFAULT_STKSIZE
19 #include "kmp_stub.h"
20 #include "omp.h" // Function renamings.
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   return malloc(size);
143 }
144 void *kmp_aligned_malloc(size_t sz, size_t a) {
145   i;
146 #if KMP_OS_WINDOWS
147   errno = ENOSYS; // not supported
148   return NULL; // no standard aligned allocator on Windows (pre - C11)
149 #else
150   void *res;
151   int err;
152   if (err = posix_memalign(&res, a, sz)) {
153     errno = err; // can be EINVAL or ENOMEM
154     return NULL;
155   }
156   return res;
157 #endif
158 }
159 void *kmp_calloc(size_t nelem, size_t elsize) {
160   i;
161   return calloc(nelem, elsize);
162 }
163 void *kmp_realloc(void *ptr, size_t size) {
164   i;
165   return realloc(ptr, size);
166 }
167 void kmp_free(void *ptr) {
168   i;
169   free(ptr);
170 }
171 
172 static int __kmps_blocktime = INT_MAX;
173 
174 void __kmps_set_blocktime(int arg) {
175   i;
176   __kmps_blocktime = arg;
177 } // __kmps_set_blocktime
178 
179 int __kmps_get_blocktime(void) {
180   i;
181   return __kmps_blocktime;
182 } // __kmps_get_blocktime
183 
184 static int __kmps_dynamic = 0;
185 
186 void __kmps_set_dynamic(int arg) {
187   i;
188   __kmps_dynamic = arg;
189 } // __kmps_set_dynamic
190 
191 int __kmps_get_dynamic(void) {
192   i;
193   return __kmps_dynamic;
194 } // __kmps_get_dynamic
195 
196 static int __kmps_library = 1000;
197 
198 void __kmps_set_library(int arg) {
199   i;
200   __kmps_library = arg;
201 } // __kmps_set_library
202 
203 int __kmps_get_library(void) {
204   i;
205   return __kmps_library;
206 } // __kmps_get_library
207 
208 static int __kmps_nested = 0;
209 
210 void __kmps_set_nested(int arg) {
211   i;
212   __kmps_nested = arg;
213 } // __kmps_set_nested
214 
215 int __kmps_get_nested(void) {
216   i;
217   return __kmps_nested;
218 } // __kmps_get_nested
219 
220 static size_t __kmps_stacksize = KMP_DEFAULT_STKSIZE;
221 
222 void __kmps_set_stacksize(int arg) {
223   i;
224   __kmps_stacksize = arg;
225 } // __kmps_set_stacksize
226 
227 int __kmps_get_stacksize(void) {
228   i;
229   return __kmps_stacksize;
230 } // __kmps_get_stacksize
231 
232 static kmp_sched_t __kmps_sched_kind = kmp_sched_default;
233 static int __kmps_sched_modifier = 0;
234 
235 void __kmps_set_schedule(kmp_sched_t kind, int modifier) {
236   i;
237   __kmps_sched_kind = kind;
238   __kmps_sched_modifier = modifier;
239 } // __kmps_set_schedule
240 
241 void __kmps_get_schedule(kmp_sched_t *kind, int *modifier) {
242   i;
243   *kind = __kmps_sched_kind;
244   *modifier = __kmps_sched_modifier;
245 } // __kmps_get_schedule
246 
247 #if OMP_40_ENABLED
248 
249 static kmp_proc_bind_t __kmps_proc_bind = proc_bind_false;
250 
251 void __kmps_set_proc_bind(kmp_proc_bind_t arg) {
252   i;
253   __kmps_proc_bind = arg;
254 } // __kmps_set_proc_bind
255 
256 kmp_proc_bind_t __kmps_get_proc_bind(void) {
257   i;
258   return __kmps_proc_bind;
259 } // __kmps_get_proc_bind
260 
261 #endif /* OMP_40_ENABLED */
262 
263 double __kmps_get_wtime(void) {
264   // Elapsed wall clock time (in second) from "sometime in the past".
265   double wtime = 0.0;
266   i;
267 #if KMP_OS_WINDOWS
268   if (frequency > 0.0) {
269     LARGE_INTEGER now;
270     BOOL status = QueryPerformanceCounter(&now);
271     if (status) {
272       wtime = double(now.QuadPart) / frequency;
273     }
274   }
275 #else
276   // gettimeofday() returns seconds and microseconds since the Epoch.
277   struct timeval tval;
278   int rc;
279   rc = gettimeofday(&tval, NULL);
280   if (rc == 0) {
281     wtime = (double)(tval.tv_sec) + 1.0E-06 * (double)(tval.tv_usec);
282   } else {
283     // TODO: Assert or abort here.
284   }
285 #endif
286   return wtime;
287 } // __kmps_get_wtime
288 
289 double __kmps_get_wtick(void) {
290   // Number of seconds between successive clock ticks.
291   double wtick = 0.0;
292   i;
293 #if KMP_OS_WINDOWS
294   {
295     DWORD increment;
296     DWORD adjustment;
297     BOOL disabled;
298     BOOL rc;
299     rc = GetSystemTimeAdjustment(&adjustment, &increment, &disabled);
300     if (rc) {
301       wtick = 1.0E-07 * (double)(disabled ? increment : adjustment);
302     } else {
303       // TODO: Assert or abort here.
304       wtick = 1.0E-03;
305     }
306   }
307 #else
308   // TODO: gettimeofday() returns in microseconds, but what the precision?
309   wtick = 1.0E-06;
310 #endif
311   return wtick;
312 } // __kmps_get_wtick
313 
314 // end of file //
315