xref: /llvm-project/openmp/libompd/gdb-plugin/ompdModule.c (revision b0fc18da5bd9f6c6da5f8af775f75a7af9c27af1)
1 /*
2  * ompdModule.c
3  */
4 
5 //===----------------------------------------------------------------------===//
6 //
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include <Python.h>
14 #include <omp-tools.h>
15 // #include <ompd.h>
16 #include <dlfcn.h>
17 #include <errno.h>
18 #include <pthread.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 void *ompd_library;
24 
25 #define OMPD_WEAK_ATTR __attribute__((weak))
26 
27 struct _ompd_aspace_cont {
28   int id;
29 };
30 struct _ompd_thread_cont {
31   int id;
32 };
33 ompd_address_space_context_t acontext = {42};
34 
35 PyObject *pModule;
36 
37 ompd_rc_t _print(const char *str, int category);
38 
39 // NOTE: implement functions to check parameters of OMPD API functions for
40 // correctness
ompd_get_api_version(ompd_word_t * addr)41 OMPD_WEAK_ATTR ompd_rc_t ompd_get_api_version(ompd_word_t *addr) {
42   static ompd_rc_t (*my_get_api_version)(ompd_word_t *) = NULL;
43   if (!my_get_api_version) {
44     my_get_api_version = dlsym(ompd_library, "ompd_get_api_version");
45     if (dlerror()) {
46       return ompd_rc_error;
47     }
48   }
49   return my_get_api_version(addr);
50 }
51 
ompd_get_version_string(const char ** string)52 OMPD_WEAK_ATTR ompd_rc_t ompd_get_version_string(const char **string) {
53   static ompd_rc_t (*my_get_version_string)(const char **) = NULL;
54   if (!my_get_version_string) {
55     my_get_version_string = dlsym(ompd_library, "ompd_get_version_string");
56     if (dlerror()) {
57       return ompd_rc_error;
58     }
59   }
60   return my_get_version_string(string);
61 }
62 
ompd_finalize(void)63 OMPD_WEAK_ATTR ompd_rc_t ompd_finalize(void) {
64   static ompd_rc_t (*my_ompd_finalize)(void) = NULL;
65   if (!my_ompd_finalize) {
66     my_ompd_finalize = dlsym(ompd_library, "ompd_finalize");
67     if (dlerror()) {
68       return ompd_rc_error;
69     }
70   }
71   return my_ompd_finalize();
72 }
73 
74 OMPD_WEAK_ATTR ompd_rc_t
ompd_process_initialize(ompd_address_space_context_t * context,ompd_address_space_handle_t ** handle)75 ompd_process_initialize(ompd_address_space_context_t *context,
76                         ompd_address_space_handle_t **handle) {
77   static ompd_rc_t (*my_ompd_process_initialize)(
78       ompd_address_space_context_t *, ompd_address_space_handle_t **) = NULL;
79   if (!my_ompd_process_initialize) {
80     my_ompd_process_initialize = dlsym(ompd_library, "ompd_process_initialize");
81     if (dlerror()) {
82       return ompd_rc_error;
83     }
84   }
85   return my_ompd_process_initialize(context, handle);
86 }
87 
ompd_get_omp_version(ompd_address_space_handle_t * address_space,ompd_word_t * omp_version)88 OMPD_WEAK_ATTR ompd_rc_t ompd_get_omp_version(
89     ompd_address_space_handle_t *address_space, ompd_word_t *omp_version) {
90   static ompd_rc_t (*my_ompd_get_omp_version)(ompd_address_space_handle_t *,
91                                               ompd_word_t *) = NULL;
92   if (!my_ompd_get_omp_version) {
93     my_ompd_get_omp_version = dlsym(ompd_library, "ompd_get_omp_version");
94     if (dlerror()) {
95       return ompd_rc_error;
96     }
97   }
98   return my_ompd_get_omp_version(address_space, omp_version);
99 }
100 
ompd_get_omp_version_string(ompd_address_space_handle_t * address_space,const char ** string)101 OMPD_WEAK_ATTR ompd_rc_t ompd_get_omp_version_string(
102     ompd_address_space_handle_t *address_space, const char **string) {
103   static ompd_rc_t (*my_ompd_get_omp_version_string)(
104       ompd_address_space_handle_t *, const char **) = NULL;
105   if (!my_ompd_get_omp_version_string) {
106     my_ompd_get_omp_version_string =
107         dlsym(ompd_library, "ompd_get_omp_version_string");
108     if (dlerror()) {
109       return ompd_rc_error;
110     }
111   }
112   return my_ompd_get_omp_version_string(address_space, string);
113 }
114 
ompd_get_thread_handle(ompd_address_space_handle_t * handle,ompd_thread_id_t kind,ompd_size_t tidSize,const void * tid,ompd_thread_handle_t ** threadHandle)115 OMPD_WEAK_ATTR ompd_rc_t ompd_get_thread_handle(
116     ompd_address_space_handle_t *handle, ompd_thread_id_t kind,
117     ompd_size_t tidSize, const void *tid, ompd_thread_handle_t **threadHandle) {
118   static ompd_rc_t (*my_get_thread_handle)(
119       ompd_address_space_handle_t *, ompd_thread_id_t, ompd_size_t,
120       const void *, ompd_thread_handle_t **) = NULL;
121   if (!my_get_thread_handle) {
122     my_get_thread_handle = dlsym(ompd_library, "ompd_get_thread_handle");
123     if (dlerror()) {
124       return ompd_rc_error;
125     }
126   }
127   return my_get_thread_handle(handle, kind, tidSize, tid, threadHandle);
128 }
129 
ompd_get_thread_in_parallel(ompd_parallel_handle_t * parallelHandle,int threadNum,ompd_thread_handle_t ** threadHandle)130 OMPD_WEAK_ATTR ompd_rc_t ompd_get_thread_in_parallel(
131     ompd_parallel_handle_t *parallelHandle, int threadNum,
132     ompd_thread_handle_t **threadHandle) {
133   static ompd_rc_t (*my_get_thread_in_parallel)(ompd_parallel_handle_t *, int,
134                                                 ompd_thread_handle_t **) = NULL;
135   if (!my_get_thread_in_parallel) {
136     my_get_thread_in_parallel =
137         dlsym(ompd_library, "ompd_get_thread_in_parallel");
138     if (dlerror()) {
139       return ompd_rc_error;
140     }
141   }
142   return my_get_thread_in_parallel(parallelHandle, threadNum, threadHandle);
143 }
144 
ompd_thread_handle_compare(ompd_thread_handle_t * thread_handle1,ompd_thread_handle_t * thread_handle2,int * cmp_value)145 OMPD_WEAK_ATTR ompd_rc_t ompd_thread_handle_compare(
146     ompd_thread_handle_t *thread_handle1, ompd_thread_handle_t *thread_handle2,
147     int *cmp_value) {
148   static ompd_rc_t (*my_thread_handle_compare)(
149       ompd_thread_handle_t *, ompd_thread_handle_t *, int *) = NULL;
150   if (!my_thread_handle_compare) {
151     my_thread_handle_compare =
152         dlsym(ompd_library, "ompd_thread_handle_compare");
153     if (dlerror()) {
154       return ompd_rc_error;
155     }
156   }
157   return my_thread_handle_compare(thread_handle1, thread_handle2, cmp_value);
158 }
159 
160 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_curr_parallel_handle(ompd_thread_handle_t * threadHandle,ompd_parallel_handle_t ** parallelHandle)161 ompd_get_curr_parallel_handle(ompd_thread_handle_t *threadHandle,
162                               ompd_parallel_handle_t **parallelHandle) {
163   static ompd_rc_t (*my_get_current_parallel_handle)(
164       ompd_thread_handle_t *, ompd_parallel_handle_t **) = NULL;
165   if (!my_get_current_parallel_handle) {
166     my_get_current_parallel_handle =
167         dlsym(ompd_library, "ompd_get_curr_parallel_handle");
168     if (dlerror()) {
169       return ompd_rc_error;
170     }
171   }
172   return my_get_current_parallel_handle(threadHandle, parallelHandle);
173 }
174 
ompd_parallel_handle_compare(ompd_parallel_handle_t * parallel_handle_1,ompd_parallel_handle_t * parallel_handle_2,int * cmp_value)175 OMPD_WEAK_ATTR ompd_rc_t ompd_parallel_handle_compare(
176     ompd_parallel_handle_t *parallel_handle_1,
177     ompd_parallel_handle_t *parallel_handle_2, int *cmp_value) {
178   static ompd_rc_t (*my_parallel_handle_compare)(
179       ompd_parallel_handle_t *, ompd_parallel_handle_t *, int *) = NULL;
180   if (!my_parallel_handle_compare) {
181     my_parallel_handle_compare =
182         dlsym(ompd_library, "ompd_parallel_handle_compare");
183     if (dlerror()) {
184       return ompd_rc_error;
185     }
186   }
187   return my_parallel_handle_compare(parallel_handle_1, parallel_handle_2,
188                                     cmp_value);
189 }
190 
191 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_enclosing_parallel_handle(ompd_parallel_handle_t * parallelHandle,ompd_parallel_handle_t ** enclosing)192 ompd_get_enclosing_parallel_handle(ompd_parallel_handle_t *parallelHandle,
193                                    ompd_parallel_handle_t **enclosing) {
194   static ompd_rc_t (*my_get_enclosing_parallel_handle)(
195       ompd_parallel_handle_t *, ompd_parallel_handle_t **) = NULL;
196   if (!my_get_enclosing_parallel_handle) {
197     my_get_enclosing_parallel_handle =
198         dlsym(ompd_library, "ompd_get_enclosing_parallel_handle");
199     if (dlerror()) {
200       return ompd_rc_error;
201     }
202   }
203   return my_get_enclosing_parallel_handle(parallelHandle, enclosing);
204 }
205 
206 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_task_parallel_handle(ompd_task_handle_t * taskHandle,ompd_parallel_handle_t ** taskParallelHandle)207 ompd_get_task_parallel_handle(ompd_task_handle_t *taskHandle,
208                               ompd_parallel_handle_t **taskParallelHandle) {
209   static ompd_rc_t (*my_get_task_parallel_handle)(
210       ompd_task_handle_t *, ompd_parallel_handle_t **) = NULL;
211   if (!my_get_task_parallel_handle) {
212     my_get_task_parallel_handle =
213         dlsym(ompd_library, "ompd_get_task_parallel_handle");
214     if (dlerror()) {
215       return ompd_rc_error;
216     }
217   }
218   return my_get_task_parallel_handle(taskHandle, taskParallelHandle);
219 }
220 
ompd_get_curr_task_handle(ompd_thread_handle_t * threadHandle,ompd_task_handle_t ** taskHandle)221 OMPD_WEAK_ATTR ompd_rc_t ompd_get_curr_task_handle(
222     ompd_thread_handle_t *threadHandle, ompd_task_handle_t **taskHandle) {
223   static ompd_rc_t (*my_get_current_task_handle)(ompd_thread_handle_t *,
224                                                  ompd_task_handle_t **) = NULL;
225   if (!my_get_current_task_handle) {
226     my_get_current_task_handle =
227         dlsym(ompd_library, "ompd_get_curr_task_handle");
228     if (dlerror()) {
229       return ompd_rc_error;
230     }
231   }
232   return my_get_current_task_handle(threadHandle, taskHandle);
233 }
234 
ompd_get_generating_task_handle(ompd_task_handle_t * taskHandle,ompd_task_handle_t ** generating)235 OMPD_WEAK_ATTR ompd_rc_t ompd_get_generating_task_handle(
236     ompd_task_handle_t *taskHandle, ompd_task_handle_t **generating) {
237   static ompd_rc_t (*my_get_generating_task_handle)(
238       ompd_task_handle_t *, ompd_task_handle_t **) = NULL;
239   if (!my_get_generating_task_handle) {
240     my_get_generating_task_handle =
241         dlsym(ompd_library, "ompd_get_generating_task_handle");
242     if (dlerror()) {
243       return ompd_rc_error;
244     }
245   }
246   return my_get_generating_task_handle(taskHandle, generating);
247 }
248 
ompd_get_scheduling_task_handle(ompd_task_handle_t * taskHandle,ompd_task_handle_t ** scheduling)249 OMPD_WEAK_ATTR ompd_rc_t ompd_get_scheduling_task_handle(
250     ompd_task_handle_t *taskHandle, ompd_task_handle_t **scheduling) {
251   static ompd_rc_t (*my_get_scheduling_task_handle)(
252       ompd_task_handle_t *, ompd_task_handle_t **) = NULL;
253   if (!my_get_scheduling_task_handle) {
254     my_get_scheduling_task_handle =
255         dlsym(ompd_library, "ompd_get_scheduling_task_handle");
256     if (dlerror()) {
257       return ompd_rc_error;
258     }
259   }
260   return my_get_scheduling_task_handle(taskHandle, scheduling);
261 }
262 
263 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_task_in_parallel(ompd_parallel_handle_t * parallelHandle,int threadNum,ompd_task_handle_t ** taskHandle)264 ompd_get_task_in_parallel(ompd_parallel_handle_t *parallelHandle, int threadNum,
265                           ompd_task_handle_t **taskHandle) {
266   static ompd_rc_t (*my_get_task_in_parallel)(ompd_parallel_handle_t *, int,
267                                               ompd_task_handle_t **) = NULL;
268   if (!my_get_task_in_parallel) {
269     my_get_task_in_parallel = dlsym(ompd_library, "ompd_get_task_in_parallel");
270     if (dlerror()) {
271       return ompd_rc_error;
272     }
273   }
274   return my_get_task_in_parallel(parallelHandle, threadNum, taskHandle);
275 }
276 
ompd_get_task_frame(ompd_task_handle_t * taskHandle,ompd_frame_info_t * exitFrame,ompd_frame_info_t * enterFrame)277 OMPD_WEAK_ATTR ompd_rc_t ompd_get_task_frame(ompd_task_handle_t *taskHandle,
278                                              ompd_frame_info_t *exitFrame,
279                                              ompd_frame_info_t *enterFrame) {
280   static ompd_rc_t (*my_get_task_frame)(
281       ompd_task_handle_t *, ompd_frame_info_t *, ompd_frame_info_t *) = NULL;
282   if (!my_get_task_frame) {
283     my_get_task_frame = dlsym(ompd_library, "ompd_get_task_frame");
284     if (dlerror()) {
285       return ompd_rc_error;
286     }
287   }
288   return my_get_task_frame(taskHandle, exitFrame, enterFrame);
289 }
290 
ompd_get_icv_from_scope(void * handle,ompd_scope_t scope,ompd_icv_id_t icvId,ompd_word_t * icvValue)291 OMPD_WEAK_ATTR ompd_rc_t ompd_get_icv_from_scope(void *handle,
292                                                  ompd_scope_t scope,
293                                                  ompd_icv_id_t icvId,
294                                                  ompd_word_t *icvValue) {
295   static ompd_rc_t (*my_get_icv_from_scope)(void *, ompd_scope_t, ompd_icv_id_t,
296                                             ompd_word_t *) = NULL;
297   if (!my_get_icv_from_scope) {
298     my_get_icv_from_scope = dlsym(ompd_library, "ompd_get_icv_from_scope");
299     if (dlerror()) {
300       return ompd_rc_error;
301     }
302   }
303   return my_get_icv_from_scope(handle, scope, icvId, icvValue);
304 }
305 
306 OMPD_WEAK_ATTR ompd_rc_t
ompd_enumerate_icvs(ompd_address_space_handle_t * handle,ompd_icv_id_t current,ompd_icv_id_t * next,const char ** nextIcvName,ompd_scope_t * nextScope,int * more)307 ompd_enumerate_icvs(ompd_address_space_handle_t *handle, ompd_icv_id_t current,
308                     ompd_icv_id_t *next, const char **nextIcvName,
309                     ompd_scope_t *nextScope, int *more) {
310   static ompd_rc_t (*my_enumerate_icvs)(
311       ompd_address_space_handle_t *, ompd_icv_id_t, ompd_icv_id_t *,
312       const char **, ompd_scope_t *, int *) = NULL;
313   if (!my_enumerate_icvs) {
314     my_enumerate_icvs = dlsym(ompd_library, "ompd_enumerate_icvs");
315     if (dlerror()) {
316       return ompd_rc_error;
317     }
318   }
319   return my_enumerate_icvs(handle, current, next, nextIcvName, nextScope, more);
320 }
321 
322 OMPD_WEAK_ATTR ompd_rc_t
ompd_enumerate_states(ompd_address_space_handle_t * addrSpaceHandle,ompd_word_t currentState,ompd_word_t * nextState,const char ** nextStateName,ompd_word_t * moreEnums)323 ompd_enumerate_states(ompd_address_space_handle_t *addrSpaceHandle,
324                       ompd_word_t currentState, ompd_word_t *nextState,
325                       const char **nextStateName, ompd_word_t *moreEnums) {
326   static ompd_rc_t (*my_enumerate_states)(ompd_address_space_handle_t *,
327                                           ompd_word_t, ompd_word_t *,
328                                           const char **, ompd_word_t *) = NULL;
329   if (!my_enumerate_states) {
330     my_enumerate_states = dlsym(ompd_library, "ompd_enumerate_states");
331     if (dlerror()) {
332       return ompd_rc_error;
333     }
334   }
335   return my_enumerate_states(addrSpaceHandle, currentState, nextState,
336                              nextStateName, moreEnums);
337 }
338 
ompd_get_state(ompd_thread_handle_t * threadHandle,ompd_word_t * state,ompd_wait_id_t * waitId)339 OMPD_WEAK_ATTR ompd_rc_t ompd_get_state(ompd_thread_handle_t *threadHandle,
340                                         ompd_word_t *state,
341                                         ompd_wait_id_t *waitId) {
342   static ompd_rc_t (*my_get_state)(ompd_thread_handle_t *, ompd_word_t *,
343                                    ompd_wait_id_t *) = NULL;
344   if (!my_get_state) {
345     my_get_state = dlsym(ompd_library, "ompd_get_state");
346     if (dlerror()) {
347       return ompd_rc_error;
348     }
349   }
350   return my_get_state(threadHandle, state, waitId);
351 }
352 
ompd_get_task_function(ompd_task_handle_t * taskHandle,ompd_address_t * entryPoint)353 OMPD_WEAK_ATTR ompd_rc_t ompd_get_task_function(ompd_task_handle_t *taskHandle,
354                                                 ompd_address_t *entryPoint) {
355   static ompd_rc_t (*my_get_task_function)(ompd_task_handle_t *,
356                                            ompd_address_t *) = NULL;
357   if (!my_get_task_function) {
358     my_get_task_function = dlsym(ompd_library, "ompd_get_task_function");
359     if (dlerror()) {
360       return ompd_rc_error;
361     }
362   }
363   return my_get_task_function(taskHandle, entryPoint);
364 }
365 
ompd_get_thread_id(ompd_thread_handle_t * threadHandle,ompd_thread_id_t kind,ompd_size_t tidSize,void * tid)366 OMPD_WEAK_ATTR ompd_rc_t ompd_get_thread_id(ompd_thread_handle_t *threadHandle,
367                                             ompd_thread_id_t kind,
368                                             ompd_size_t tidSize, void *tid) {
369   static ompd_rc_t (*my_get_thread_id)(ompd_thread_handle_t *, ompd_thread_id_t,
370                                        ompd_size_t, void *) = NULL;
371   if (!my_get_thread_id) {
372     my_get_thread_id = dlsym(ompd_library, "ompd_get_thread_id");
373     if (dlerror()) {
374       return ompd_rc_error;
375     }
376   }
377   return my_get_thread_id(threadHandle, kind, tidSize, tid);
378 }
379 
ompd_get_tool_data(void * handle,ompd_scope_t scope,ompd_word_t * value,ompd_address_t * ptr)380 OMPD_WEAK_ATTR ompd_rc_t ompd_get_tool_data(void *handle, ompd_scope_t scope,
381                                             ompd_word_t *value,
382                                             ompd_address_t *ptr) {
383   static ompd_rc_t (*my_get_tool_data)(void *, ompd_scope_t, ompd_word_t *,
384                                        ompd_address_t *) = NULL;
385   if (!my_get_tool_data) {
386     my_get_tool_data = dlsym(ompd_library, "ompd_get_tool_data");
387     if (dlerror()) {
388       return ompd_rc_error;
389     }
390   }
391   return my_get_tool_data(handle, scope, value, ptr);
392 }
393 
394 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_icv_string_from_scope(void * handle,ompd_scope_t scope,ompd_icv_id_t icvId,const char ** icvString)395 ompd_get_icv_string_from_scope(void *handle, ompd_scope_t scope,
396                                ompd_icv_id_t icvId, const char **icvString) {
397   static ompd_rc_t (*my_get_icv_string_from_scope)(
398       void *, ompd_scope_t, ompd_icv_id_t, const char **) = NULL;
399   if (!my_get_icv_string_from_scope) {
400     my_get_icv_string_from_scope =
401         dlsym(ompd_library, "ompd_get_icv_string_from_scope");
402     if (dlerror()) {
403       return ompd_rc_error;
404     }
405   }
406   return my_get_icv_string_from_scope(handle, scope, icvId, icvString);
407 }
408 
409 OMPD_WEAK_ATTR ompd_rc_t
ompd_rel_thread_handle(ompd_thread_handle_t * threadHandle)410 ompd_rel_thread_handle(ompd_thread_handle_t *threadHandle) {
411   static ompd_rc_t (*my_release_thread_handle)(ompd_thread_handle_t *) = NULL;
412   if (!my_release_thread_handle) {
413     my_release_thread_handle = dlsym(ompd_library, "ompd_rel_thread_handle");
414     if (dlerror()) {
415       return ompd_rc_error;
416     }
417   }
418   return my_release_thread_handle(threadHandle);
419 }
420 
421 OMPD_WEAK_ATTR ompd_rc_t
ompd_rel_parallel_handle(ompd_parallel_handle_t * parallelHandle)422 ompd_rel_parallel_handle(ompd_parallel_handle_t *parallelHandle) {
423   static ompd_rc_t (*my_release_parallel_handle)(ompd_parallel_handle_t *) =
424       NULL;
425   if (!my_release_parallel_handle) {
426     my_release_parallel_handle =
427         dlsym(ompd_library, "ompd_rel_parallel_handle");
428     if (dlerror()) {
429       return ompd_rc_error;
430     }
431   }
432   return my_release_parallel_handle(parallelHandle);
433 }
434 
ompd_rel_task_handle(ompd_task_handle_t * taskHandle)435 OMPD_WEAK_ATTR ompd_rc_t ompd_rel_task_handle(ompd_task_handle_t *taskHandle) {
436   static ompd_rc_t (*my_release_task_handle)(ompd_task_handle_t *) = NULL;
437   if (!my_release_task_handle) {
438     my_release_task_handle = dlsym(ompd_library, "ompd_rel_task_handle");
439     if (dlerror()) {
440       return ompd_rc_error;
441     }
442   }
443   return my_release_task_handle(taskHandle);
444 }
445 
446 OMPD_WEAK_ATTR ompd_rc_t
ompd_task_handle_compare(ompd_task_handle_t * task_handle_1,ompd_task_handle_t * task_handle_2,int * cmp_value)447 ompd_task_handle_compare(ompd_task_handle_t *task_handle_1,
448                          ompd_task_handle_t *task_handle_2, int *cmp_value) {
449   static ompd_rc_t (*my_task_handle_compare)(
450       ompd_task_handle_t *, ompd_task_handle_t *, int *) = NULL;
451   if (!my_task_handle_compare) {
452     my_task_handle_compare = dlsym(ompd_library, "ompd_task_handle_compare");
453     if (dlerror()) {
454       return ompd_rc_error;
455     }
456   }
457   return my_task_handle_compare(task_handle_1, task_handle_2, cmp_value);
458 }
459 
460 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_display_control_vars(ompd_address_space_handle_t * address_space_handle,const char * const ** control_vars)461 ompd_get_display_control_vars(ompd_address_space_handle_t *address_space_handle,
462                               const char *const **control_vars) {
463   static ompd_rc_t (*my_ompd_get_display_control_vars)(
464       ompd_address_space_handle_t *, const char *const **) = NULL;
465   if (!my_ompd_get_display_control_vars) {
466     my_ompd_get_display_control_vars =
467         dlsym(ompd_library, "ompd_get_display_control_vars");
468     if (dlerror()) {
469       return ompd_rc_error;
470     }
471   }
472   return my_ompd_get_display_control_vars(address_space_handle, control_vars);
473 }
474 
475 /**
476  * Loads the OMPD library (libompd.so). Returns an integer with the version if
477  * the OMPD library could be loaded successfully. Error codes: -1: argument
478  * could not be converted to string -2: error when calling dlopen -3: error when
479  * fetching version of OMPD API else: see ompd return codes
480  */
ompd_open(PyObject * self,PyObject * args)481 static PyObject *ompd_open(PyObject *self, PyObject *args) {
482   const char *name, *dlerr;
483   dlerror();
484   if (!PyArg_ParseTuple(args, "s", &name)) {
485     return Py_BuildValue("i", -1);
486   }
487   ompd_library = dlopen(name, RTLD_LAZY);
488   if ((dlerr = dlerror())) {
489     return Py_BuildValue("i", -2);
490   }
491   if (dlerror()) {
492     return Py_BuildValue("i", -3);
493   }
494   ompd_word_t version;
495   ompd_rc_t rc = ompd_get_api_version(&version);
496   if (rc != ompd_rc_ok)
497     return Py_BuildValue("l", -10 - rc);
498 
499   int returnValue = version;
500   return Py_BuildValue("i", returnValue);
501 }
502 
503 /**
504  * Have the debugger print a string.
505  */
_print(const char * str,int category)506 ompd_rc_t _print(const char *str, int category) {
507   PyObject *pFunc = PyObject_GetAttrString(pModule, "_print");
508   if (pFunc && PyCallable_Check(pFunc)) {
509     PyObject *pArgs = PyTuple_New(1);
510     PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", str));
511     PyObject_CallObject(pFunc, pArgs);
512     Py_XDECREF(pArgs);
513   }
514   Py_XDECREF(pFunc);
515   return ompd_rc_ok;
516 }
517 
_printf(const char * format,...)518 void _printf(const char *format, ...) {
519   va_list args;
520   va_start(args, format);
521   char output[1024];
522   vsnprintf(output, 1024, format, args);
523   va_end(args);
524   _print(output, 0);
525 }
526 
527 /**
528  * Capsule destructors for thread, parallel and task handles.
529  */
call_ompd_rel_thread_handle_temp(PyObject * capsule)530 static void call_ompd_rel_thread_handle_temp(PyObject *capsule) {
531   ompd_thread_handle_t *threadHandle =
532       (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule, "ThreadHandle"));
533 
534   ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle);
535   if (retVal != ompd_rc_ok) {
536     _printf(
537         "An error occurred when calling ompd_rel_thread_handle! Error code: %d",
538         retVal);
539   }
540 }
541 
destroyThreadCapsule(PyObject * capsule)542 static void destroyThreadCapsule(PyObject *capsule) {
543   call_ompd_rel_thread_handle_temp(capsule);
544 }
545 static void (*my_thread_capsule_destructor)(PyObject *) = destroyThreadCapsule;
546 
call_ompd_rel_parallel_handle_temp(PyObject * capsule)547 static void call_ompd_rel_parallel_handle_temp(PyObject *capsule) {
548   ompd_parallel_handle_t *parallelHandle =
549       (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule,
550                                                       "ParallelHandle"));
551 
552   ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle);
553   if (retVal != ompd_rc_ok) {
554     _printf("An error occurred when calling ompd_rel_parallel_handle! Error "
555             "code: %d",
556             retVal);
557   }
558 }
559 
destroyParallelCapsule(PyObject * capsule)560 static void destroyParallelCapsule(PyObject *capsule) {
561   call_ompd_rel_parallel_handle_temp(capsule);
562 }
563 static void (*my_parallel_capsule_destructor)(PyObject *) =
564     destroyParallelCapsule;
565 
call_ompd_rel_task_handle_temp(PyObject * capsule)566 static void call_ompd_rel_task_handle_temp(PyObject *capsule) {
567   ompd_task_handle_t *taskHandle =
568       (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule, "TaskHandle"));
569 
570   ompd_rc_t retVal = ompd_rel_task_handle(taskHandle);
571   if (retVal != ompd_rc_ok) {
572     _printf("An error occurred when calling ompd_rel_task_handle!\n");
573   }
574 }
575 
destroyTaskCapsule(PyObject * capsule)576 static void destroyTaskCapsule(PyObject *capsule) {
577   call_ompd_rel_task_handle_temp(capsule);
578 }
579 static void (*my_task_capsule_destructor)(PyObject *) = destroyTaskCapsule;
580 
581 /**
582  * Release thread handle. Called inside destructor for Python thread_handle
583  * object.
584  */
call_ompd_rel_thread_handle(PyObject * self,PyObject * args)585 static PyObject *call_ompd_rel_thread_handle(PyObject *self, PyObject *args) {
586   PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
587   ompd_thread_handle_t *threadHandle =
588       (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,
589                                                     "ThreadHandle"));
590 
591   ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle);
592   if (retVal != ompd_rc_ok) {
593     _printf(
594         "An error occurred when calling ompd_rel_thread_handle! Error code: %d",
595         retVal);
596   }
597   return Py_BuildValue("l", retVal);
598 }
599 
600 /**
601  * Allocate memory in the debugger's address space.
602  */
_alloc(ompd_size_t bytes,void ** ptr)603 ompd_rc_t _alloc(ompd_size_t bytes, void **ptr) {
604   if (ptr == NULL) {
605     return ompd_rc_bad_input;
606   }
607   *ptr = malloc(bytes);
608   return ompd_rc_ok;
609 }
610 
611 /**
612  * Free memory in the debugger's address space.
613  */
_free(void * ptr)614 ompd_rc_t _free(void *ptr) {
615   free(ptr);
616   return ompd_rc_ok;
617 }
618 
619 /**
620  * Look up the sizes of primitive types in the target.
621  */
_sizes(ompd_address_space_context_t * _acontext,ompd_device_type_sizes_t * sizes)622 ompd_rc_t _sizes(ompd_address_space_context_t *_acontext, /* IN */
623                  ompd_device_type_sizes_t *sizes)         /* OUT */
624 {
625   if (acontext.id != _acontext->id)
626     return ompd_rc_stale_handle;
627   ompd_device_type_sizes_t mysizes = {
628       (uint8_t)sizeof(char),      (uint8_t)sizeof(short),
629       (uint8_t)sizeof(int),       (uint8_t)sizeof(long),
630       (uint8_t)sizeof(long long), (uint8_t)sizeof(void *)};
631   *sizes = mysizes;
632   return ompd_rc_ok;
633 }
634 
635 /**
636  * Look up the address of a global symbol in the target.
637  */
_sym_addr(ompd_address_space_context_t * context,ompd_thread_context_t * tcontext,const char * symbol_name,ompd_address_t * symbol_addr,const char * file_name)638 ompd_rc_t _sym_addr(ompd_address_space_context_t *context, /* IN */
639                     ompd_thread_context_t *tcontext,       /* IN */
640                     const char *symbol_name,               /* IN */
641                     ompd_address_t *symbol_addr,           /* OUT */
642                     const char *file_name)                 /* IN */
643 {
644   int thread_id = -1;
645   PyObject *symbolAddress;
646   if (tcontext != NULL) {
647     thread_id = tcontext->id;
648   }
649   PyObject *pFunc = PyObject_GetAttrString(pModule, "_sym_addr");
650   if (pFunc && PyCallable_Check(pFunc)) {
651     PyObject *pArgs = PyTuple_New(2);
652     PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", thread_id));
653     PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", symbol_name));
654     symbolAddress = PyObject_CallObject(pFunc, pArgs);
655     if (symbolAddress == NULL) {
656       PyErr_Print();
657     }
658     symbol_addr->address = PyLong_AsLong(symbolAddress);
659     Py_XDECREF(pArgs);
660     Py_XDECREF(symbolAddress);
661   }
662   Py_XDECREF(pFunc);
663   return ompd_rc_ok;
664 }
665 
666 /**
667  * Read memory from the target.
668  */
_read(ompd_address_space_context_t * context,ompd_thread_context_t * tcontext,const ompd_address_t * addr,ompd_size_t nbytes,void * buffer)669 ompd_rc_t _read(ompd_address_space_context_t *context, /* IN */
670                 ompd_thread_context_t *tcontext,       /* IN */
671                 const ompd_address_t *addr,            /* IN */
672                 ompd_size_t nbytes,                    /* IN */
673                 void *buffer)                          /* OUT */
674 {
675   uint64_t readMem = (uint64_t)addr->address;
676   PyObject *pFunc = PyObject_GetAttrString(pModule, "_read");
677   if (pFunc && PyCallable_Check(pFunc)) {
678     PyObject *pArgs = PyTuple_New(2);
679     PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", readMem));
680     PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", nbytes));
681     PyObject *retArray = PyObject_CallObject(pFunc, pArgs);
682     Py_XDECREF(pArgs);
683     if (retArray == NULL) {
684       PyErr_Print();
685     }
686     if (!PyByteArray_Check(retArray)) {
687       return ompd_rc_error;
688     }
689     Py_ssize_t retSize = PyByteArray_Size(retArray);
690     const char *strBuf = PyByteArray_AsString(retArray);
691     if ((ompd_size_t)retSize != nbytes) {
692       return ompd_rc_error;
693     }
694     memcpy(buffer, strBuf, nbytes);
695     Py_XDECREF(retArray);
696   }
697   Py_XDECREF(pFunc);
698   return ompd_rc_ok;
699 }
700 
701 /**
702  * Reads string from target.
703  */
_read_string(ompd_address_space_context_t * context,ompd_thread_context_t * tcontext,const ompd_address_t * addr,ompd_size_t nbytes,void * buffer)704 ompd_rc_t _read_string(ompd_address_space_context_t *context, /* IN */
705                        ompd_thread_context_t *tcontext,       /* IN */
706                        const ompd_address_t *addr,            /* IN */
707                        ompd_size_t nbytes,                    /* IN */
708                        void *buffer)                          /* OUT */
709 {
710   ompd_rc_t retVal = ompd_rc_ok;
711   uint64_t readMem = (uint64_t)addr->address;
712   PyObject *pFunc = PyObject_GetAttrString(pModule, "_read_string");
713   PyObject *pArgs = PyTuple_New(1);
714   PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", readMem));
715   PyObject *retString = PyObject_CallObject(pFunc, pArgs);
716   Py_XDECREF(pArgs);
717   if (!PyUnicode_Check(retString)) {
718     return ompd_rc_error;
719   }
720   Py_ssize_t retSize;
721   const char *strbuffer = PyUnicode_AsUTF8AndSize(retString, &retSize);
722   if ((ompd_size_t)retSize + 1 >= nbytes) {
723     retVal = ompd_rc_incomplete;
724   }
725   strncpy(buffer, strbuffer, nbytes);
726   ((char *)buffer)[nbytes - 1] = '\0';
727   return retVal;
728 }
729 
730 /**
731  * Write memory from the target.
732  */
733 ompd_rc_t
_endianess(ompd_address_space_context_t * address_space_context,const void * input,ompd_size_t unit_size,ompd_size_t count,void * output)734 _endianess(ompd_address_space_context_t *address_space_context, /* IN */
735            const void *input,                                   /* IN */
736            ompd_size_t unit_size,                               /* IN */
737            ompd_size_t count, /* IN: number of primitive type */
738            void *output) {
739   if (acontext.id != address_space_context->id)
740     return ompd_rc_stale_handle;
741   memmove(output, input, count * unit_size);
742   return ompd_rc_ok;
743 }
744 
745 /**
746  * Returns thread context for thread id; helper function for _thread_context
747  * callback.
748  */
get_thread_context(int id)749 ompd_thread_context_t *get_thread_context(int id) {
750   static ompd_thread_context_t *tc = NULL;
751   static int size = 0;
752   int i;
753   if (id < 1)
754     return NULL;
755   if (tc == NULL) {
756     size = 16;
757     tc = malloc(size * sizeof(ompd_thread_context_t));
758     for (i = 0; i < size; i++)
759       tc[i].id = i + 1;
760   }
761   if (id - 1 >= size) {
762     size += 16;
763     tc = realloc(tc, size * sizeof(ompd_thread_context_t));
764     for (i = 0; i < size; i++)
765       tc[i].id = i + 1;
766   }
767   return tc + id - 1;
768 }
769 
770 /**
771  * Get thread specific context.
772  */
773 ompd_rc_t
_thread_context(ompd_address_space_context_t * context,ompd_thread_id_t kind,ompd_size_t sizeof_thread_id,const void * thread_id,ompd_thread_context_t ** thread_context)774 _thread_context(ompd_address_space_context_t *context, /* IN */
775                 ompd_thread_id_t kind,        /* IN, 0 for pthread, 1 for lwp */
776                 ompd_size_t sizeof_thread_id, /* IN */
777                 const void *thread_id,        /* IN */
778                 ompd_thread_context_t **thread_context) /* OUT */
779 {
780   if (acontext.id != context->id)
781     return ompd_rc_stale_handle;
782   if (kind != 0 && kind != 1)
783     return ompd_rc_unsupported;
784   long int tid;
785   if (sizeof(long int) >= 8 && sizeof_thread_id == 8)
786     tid = *(const uint64_t *)thread_id;
787   else if (sizeof(long int) >= 4 && sizeof_thread_id == 4)
788     tid = *(const uint32_t *)thread_id;
789   else if (sizeof(long int) >= 2 && sizeof_thread_id == 2)
790     tid = *(const uint16_t *)thread_id;
791   else
792     return ompd_rc_bad_input;
793   PyObject *pFunc = PyObject_GetAttrString(pModule, "_thread_context");
794   if (pFunc && PyCallable_Check(pFunc)) {
795     PyObject *pArgs = PyTuple_New(2);
796     PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", kind));
797     PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", tid));
798     PyObject *res = PyObject_CallObject(pFunc, pArgs);
799     int resAsInt = (int)PyLong_AsLong(res);
800     if (resAsInt == -1) {
801       // NOTE: could not find match for thread_id
802       return ompd_rc_unavailable;
803     }
804     (*thread_context) = get_thread_context(resAsInt);
805     Py_XDECREF(pArgs);
806     Py_XDECREF(res);
807     Py_XDECREF(pFunc);
808     if (*thread_context == NULL) {
809       return ompd_rc_bad_input;
810     }
811     return ompd_rc_ok;
812   }
813   Py_XDECREF(pFunc);
814   return ompd_rc_error;
815 }
816 
817 /**
818  * Calls ompd_process_initialize; returns pointer to ompd_address_space_handle.
819  */
call_ompd_initialize(PyObject * self,PyObject * noargs)820 static PyObject *call_ompd_initialize(PyObject *self, PyObject *noargs) {
821   pModule = PyImport_Import(PyUnicode_FromString("ompd_callbacks"));
822 
823   static ompd_callbacks_t table = {
824       _alloc, _free,        _print,     _sizes,     _sym_addr,      _read,
825       NULL,   _read_string, _endianess, _endianess, _thread_context};
826 
827   ompd_rc_t (*my_ompd_init)(ompd_word_t version, ompd_callbacks_t *) =
828       dlsym(ompd_library, "ompd_initialize");
829   ompd_rc_t returnInit = my_ompd_init(201811, &table);
830   if (returnInit != ompd_rc_ok) {
831     _printf("An error occurred when calling ompd_initialize! Error code: %d",
832             returnInit);
833   }
834   ompd_address_space_handle_t *addr_space = NULL;
835   ompd_rc_t (*my_proc_init)(ompd_address_space_context_t *,
836                             ompd_address_space_handle_t **) =
837       dlsym(ompd_library, "ompd_process_initialize");
838   ompd_rc_t retProcInit = my_proc_init(&acontext, &addr_space);
839   if (retProcInit != ompd_rc_ok) {
840     _printf("An error occurred when calling ompd_process_initialize! Error "
841             "code: %d",
842             retProcInit);
843   }
844   return PyCapsule_New(addr_space, "AddressSpace", NULL);
845 }
846 
847 /**
848  * Returns a PyCapsule pointer to thread handle for thread with the given id.
849  */
get_thread_handle(PyObject * self,PyObject * args)850 static PyObject *get_thread_handle(PyObject *self, PyObject *args) {
851   PyObject *threadIdTup = PyTuple_GetItem(args, 0);
852   uint64_t threadId = (uint64_t)PyLong_AsLong(threadIdTup);
853   // NOTE: compiler does not know what thread handle looks like, so no memory
854   // is allocated automatically in the debugger's memory space
855 
856   PyObject *addrSpaceTup = PyTuple_GetItem(args, 1);
857   ompd_thread_handle_t *threadHandle;
858   ompd_address_space_handle_t *addrSpace =
859       (ompd_address_space_handle_t *)PyCapsule_GetPointer(addrSpaceTup,
860                                                           "AddressSpace");
861 
862   ompd_size_t sizeof_tid = (ompd_size_t)sizeof(uint64_t);
863   ompd_rc_t retVal = ompd_get_thread_handle(addrSpace, 1, sizeof_tid, &threadId,
864                                             &threadHandle);
865 
866   if (retVal == ompd_rc_unavailable) {
867     return Py_BuildValue("i", -1);
868   } else if (retVal != ompd_rc_ok) {
869     _printf(
870         "An error occured when calling ompd_get_thread_handle! Error code: %d",
871         retVal);
872     return Py_BuildValue("l", retVal);
873   }
874   return PyCapsule_New(threadHandle, "ThreadHandle",
875                        my_thread_capsule_destructor);
876 }
877 
878 /**
879  * Returns a PyCapsule pointer to a thread handle for a specific thread id in
880  * the current parallel context.
881  */
call_ompd_get_thread_in_parallel(PyObject * self,PyObject * args)882 static PyObject *call_ompd_get_thread_in_parallel(PyObject *self,
883                                                   PyObject *args) {
884   PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
885   int threadNum = (int)PyLong_AsLong(PyTuple_GetItem(args, 1));
886   ompd_parallel_handle_t *parallelHandle =
887       (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,
888                                                       "ParallelHandle"));
889   ompd_thread_handle_t *threadHandle;
890 
891   ompd_rc_t retVal =
892       ompd_get_thread_in_parallel(parallelHandle, threadNum, &threadHandle);
893 
894   if (retVal != ompd_rc_ok) {
895     _printf("An error occurred when calling ompd_get_thread_in_parallel! Error "
896             "code: %d",
897             retVal);
898     return Py_BuildValue("l", retVal);
899   }
900   return PyCapsule_New(threadHandle, "ThreadHandle",
901                        my_thread_capsule_destructor);
902 }
903 
904 /**
905  * Returns a PyCapsule pointer to the parallel handle of the current parallel
906  * region associated with a thread.
907  */
call_ompd_get_curr_parallel_handle(PyObject * self,PyObject * args)908 static PyObject *call_ompd_get_curr_parallel_handle(PyObject *self,
909                                                     PyObject *args) {
910   PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
911   ompd_thread_handle_t *threadHandle =
912       (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,
913                                                     "ThreadHandle"));
914   ompd_parallel_handle_t *parallelHandle;
915 
916   ompd_rc_t retVal =
917       ompd_get_curr_parallel_handle(threadHandle, &parallelHandle);
918 
919   if (retVal != ompd_rc_ok) {
920     _printf("An error occurred when calling ompd_get_curr_parallel_handle! "
921             "Error code: %d",
922             retVal);
923     return Py_BuildValue("l", retVal);
924   }
925   return PyCapsule_New(parallelHandle, "ParallelHandle",
926                        my_parallel_capsule_destructor);
927 }
928 
929 /**
930  * Returns a PyCapsule pointer to the parallel  handle for the parallel region
931  * enclosing the parallel region specified by parallel_handle.
932  */
call_ompd_get_enclosing_parallel_handle(PyObject * self,PyObject * args)933 static PyObject *call_ompd_get_enclosing_parallel_handle(PyObject *self,
934                                                          PyObject *args) {
935   PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
936   ompd_parallel_handle_t *parallelHandle =
937       (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,
938                                                       "ParallelHandle"));
939   ompd_parallel_handle_t *enclosingParallelHandle;
940 
941   ompd_rc_t retVal = ompd_get_enclosing_parallel_handle(
942       parallelHandle, &enclosingParallelHandle);
943 
944   if (retVal != ompd_rc_ok) {
945     _printf("An error occurred when calling "
946             "ompd_get_enclosing_parallel_handle! Error code: %d",
947             retVal);
948     return Py_BuildValue("l", retVal);
949   }
950   return PyCapsule_New(enclosingParallelHandle, "ParallelHandle",
951                        my_parallel_capsule_destructor);
952 }
953 
954 /**
955  * Returns a PyCapsule pointer to the parallel handle for the parallel region
956  * enclosing the task specified.
957  */
call_ompd_get_task_parallel_handle(PyObject * self,PyObject * args)958 static PyObject *call_ompd_get_task_parallel_handle(PyObject *self,
959                                                     PyObject *args) {
960   PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
961   ompd_task_handle_t *taskHandle =
962       PyCapsule_GetPointer(taskHandlePy, "TaskHandle");
963   ompd_parallel_handle_t *taskParallelHandle;
964 
965   ompd_rc_t retVal =
966       ompd_get_task_parallel_handle(taskHandle, &taskParallelHandle);
967 
968   if (retVal != ompd_rc_ok) {
969     _printf("An error occurred when calling ompd_get_task_parallel_handle! "
970             "Error code: %d");
971     return Py_BuildValue("l", retVal);
972   }
973   return PyCapsule_New(taskParallelHandle, "ParallelHandle",
974                        my_parallel_capsule_destructor);
975 }
976 
977 /**
978  * Releases a parallel handle; is called in by the destructor of a Python
979  * parallel_handle object.
980  */
call_ompd_rel_parallel_handle(PyObject * self,PyObject * args)981 static PyObject *call_ompd_rel_parallel_handle(PyObject *self, PyObject *args) {
982   PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
983   ompd_parallel_handle_t *parallelHandle =
984       (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,
985                                                       "ParallelHandle"));
986 
987   ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle);
988   if (retVal != ompd_rc_ok) {
989     _printf("An error occurred when calling ompd_rel_parallel_handle! Error "
990             "code: %d",
991             retVal);
992   }
993   return Py_BuildValue("l", retVal);
994 }
995 
996 /**
997  * Returns a PyCapsule pointer to the task handle of the current task region
998  * associated with a thread.
999  */
call_ompd_get_curr_task_handle(PyObject * self,PyObject * args)1000 static PyObject *call_ompd_get_curr_task_handle(PyObject *self,
1001                                                 PyObject *args) {
1002   PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
1003   ompd_thread_handle_t *threadHandle =
1004       (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,
1005                                                     "ThreadHandle"));
1006   ompd_task_handle_t *taskHandle;
1007 
1008   ompd_rc_t retVal = ompd_get_curr_task_handle(threadHandle, &taskHandle);
1009 
1010   if (retVal != ompd_rc_ok) {
1011     _printf("An error occurred when calling ompd_get_curr_task_handle! Error "
1012             "code: %d",
1013             retVal);
1014     return Py_BuildValue("l", retVal);
1015   }
1016   return PyCapsule_New(taskHandle, "TaskHandle", my_task_capsule_destructor);
1017 }
1018 
1019 /**
1020  * Returns a task handle for the task that created the task specified.
1021  */
call_ompd_get_generating_task_handle(PyObject * self,PyObject * args)1022 static PyObject *call_ompd_get_generating_task_handle(PyObject *self,
1023                                                       PyObject *args) {
1024   PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1025   ompd_task_handle_t *taskHandle =
1026       (ompd_task_handle_t *)(PyCapsule_GetPointer(taskHandlePy, "TaskHandle"));
1027   ompd_task_handle_t *generatingTaskHandle;
1028 
1029   ompd_rc_t retVal =
1030       ompd_get_generating_task_handle(taskHandle, &generatingTaskHandle);
1031 
1032   if (retVal != ompd_rc_ok) {
1033     _printf("An error occurred when calling ompd_get_generating_task_handle! "
1034             "Error code: %d",
1035             retVal);
1036     return Py_BuildValue("l", retVal);
1037   }
1038   return PyCapsule_New(generatingTaskHandle, "TaskHandle",
1039                        my_task_capsule_destructor);
1040 }
1041 
1042 /**
1043  * Returns the task handle for the task that scheduled the task specified.
1044  */
call_ompd_get_scheduling_task_handle(PyObject * self,PyObject * args)1045 static PyObject *call_ompd_get_scheduling_task_handle(PyObject *self,
1046                                                       PyObject *args) {
1047   PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1048   ompd_task_handle_t *taskHandle =
1049       (ompd_task_handle_t *)(PyCapsule_GetPointer(taskHandlePy, "TaskHandle"));
1050   ompd_task_handle_t *schedulingTaskHandle;
1051 
1052   ompd_rc_t retVal =
1053       ompd_get_scheduling_task_handle(taskHandle, &schedulingTaskHandle);
1054 
1055   if (retVal == ompd_rc_unavailable) {
1056     return Py_None;
1057   } else if (retVal != ompd_rc_ok) {
1058     _printf("An error occurred when calling ompd_get_scheduling_task_handle! "
1059             "Error code: %d",
1060             retVal);
1061     return Py_BuildValue("l", retVal);
1062   }
1063   return PyCapsule_New(schedulingTaskHandle, "TaskHandle",
1064                        my_task_capsule_destructor);
1065 }
1066 
1067 /**
1068  * Returns task handles for the implicit tasks associated with a parallel
1069  * region.
1070  */
call_ompd_get_task_in_parallel(PyObject * self,PyObject * args)1071 static PyObject *call_ompd_get_task_in_parallel(PyObject *self,
1072                                                 PyObject *args) {
1073   PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
1074   int threadNum = (int)PyLong_AsLong(PyTuple_GetItem(args, 1));
1075   ompd_parallel_handle_t *parallelHandle =
1076       (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,
1077                                                       "ParallelHandle"));
1078   ompd_task_handle_t *taskHandle;
1079 
1080   ompd_rc_t retVal =
1081       ompd_get_task_in_parallel(parallelHandle, threadNum, &taskHandle);
1082 
1083   if (retVal != ompd_rc_ok) {
1084     _printf("An error occurred when calling ompd_get_task_in_parallel! Error "
1085             "code: %d",
1086             retVal);
1087     return Py_BuildValue("l", retVal);
1088   }
1089   return PyCapsule_New(taskHandle, "TaskHandle", my_task_capsule_destructor);
1090 }
1091 
1092 /**
1093  * Releases a task handle; is called by the destructor of a Python task_handle
1094  * object.
1095  */
call_ompd_rel_task_handle(PyObject * self,PyObject * args)1096 static PyObject *call_ompd_rel_task_handle(PyObject *self, PyObject *args) {
1097   PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1098   ompd_task_handle_t *taskHandle =
1099       (ompd_task_handle_t *)(PyCapsule_GetPointer(taskHandlePy, "TaskHandle"));
1100 
1101   ompd_rc_t retVal = ompd_rel_task_handle(taskHandle);
1102   if (retVal != ompd_rc_ok) {
1103     _printf(
1104         "An error occurred when calling ompd_rel_task_handle! Error code: %d",
1105         retVal);
1106   }
1107   return Py_BuildValue("l", retVal);
1108 }
1109 
1110 /**
1111  * Calls ompd_get_task_frame and returns a PyCapsule for the enter frame of the
1112  * given task.
1113  */
call_ompd_get_task_frame(PyObject * self,PyObject * args)1114 static PyObject *call_ompd_get_task_frame(PyObject *self, PyObject *args) {
1115   PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1116   ompd_task_handle_t *taskHandle =
1117       (ompd_task_handle_t *)PyCapsule_GetPointer(taskHandlePy, "TaskHandle");
1118   ompd_frame_info_t exitFrameInfo;
1119   ompd_frame_info_t enterFrameInfo;
1120 
1121   ompd_rc_t retVal =
1122       ompd_get_task_frame(taskHandle, &exitFrameInfo, &enterFrameInfo);
1123 
1124   if (retVal != ompd_rc_ok) {
1125     _printf(
1126         "An error occurred when calling ompd_get_task_frame! Error code: %d",
1127         retVal);
1128     return Py_BuildValue("l", retVal);
1129   }
1130 
1131   PyObject *result = PyTuple_New(4);
1132   PyTuple_SetItem(
1133       result, 0, PyLong_FromUnsignedLong(enterFrameInfo.frame_address.address));
1134   PyTuple_SetItem(result, 1,
1135                   PyLong_FromUnsignedLong(enterFrameInfo.frame_flag));
1136   PyTuple_SetItem(result, 2,
1137                   PyLong_FromUnsignedLong(exitFrameInfo.frame_address.address));
1138   PyTuple_SetItem(result, 3, PyLong_FromUnsignedLong(exitFrameInfo.frame_flag));
1139   return result;
1140 }
1141 
1142 /**
1143  * Calls ompd_get_icv_from_scope.
1144  */
call_ompd_get_icv_from_scope(PyObject * self,PyObject * args)1145 static PyObject *call_ompd_get_icv_from_scope(PyObject *self, PyObject *args) {
1146   PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);
1147   PyObject *scopePy = PyTuple_GetItem(args, 1);
1148   PyObject *icvIdPy = PyTuple_GetItem(args, 2);
1149 
1150   ompd_scope_t scope = (ompd_scope_t)PyLong_AsLong(scopePy);
1151   ompd_address_space_handle_t *addrSpaceHandle;
1152   switch (scope) {
1153   case ompd_scope_thread:
1154     addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1155         addrSpaceHandlePy, "ThreadHandle");
1156     break;
1157   case ompd_scope_parallel:
1158     addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1159         addrSpaceHandlePy, "ParallelHandle");
1160     break;
1161   case ompd_scope_implicit_task:
1162     addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1163         addrSpaceHandlePy, "TaskHandle");
1164     break;
1165   case ompd_scope_task:
1166     addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1167         addrSpaceHandlePy, "TaskHandle");
1168     break;
1169   default:
1170     addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1171         addrSpaceHandlePy, "AddressSpace");
1172     break;
1173   }
1174 
1175   ompd_icv_id_t icvId = (ompd_icv_id_t)PyLong_AsLong(icvIdPy);
1176   ompd_word_t icvValue;
1177 
1178   ompd_rc_t retVal =
1179       ompd_get_icv_from_scope(addrSpaceHandle, scope, icvId, &icvValue);
1180 
1181   if (retVal != ompd_rc_ok) {
1182     if (retVal != ompd_rc_incomplete) {
1183       _printf("An error occurred when calling ompd_get_icv_from_scope(%i, %i): "
1184               "Error code: %d",
1185               scope, icvId, retVal);
1186     }
1187     return Py_None;
1188   }
1189   return PyLong_FromLong(icvValue);
1190 }
1191 
1192 /**
1193  * Calls ompd_enumerate_icvs.
1194  */
call_ompd_enumerate_icvs(PyObject * self,PyObject * args)1195 static PyObject *call_ompd_enumerate_icvs(PyObject *self, PyObject *args) {
1196   PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);
1197   PyObject *currentPy = PyTuple_GetItem(args, 1);
1198   ompd_icv_id_t current = (ompd_icv_id_t)(PyLong_AsLong(currentPy));
1199   ompd_address_space_handle_t *addrSpaceHandle =
1200       (ompd_address_space_handle_t *)PyCapsule_GetPointer(addrSpaceHandlePy,
1201                                                           "AddressSpace");
1202 
1203   const char *nextIcv;
1204   ompd_scope_t nextScope;
1205   int more;
1206   ompd_icv_id_t nextId;
1207 
1208   ompd_rc_t retVal = ompd_enumerate_icvs(addrSpaceHandle, current, &nextId,
1209                                          &nextIcv, &nextScope, &more);
1210 
1211   if (retVal != ompd_rc_ok) {
1212     _printf(
1213         "An error occurred when calling ompd_enumerate_icvs! Error code: %d",
1214         retVal);
1215     return Py_None;
1216   }
1217   PyObject *retTuple = PyTuple_New(4);
1218   PyTuple_SetItem(retTuple, 0, PyLong_FromUnsignedLong(nextId));
1219   PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(nextIcv));
1220   PyTuple_SetItem(retTuple, 2, PyLong_FromUnsignedLong(nextScope));
1221   PyTuple_SetItem(retTuple, 3, PyLong_FromLong(more));
1222   return retTuple;
1223 }
1224 
1225 /**
1226  * Calls ompd_enumerate_states.
1227  */
call_ompd_enumerate_states(PyObject * self,PyObject * args)1228 static PyObject *call_ompd_enumerate_states(PyObject *self, PyObject *args) {
1229   PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);
1230   ompd_address_space_handle_t *addrSpaceHandle =
1231       (ompd_address_space_handle_t *)PyCapsule_GetPointer(addrSpaceHandlePy,
1232                                                           "AddressSpace");
1233   ompd_word_t currentState =
1234       (ompd_word_t)PyLong_AsLong(PyTuple_GetItem(args, 1));
1235 
1236   ompd_word_t nextState;
1237   const char *nextStateName;
1238   ompd_word_t moreEnums;
1239 
1240   ompd_rc_t retVal = ompd_enumerate_states(
1241       addrSpaceHandle, currentState, &nextState, &nextStateName, &moreEnums);
1242 
1243   if (retVal != ompd_rc_ok) {
1244     _printf(
1245         "An error occurred when calling ompd_enumerate_states! Error code: %d",
1246         retVal);
1247     return Py_None;
1248   }
1249   PyObject *retTuple = PyTuple_New(3);
1250   PyTuple_SetItem(retTuple, 0, PyLong_FromLong(nextState));
1251   PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(nextStateName));
1252   PyTuple_SetItem(retTuple, 2, PyLong_FromLong(moreEnums));
1253   return retTuple;
1254 }
1255 
1256 /**
1257  * Calls ompd_get_state.
1258  */
call_ompd_get_state(PyObject * self,PyObject * args)1259 static PyObject *call_ompd_get_state(PyObject *self, PyObject *args) {
1260   PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
1261   ompd_thread_handle_t *threadHandle =
1262       (ompd_thread_handle_t *)PyCapsule_GetPointer(threadHandlePy,
1263                                                    "ThreadHandle");
1264   ompd_word_t state;
1265   ompd_wait_id_t waitId;
1266 
1267   ompd_rc_t retVal = ompd_get_state(threadHandle, &state, &waitId);
1268 
1269   if (retVal != ompd_rc_ok) {
1270     _printf("An error occurred when calling ompd_get_state! Error code: %d",
1271             retVal);
1272     return Py_None;
1273   }
1274   PyObject *retTuple = PyTuple_New(2);
1275   PyTuple_SetItem(retTuple, 0, PyLong_FromLong(state));
1276   PyTuple_SetItem(retTuple, 1, PyLong_FromUnsignedLong(waitId));
1277   return retTuple;
1278 }
1279 
1280 /**
1281  * Calls ompd_get_task_function and returns entry point of the code that
1282  * corresponds to the code executed by the task.
1283  */
call_ompd_get_task_function(PyObject * self,PyObject * args)1284 static PyObject *call_ompd_get_task_function(PyObject *self, PyObject *args) {
1285   PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1286   ompd_task_handle_t *taskHandle =
1287       (ompd_task_handle_t *)PyCapsule_GetPointer(taskHandlePy, "TaskHandle");
1288   ompd_address_t entryPoint;
1289 
1290   ompd_rc_t retVal = ompd_get_task_function(taskHandle, &entryPoint);
1291 
1292   if (retVal != ompd_rc_ok) {
1293     _printf(
1294         "An error occurred when calling ompd_get_task_function! Error code: %d",
1295         retVal);
1296     return Py_None;
1297   }
1298   return PyLong_FromLong((long)entryPoint.address);
1299 }
1300 
1301 /**
1302  * Prints pointer stored inside PyCapusle.
1303  */
print_capsule(PyObject * self,PyObject * args)1304 static PyObject *print_capsule(PyObject *self, PyObject *args) {
1305   PyObject *capsule = PyTuple_GetItem(args, 0);
1306   PyObject *name = PyTuple_GetItem(args, 1);
1307   void *pointer =
1308       PyCapsule_GetPointer(capsule, PyUnicode_AsUTF8AndSize(name, NULL));
1309   _printf("Capsule pointer: %p", pointer);
1310   return Py_None;
1311 }
1312 
1313 /**
1314  * Calls ompd_get_thread_id for given handle and returns the thread id as a
1315  * long.
1316  */
call_ompd_get_thread_id(PyObject * self,PyObject * args)1317 static PyObject *call_ompd_get_thread_id(PyObject *self, PyObject *args) {
1318   PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
1319   ompd_thread_handle_t *threadHandle =
1320       (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,
1321                                                     "ThreadHandle"));
1322   ompd_thread_id_t kind = 0; // OMPD_THREAD_ID_PTHREAD
1323   ompd_size_t sizeOfId = (ompd_size_t)sizeof(pthread_t);
1324 
1325   uint64_t thread;
1326   ompd_rc_t retVal = ompd_get_thread_id(threadHandle, kind, sizeOfId, &thread);
1327 
1328   if (retVal != ompd_rc_ok) {
1329     kind = 1; // OMPD_THREAD_ID_LWP
1330     retVal = ompd_get_thread_id(threadHandle, kind, sizeOfId, &thread);
1331     if (retVal != ompd_rc_ok) {
1332       _printf(
1333           "An error occurred when calling ompd_get_thread_id! Error code: %d",
1334           retVal);
1335       return Py_None;
1336     }
1337   }
1338   return PyLong_FromLong(thread);
1339 }
1340 
1341 /**
1342  * Calls ompd_get_tool_data and returns a tuple containing the value and pointer
1343  * of the ompt_data_t union for the selected scope.
1344  */
call_ompd_get_tool_data(PyObject * self,PyObject * args)1345 static PyObject *call_ompd_get_tool_data(PyObject *self, PyObject *args) {
1346   PyObject *scopePy = PyTuple_GetItem(args, 0);
1347   ompd_scope_t scope = (ompd_scope_t)(PyLong_AsLong(scopePy));
1348   PyObject *handlePy = PyTuple_GetItem(args, 1);
1349   void *handle = NULL;
1350 
1351   if (scope == 3) {
1352     ompd_thread_handle_t *threadHandle =
1353         (ompd_thread_handle_t *)(PyCapsule_GetPointer(handlePy,
1354                                                       "ThreadHandle"));
1355     handle = threadHandle;
1356   } else if (scope == 4) {
1357     ompd_parallel_handle_t *parallelHandle =
1358         (ompd_parallel_handle_t *)(PyCapsule_GetPointer(handlePy,
1359                                                         "ParallelHandle"));
1360     handle = parallelHandle;
1361   } else if (scope == 5 || scope == 6) {
1362     ompd_task_handle_t *taskHandle =
1363         (ompd_task_handle_t *)(PyCapsule_GetPointer(handlePy, "TaskHandle"));
1364     handle = taskHandle;
1365   } else {
1366     _printf("An error occured when calling ompd_get_tool_data! Scope type not "
1367             "supported.");
1368     return Py_None;
1369   }
1370 
1371   ompd_word_t value;
1372   ompd_address_t ptr;
1373 
1374   ompd_rc_t retVal = ompd_get_tool_data(handle, scope, &value, &ptr);
1375 
1376   if (retVal != ompd_rc_ok) {
1377     _printf("An error occured when calling ompd_get_tool_data! Error code: %d",
1378             retVal);
1379     return Py_None;
1380   }
1381 
1382   PyObject *retTuple = PyTuple_New(2);
1383   PyTuple_SetItem(retTuple, 0, PyLong_FromLong(value));
1384   PyTuple_SetItem(retTuple, 1, PyLong_FromLong(ptr.address));
1385   return retTuple;
1386 }
1387 
1388 /** Calls ompd_get_icv_string_from_scope.
1389  */
call_ompd_get_icv_string_from_scope(PyObject * self,PyObject * args)1390 static PyObject *call_ompd_get_icv_string_from_scope(PyObject *self,
1391                                                      PyObject *args) {
1392   PyObject *handlePy = PyTuple_GetItem(args, 0);
1393   PyObject *scopePy = PyTuple_GetItem(args, 1);
1394   PyObject *icvIdPy = PyTuple_GetItem(args, 2);
1395 
1396   ompd_scope_t scope = (ompd_scope_t)PyLong_AsLong(scopePy);
1397   void *handle = NULL;
1398   switch (scope) {
1399   case ompd_scope_thread:
1400     handle =
1401         (ompd_thread_handle_t *)PyCapsule_GetPointer(handlePy, "ThreadHandle");
1402     break;
1403   case ompd_scope_parallel:
1404     handle = (ompd_parallel_handle_t *)PyCapsule_GetPointer(handlePy,
1405                                                             "ParallelHandle");
1406     break;
1407   case ompd_scope_implicit_task:
1408     handle = (ompd_task_handle_t *)PyCapsule_GetPointer(handlePy, "TaskHandle");
1409     break;
1410   case ompd_scope_task:
1411     handle = (ompd_task_handle_t *)PyCapsule_GetPointer(handlePy, "TaskHandle");
1412     break;
1413   default:
1414     handle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1415         handlePy, "AddressSpace");
1416     break;
1417   }
1418 
1419   ompd_icv_id_t icvId = (ompd_icv_id_t)PyLong_AsLong(icvIdPy);
1420   const char *icvString;
1421 
1422   ompd_rc_t retVal =
1423       ompd_get_icv_string_from_scope(handle, scope, icvId, &icvString);
1424 
1425   if (retVal != ompd_rc_ok) {
1426     _printf("An error occurred when calling ompd_get_icv_string_from_scope! "
1427             "Error code: %d",
1428             retVal);
1429     return Py_None;
1430   }
1431   return PyUnicode_FromString(icvString);
1432 }
1433 
1434 // Prototypes of API test functions.
1435 PyObject *test_ompd_get_thread_handle(PyObject *self, PyObject *args);
1436 PyObject *test_ompd_get_curr_parallel_handle(PyObject *self, PyObject *args);
1437 PyObject *test_ompd_get_thread_in_parallel(PyObject *self, PyObject *args);
1438 PyObject *test_ompd_thread_handle_compare(PyObject *self, PyObject *args);
1439 PyObject *test_ompd_get_thread_id(PyObject *self, PyObject *args);
1440 PyObject *test_ompd_rel_thread_handle(PyObject *self, PyObject *args);
1441 PyObject *test_ompd_get_enclosing_parallel_handle(PyObject *self,
1442                                                   PyObject *args);
1443 PyObject *test_ompd_parallel_handle_compare(PyObject *self, PyObject *args);
1444 PyObject *test_ompd_rel_parallel_handle(PyObject *self, PyObject *args);
1445 PyObject *test_ompd_initialize(PyObject *self, PyObject *noargs);
1446 PyObject *test_ompd_get_api_version(PyObject *self, PyObject *noargs);
1447 PyObject *test_ompd_get_version_string(PyObject *self, PyObject *noargs);
1448 PyObject *test_ompd_finalize(PyObject *self, PyObject *noargs);
1449 PyObject *test_ompd_process_initialize(PyObject *self, PyObject *noargs);
1450 PyObject *test_ompd_device_initialize(PyObject *self, PyObject *noargs);
1451 PyObject *test_ompd_rel_address_space_handle(PyObject *self, PyObject *noargs);
1452 PyObject *test_ompd_get_omp_version(PyObject *self, PyObject *args);
1453 PyObject *test_ompd_get_omp_version_string(PyObject *self, PyObject *args);
1454 PyObject *test_ompd_get_curr_task_handle(PyObject *self, PyObject *args);
1455 PyObject *test_ompd_get_task_parallel_handle(PyObject *self, PyObject *args);
1456 PyObject *test_ompd_get_generating_task_handle(PyObject *self, PyObject *args);
1457 PyObject *test_ompd_get_scheduling_task_handle(PyObject *self, PyObject *args);
1458 PyObject *test_ompd_get_task_in_parallel(PyObject *self, PyObject *args);
1459 PyObject *test_ompd_rel_task_handle(PyObject *self, PyObject *noargs);
1460 PyObject *test_ompd_task_handle_compare(PyObject *self, PyObject *args);
1461 PyObject *test_ompd_get_task_function(PyObject *self, PyObject *args);
1462 PyObject *test_ompd_get_task_frame(PyObject *self, PyObject *args);
1463 PyObject *test_ompd_get_state(PyObject *self, PyObject *args);
1464 PyObject *test_ompd_get_display_control_vars(PyObject *self, PyObject *args);
1465 PyObject *test_ompd_rel_display_control_vars(PyObject *self, PyObject *noargs);
1466 PyObject *test_ompd_enumerate_icvs(PyObject *self, PyObject *noargs);
1467 PyObject *test_ompd_get_icv_from_scope_with_addr_handle(PyObject *self,
1468                                                         PyObject *noargs);
1469 PyObject *test_ompd_get_icv_from_scope_with_thread_handle(PyObject *self,
1470                                                           PyObject *noargs);
1471 PyObject *test_ompd_get_icv_from_scope_with_parallel_handle(PyObject *self,
1472                                                             PyObject *noargs);
1473 PyObject *test_ompd_get_icv_from_scope_with_task_handle(PyObject *self,
1474                                                         PyObject *noargs);
1475 PyObject *test_ompd_get_icv_string_from_scope(PyObject *self, PyObject *noargs);
1476 PyObject *test_ompd_get_tool_data(PyObject *self, PyObject *noargs);
1477 PyObject *test_ompd_enumerate_states(PyObject *self, PyObject *noargs);
1478 /**
1479  * Binds Python function names to C functions.
1480  */
1481 static PyMethodDef ompdModule_methods[] = {
1482     {"ompd_open", ompd_open, METH_VARARGS,
1483      "Execute dlopen, return OMPD version."},
1484     {"call_ompd_initialize", call_ompd_initialize, METH_NOARGS,
1485      "Initializes OMPD environment and callbacks."},
1486     {"call_ompd_rel_thread_handle", call_ompd_rel_thread_handle, METH_VARARGS,
1487      "Releases a thread handle."},
1488     {"get_thread_handle", get_thread_handle, METH_VARARGS,
1489      "Collects information on threads."},
1490     {"call_ompd_get_thread_in_parallel", call_ompd_get_thread_in_parallel,
1491      METH_VARARGS,
1492      "Obtains handle for a certain thread within parallel region."},
1493     {"call_ompd_get_curr_parallel_handle", call_ompd_get_curr_parallel_handle,
1494      METH_VARARGS,
1495      "Obtains a pointer to the parallel handle for the current parallel "
1496      "region."},
1497     {"call_ompd_get_enclosing_parallel_handle",
1498      call_ompd_get_enclosing_parallel_handle, METH_VARARGS,
1499      "Obtains a pointer to the parallel handle for the parallel region "
1500      "enclosing the parallel region specified."},
1501     {"call_ompd_get_task_parallel_handle", call_ompd_get_task_parallel_handle,
1502      METH_VARARGS,
1503      "Obtains a pointer to the parallel handle for the parallel region "
1504      "enclosing the task region specified."},
1505     {"call_ompd_rel_parallel_handle", call_ompd_rel_parallel_handle,
1506      METH_VARARGS, "Releases a parallel region handle."},
1507     {"call_ompd_get_curr_task_handle", call_ompd_get_curr_task_handle,
1508      METH_VARARGS,
1509      "Obtains a pointer to the task handle for the current task region "
1510      "associated with an OpenMP thread."},
1511     {"call_ompd_get_generating_task_handle",
1512      call_ompd_get_generating_task_handle, METH_VARARGS,
1513      "Obtains a pointer to the task handle for the task that was created when "
1514      "the task handle specified was encountered."},
1515     {"call_ompd_get_scheduling_task_handle",
1516      call_ompd_get_scheduling_task_handle, METH_VARARGS,
1517      "Obtains a pointer to the task handle for the task that scheduled the "
1518      "task specified."},
1519     {"call_ompd_get_task_in_parallel", call_ompd_get_task_in_parallel,
1520      METH_VARARGS,
1521      "Obtains the handle for implicit tasks associated with a parallel "
1522      "region."},
1523     {"call_ompd_rel_task_handle", call_ompd_rel_task_handle, METH_VARARGS,
1524      "Releases a task handle."},
1525     {"call_ompd_get_task_frame", call_ompd_get_task_frame, METH_VARARGS,
1526      "Returns a pointer to the enter and exit frame address and flag of the "
1527      "given task."},
1528     {"call_ompd_enumerate_icvs", call_ompd_enumerate_icvs, METH_VARARGS,
1529      "Saves ICVs in map."},
1530     {"call_ompd_get_icv_from_scope", call_ompd_get_icv_from_scope, METH_VARARGS,
1531      "Gets ICVs from scope."},
1532     {"call_ompd_enumerate_states", call_ompd_enumerate_states, METH_VARARGS,
1533      "Enumerates OMP states."},
1534     {"call_ompd_get_state", call_ompd_get_state, METH_VARARGS,
1535      "Returns state for given thread handle."},
1536     {"call_ompd_get_task_function", call_ompd_get_task_function, METH_VARARGS,
1537      "Returns point of code where task starts executing."},
1538     {"print_capsule", print_capsule, METH_VARARGS, "Print capsule content"},
1539     {"call_ompd_get_thread_id", call_ompd_get_thread_id, METH_VARARGS,
1540      "Maps an OMPD thread handle to a native thread."},
1541     {"call_ompd_get_tool_data", call_ompd_get_tool_data, METH_VARARGS,
1542      "Returns value and pointer of ompd_data_t for given scope and handle."},
1543     {"call_ompd_get_icv_string_from_scope", call_ompd_get_icv_string_from_scope,
1544      METH_VARARGS, "Gets ICV string representation from scope."},
1545 
1546     {"test_ompd_get_thread_handle", test_ompd_get_thread_handle, METH_VARARGS,
1547      "Test API ompd_get_thread_handle."},
1548     {"test_ompd_get_curr_parallel_handle", test_ompd_get_curr_parallel_handle,
1549      METH_VARARGS, "Test API test_ompd_get_curr_parallel_handle."},
1550     {"test_ompd_get_thread_in_parallel", test_ompd_get_thread_in_parallel,
1551      METH_VARARGS, "Test API ompd_get_thread_in_parallel."},
1552     {"test_ompd_thread_handle_compare", test_ompd_thread_handle_compare,
1553      METH_VARARGS, "Test API ompd_thread_handle_compare."},
1554     {"test_ompd_get_thread_id", test_ompd_get_thread_id, METH_VARARGS,
1555      "Test API ompd_get_thread_id."},
1556     {"test_ompd_rel_thread_handle", test_ompd_rel_thread_handle, METH_VARARGS,
1557      "Test API ompd_rel_thread_handle."},
1558     {"test_ompd_get_enclosing_parallel_handle",
1559      test_ompd_get_enclosing_parallel_handle, METH_VARARGS,
1560      "Test API ompd_get_enclosing_parallel_handle."},
1561     {"test_ompd_parallel_handle_compare", test_ompd_parallel_handle_compare,
1562      METH_VARARGS, "Test API test_ompd_parallel_handle_compare."},
1563     {"test_ompd_rel_parallel_handle", test_ompd_rel_parallel_handle,
1564      METH_VARARGS, "Test API ompd_rel_parallel_handle."},
1565 
1566     {"test_ompd_initialize", test_ompd_initialize, METH_VARARGS,
1567      "Test API ompd_initialize."},
1568     {"test_ompd_get_api_version", test_ompd_get_api_version, METH_VARARGS,
1569      "Test API ompd_get_api_version."},
1570     {"test_ompd_get_version_string", test_ompd_get_version_string, METH_VARARGS,
1571      "Test API ompd_get_version_string."},
1572     {"test_ompd_finalize", test_ompd_finalize, METH_VARARGS,
1573      "Test API ompd_finalize."},
1574     {"test_ompd_process_initialize", test_ompd_process_initialize, METH_VARARGS,
1575      "Test API ompd_process_initialize. "},
1576     {"test_ompd_device_initialize", test_ompd_device_initialize, METH_VARARGS,
1577      "Test API ompd_device_initialize."},
1578     {"test_ompd_rel_address_space_handle", test_ompd_rel_address_space_handle,
1579      METH_VARARGS, "Test API ompd_rel_address_space_handle."},
1580     {"test_ompd_get_omp_version", test_ompd_get_omp_version, METH_VARARGS,
1581      "Test API ompd_get_omp_version."},
1582     {"test_ompd_get_omp_version_string", test_ompd_get_omp_version_string,
1583      METH_VARARGS, "Test API ompd_get_omp_version_string."},
1584 
1585     {"test_ompd_get_curr_task_handle", test_ompd_get_curr_task_handle,
1586      METH_VARARGS, "Test API ompd_get_curr_task_handle."},
1587     {"test_ompd_get_task_parallel_handle", test_ompd_get_task_parallel_handle,
1588      METH_VARARGS, "Test API ompd_get_task_parallel_handle."},
1589     {"test_ompd_get_generating_task_handle",
1590      test_ompd_get_generating_task_handle, METH_VARARGS,
1591      "Test API ompd_get_generating_task_handle."},
1592     {"test_ompd_get_scheduling_task_handle",
1593      test_ompd_get_scheduling_task_handle, METH_VARARGS,
1594      "Test API ompd_get_scheduling_task_handle."},
1595     {"test_ompd_get_task_in_parallel", test_ompd_get_task_in_parallel,
1596      METH_VARARGS, "Test API ompd_get_task_in_parallel."},
1597     {"test_ompd_rel_task_handle", test_ompd_rel_task_handle, METH_VARARGS,
1598      "Test API ompd_rel_task_handle."},
1599     {"test_ompd_task_handle_compare", test_ompd_task_handle_compare,
1600      METH_VARARGS, "Test API ompd_task_handle_compare."},
1601     {"test_ompd_get_task_function", test_ompd_get_task_function, METH_VARARGS,
1602      "Test API ompd_get_task_function."},
1603     {"test_ompd_get_task_frame", test_ompd_get_task_frame, METH_VARARGS,
1604      "Test API ompd_get_task_frame."},
1605     {"test_ompd_get_state", test_ompd_get_state, METH_VARARGS,
1606      "Test API ompd_get_state."},
1607     {"test_ompd_get_display_control_vars", test_ompd_get_display_control_vars,
1608      METH_VARARGS, "Test API ompd_get_display_control_vars."},
1609     {"test_ompd_rel_display_control_vars", test_ompd_rel_display_control_vars,
1610      METH_VARARGS, "Test API ompd_rel_display_control_vars."},
1611     {"test_ompd_enumerate_icvs", test_ompd_enumerate_icvs, METH_VARARGS,
1612      "Test API ompd_enumerate_icvs."},
1613     {"test_ompd_get_icv_from_scope_with_addr_handle",
1614      test_ompd_get_icv_from_scope_with_addr_handle, METH_VARARGS,
1615      "Test API ompd_get_icv_from_scope with addr_handle."},
1616     {"test_ompd_get_icv_from_scope_with_thread_handle",
1617      test_ompd_get_icv_from_scope_with_thread_handle, METH_VARARGS,
1618      "Test API ompd_get_icv_from_scope with thread_handle."},
1619     {"test_ompd_get_icv_from_scope_with_parallel_handle",
1620      test_ompd_get_icv_from_scope_with_parallel_handle, METH_VARARGS,
1621      "Test API ompd_get_icv_from_scope with parallel_handle."},
1622     {"test_ompd_get_icv_from_scope_with_task_handle",
1623      test_ompd_get_icv_from_scope_with_task_handle, METH_VARARGS,
1624      "Test API ompd_get_icv_from_scope with task_handle."},
1625     {"test_ompd_get_icv_string_from_scope", test_ompd_get_icv_string_from_scope,
1626      METH_VARARGS, "Test API ompd_get_icv_string_from_scope."},
1627     {"test_ompd_get_tool_data", test_ompd_get_tool_data, METH_VARARGS,
1628      "Test API ompd_get_tool_data."},
1629     {"test_ompd_enumerate_states", test_ompd_enumerate_states, METH_VARARGS,
1630      "Test API ompd_enumerate_states."},
1631     {NULL, NULL, 0, NULL}};
1632 
1633 /**
1634  * Lets Python initialize module.
1635  */
1636 #if PY_MAJOR_VERSION >= 3
1637 static struct PyModuleDef moduledef = {
1638     PyModuleDef_HEAD_INIT,
1639     "ompdModule",       /* m_name */
1640     "This is a module", /* m_doc */
1641     -1,                 /* m_size */
1642     ompdModule_methods, /* m_methods */
1643     NULL,               /* m_reload */
1644     NULL,               /* m_traverse */
1645     NULL,               /* m_clear */
1646     NULL,               /* m_free */
1647 };
1648 #endif
PyInit_ompdModule(void)1649 void PyInit_ompdModule(void) {
1650   //	(void) Py_InitModule("ompdModule", ompdModule_methods);
1651   PyModule_Create(&moduledef);
1652 }
1653