xref: /petsc/src/sys/perfstubs/pstimer.c (revision a0c7f9aa3b59be96b422b2e54790cd20c111f46e)
1*a0c7f9aaSSamuel Khuvis // Copyright (c) 2019 University of Oregon
2*a0c7f9aaSSamuel Khuvis // Distributed under the BSD Software License
3*a0c7f9aaSSamuel Khuvis // (See accompanying file LICENSE.txt)
4*a0c7f9aaSSamuel Khuvis 
5*a0c7f9aaSSamuel Khuvis #ifndef _GNU_SOURCE
6*a0c7f9aaSSamuel Khuvis #define _GNU_SOURCE // needed to define RTLD_DEFAULT
7*a0c7f9aaSSamuel Khuvis #endif
8*a0c7f9aaSSamuel Khuvis #include <stdlib.h>
9*a0c7f9aaSSamuel Khuvis #include <stdio.h>
10*a0c7f9aaSSamuel Khuvis #include <math.h>
11*a0c7f9aaSSamuel Khuvis #ifdef __linux__
12*a0c7f9aaSSamuel Khuvis #include <dlfcn.h>
13*a0c7f9aaSSamuel Khuvis #else
14*a0c7f9aaSSamuel Khuvis #define PERFSTUBS_USE_STATIC 1
15*a0c7f9aaSSamuel Khuvis #endif
16*a0c7f9aaSSamuel Khuvis #define PERFSTUBS_USE_TIMERS
17*a0c7f9aaSSamuel Khuvis #include "timer.h"
18*a0c7f9aaSSamuel Khuvis 
19*a0c7f9aaSSamuel Khuvis #define MAX_TOOLS 1
20*a0c7f9aaSSamuel Khuvis 
21*a0c7f9aaSSamuel Khuvis #if defined(_WIN32)||defined(WIN32)||defined(_WIN64)||defined(WIN64)||defined(__CYGWIN__)||defined(__APPLE__)
22*a0c7f9aaSSamuel Khuvis #define PERFSTUBS_OFF
23*a0c7f9aaSSamuel Khuvis #endif
24*a0c7f9aaSSamuel Khuvis 
25*a0c7f9aaSSamuel Khuvis /* Make sure that the Timer singleton is constructed when the
26*a0c7f9aaSSamuel Khuvis  * library is loaded.  This will ensure (on linux, anyway) that
27*a0c7f9aaSSamuel Khuvis  * we can assert that we have m_Initialized on the main thread. */
28*a0c7f9aaSSamuel Khuvis //static void __attribute__((constructor)) initialize_library(void);
29*a0c7f9aaSSamuel Khuvis 
30*a0c7f9aaSSamuel Khuvis /* Globals for the plugin API */
31*a0c7f9aaSSamuel Khuvis 
32*a0c7f9aaSSamuel Khuvis int perfstubs_initialized = PERFSTUBS_UNKNOWN;
33*a0c7f9aaSSamuel Khuvis int num_tools_registered = 0;
34*a0c7f9aaSSamuel Khuvis /* Keep track of whether the thread has been registered */
35*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
36*a0c7f9aaSSamuel Khuvis __thread int thread_seen = 0;
37*a0c7f9aaSSamuel Khuvis #endif
38*a0c7f9aaSSamuel Khuvis /* Function pointers */
39*a0c7f9aaSSamuel Khuvis 
40*a0c7f9aaSSamuel Khuvis ps_initialize_t initialize_functions[MAX_TOOLS];
41*a0c7f9aaSSamuel Khuvis ps_register_thread_t register_thread_functions[MAX_TOOLS];
42*a0c7f9aaSSamuel Khuvis ps_finalize_t finalize_functions[MAX_TOOLS];
43*a0c7f9aaSSamuel Khuvis ps_dump_data_t dump_data_functions[MAX_TOOLS];
44*a0c7f9aaSSamuel Khuvis ps_timer_create_t timer_create_functions[MAX_TOOLS];
45*a0c7f9aaSSamuel Khuvis ps_timer_start_t timer_start_functions[MAX_TOOLS];
46*a0c7f9aaSSamuel Khuvis ps_timer_stop_t timer_stop_functions[MAX_TOOLS];
47*a0c7f9aaSSamuel Khuvis ps_set_parameter_t set_parameter_functions[MAX_TOOLS];
48*a0c7f9aaSSamuel Khuvis ps_dynamic_phase_start_t dynamic_phase_start_functions[MAX_TOOLS];
49*a0c7f9aaSSamuel Khuvis ps_dynamic_phase_stop_t dynamic_phase_stop_functions[MAX_TOOLS];
50*a0c7f9aaSSamuel Khuvis ps_create_counter_t create_counter_functions[MAX_TOOLS];
51*a0c7f9aaSSamuel Khuvis ps_sample_counter_t sample_counter_functions[MAX_TOOLS];
52*a0c7f9aaSSamuel Khuvis ps_set_metadata_t set_metadata_functions[MAX_TOOLS];
53*a0c7f9aaSSamuel Khuvis ps_get_timer_data_t get_timer_data_functions[MAX_TOOLS];
54*a0c7f9aaSSamuel Khuvis ps_get_counter_data_t get_counter_data_functions[MAX_TOOLS];
55*a0c7f9aaSSamuel Khuvis ps_get_metadata_t get_metadata_functions[MAX_TOOLS];
56*a0c7f9aaSSamuel Khuvis ps_free_timer_data_t free_timer_data_functions[MAX_TOOLS];
57*a0c7f9aaSSamuel Khuvis ps_free_counter_data_t free_counter_data_functions[MAX_TOOLS];
58*a0c7f9aaSSamuel Khuvis ps_free_metadata_t free_metadata_functions[MAX_TOOLS];
59*a0c7f9aaSSamuel Khuvis 
60*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
61*a0c7f9aaSSamuel Khuvis 
62*a0c7f9aaSSamuel Khuvis #ifdef PERFSTUBS_USE_STATIC
63*a0c7f9aaSSamuel Khuvis 
64*a0c7f9aaSSamuel Khuvis #if defined(__clang__) && defined(__APPLE__)
65*a0c7f9aaSSamuel Khuvis #define PS_WEAK_PRE
66*a0c7f9aaSSamuel Khuvis #define PS_WEAK_POST __attribute__((weak_import))
67*a0c7f9aaSSamuel Khuvis #define PS_WEAK_POST_NULL __attribute__((weak_import))
68*a0c7f9aaSSamuel Khuvis #else
69*a0c7f9aaSSamuel Khuvis #define PS_WEAK_PRE __attribute__((weak))
70*a0c7f9aaSSamuel Khuvis #define PS_WEAK_POST
71*a0c7f9aaSSamuel Khuvis #define PS_WEAK_POST_NULL
72*a0c7f9aaSSamuel Khuvis #endif
73*a0c7f9aaSSamuel Khuvis 
74*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_initialize(void) PS_WEAK_POST;
75*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_register_thread(void) PS_WEAK_POST;
76*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_finalize(void) PS_WEAK_POST;
77*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_dump_data(void) PS_WEAK_POST;
78*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void* ps_tool_timer_create(const char *) PS_WEAK_POST;
79*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_timer_start(const void *) PS_WEAK_POST;
80*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_timer_stop(const void *) PS_WEAK_POST;
81*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_set_parameter(const char *, int64_t) PS_WEAK_POST;
82*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_dynamic_phase_start(const char *, int) PS_WEAK_POST;
83*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_dynamic_phase_stop(const char *, int) PS_WEAK_POST;
84*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void* ps_tool_create_counter(const char *) PS_WEAK_POST;
85*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_sample_counter(const void *, double) PS_WEAK_POST;
86*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_set_metadata(const char *, const char *) PS_WEAK_POST;
87*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_get_timer_data(ps_tool_timer_data_t *) PS_WEAK_POST;
88*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_get_counter_data(ps_tool_counter_data_t *) PS_WEAK_POST;
89*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_get_metadata(ps_tool_metadata_t *) PS_WEAK_POST;
90*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_free_timer_data(ps_tool_timer_data_t *) PS_WEAK_POST;
91*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_free_counter_data(ps_tool_counter_data_t *) PS_WEAK_POST;
92*a0c7f9aaSSamuel Khuvis PS_WEAK_PRE void ps_tool_free_metadata(ps_tool_metadata_t *) PS_WEAK_POST;
93*a0c7f9aaSSamuel Khuvis #endif
94*a0c7f9aaSSamuel Khuvis 
95*a0c7f9aaSSamuel Khuvis 
96*a0c7f9aaSSamuel Khuvis // Disable pedantic, see https://stackoverflow.com/a/36385690
97*a0c7f9aaSSamuel Khuvis #pragma GCC diagnostic push  // Save actual diagnostics state
98*a0c7f9aaSSamuel Khuvis #pragma GCC diagnostic ignored "-Wpedantic" // Disable pedantic
99*a0c7f9aaSSamuel Khuvis 
100*a0c7f9aaSSamuel Khuvis #endif //PERFSTUBS_OFF
101*a0c7f9aaSSamuel Khuvis 
102*a0c7f9aaSSamuel Khuvis void initialize_library() {
103*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
104*a0c7f9aaSSamuel Khuvis #ifdef PERFSTUBS_USE_STATIC
105*a0c7f9aaSSamuel Khuvis     /* The initialization function is the only required one */
106*a0c7f9aaSSamuel Khuvis     initialize_functions[0] = &ps_tool_initialize;
107*a0c7f9aaSSamuel Khuvis     if (initialize_functions[0] == NULL) {
108*a0c7f9aaSSamuel Khuvis         return;
109*a0c7f9aaSSamuel Khuvis     }
110*a0c7f9aaSSamuel Khuvis     printf("Found ps_tool_initialize(), registering tool\n");
111*a0c7f9aaSSamuel Khuvis     register_thread_functions[0] = &ps_tool_register_thread;
112*a0c7f9aaSSamuel Khuvis     finalize_functions[0] = &ps_tool_finalize;
113*a0c7f9aaSSamuel Khuvis     dump_data_functions[0] = &ps_tool_dump_data;
114*a0c7f9aaSSamuel Khuvis     timer_create_functions[0] = &ps_tool_timer_create;
115*a0c7f9aaSSamuel Khuvis     timer_start_functions[0] = &ps_tool_timer_start;
116*a0c7f9aaSSamuel Khuvis     timer_stop_functions[0] = &ps_tool_timer_stop;
117*a0c7f9aaSSamuel Khuvis     set_parameter_functions[0] = &ps_tool_set_parameter;
118*a0c7f9aaSSamuel Khuvis     dynamic_phase_start_functions[0] = &ps_tool_dynamic_phase_start;
119*a0c7f9aaSSamuel Khuvis     dynamic_phase_stop_functions[0] = &ps_tool_dynamic_phase_stop;
120*a0c7f9aaSSamuel Khuvis     create_counter_functions[0] = &ps_tool_create_counter;
121*a0c7f9aaSSamuel Khuvis     sample_counter_functions[0] = &ps_tool_sample_counter;
122*a0c7f9aaSSamuel Khuvis     set_metadata_functions[0] = &ps_tool_set_metadata;
123*a0c7f9aaSSamuel Khuvis     get_timer_data_functions[0] = &ps_tool_get_timer_data;
124*a0c7f9aaSSamuel Khuvis     get_counter_data_functions[0] = &ps_tool_get_counter_data;
125*a0c7f9aaSSamuel Khuvis     get_metadata_functions[0] = &ps_tool_get_metadata;
126*a0c7f9aaSSamuel Khuvis     free_timer_data_functions[0] = &ps_tool_free_timer_data;
127*a0c7f9aaSSamuel Khuvis     free_counter_data_functions[0] = &ps_tool_free_counter_data;
128*a0c7f9aaSSamuel Khuvis     free_metadata_functions[0] = &ps_tool_free_metadata;
129*a0c7f9aaSSamuel Khuvis #else
130*a0c7f9aaSSamuel Khuvis     initialize_functions[0] =
131*a0c7f9aaSSamuel Khuvis         (ps_initialize_t)dlsym(RTLD_DEFAULT, "ps_tool_initialize");
132*a0c7f9aaSSamuel Khuvis     if (initialize_functions[0] == NULL) {
133*a0c7f9aaSSamuel Khuvis         perfstubs_initialized = PERFSTUBS_FAILURE;
134*a0c7f9aaSSamuel Khuvis         return;
135*a0c7f9aaSSamuel Khuvis     }
136*a0c7f9aaSSamuel Khuvis     printf("Found ps_tool_initialize(), registering tool\n");
137*a0c7f9aaSSamuel Khuvis     finalize_functions[0] =
138*a0c7f9aaSSamuel Khuvis         (ps_finalize_t)dlsym(RTLD_DEFAULT, "ps_tool_finalize");
139*a0c7f9aaSSamuel Khuvis     register_thread_functions[0] =
140*a0c7f9aaSSamuel Khuvis         (ps_register_thread_t)dlsym(RTLD_DEFAULT, "ps_tool_register_thread");
141*a0c7f9aaSSamuel Khuvis     dump_data_functions[0] =
142*a0c7f9aaSSamuel Khuvis         (ps_dump_data_t)dlsym(RTLD_DEFAULT, "ps_tool_dump_data");
143*a0c7f9aaSSamuel Khuvis     timer_create_functions[0] =
144*a0c7f9aaSSamuel Khuvis         (ps_timer_create_t)dlsym(RTLD_DEFAULT,
145*a0c7f9aaSSamuel Khuvis         "ps_tool_timer_create");
146*a0c7f9aaSSamuel Khuvis     timer_start_functions[0] =
147*a0c7f9aaSSamuel Khuvis         (ps_timer_start_t)dlsym(RTLD_DEFAULT, "ps_tool_timer_start");
148*a0c7f9aaSSamuel Khuvis     timer_stop_functions[0] =
149*a0c7f9aaSSamuel Khuvis         (ps_timer_stop_t)dlsym(RTLD_DEFAULT, "ps_tool_timer_stop");
150*a0c7f9aaSSamuel Khuvis     set_parameter_functions[0] =
151*a0c7f9aaSSamuel Khuvis         (ps_set_parameter_t)dlsym(RTLD_DEFAULT, "ps_tool_set_parameter");
152*a0c7f9aaSSamuel Khuvis     dynamic_phase_start_functions[0] = (ps_dynamic_phase_start_t)dlsym(
153*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_dynamic_phase_start");
154*a0c7f9aaSSamuel Khuvis     dynamic_phase_stop_functions[0] = (ps_dynamic_phase_stop_t)dlsym(
155*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_dynamic_phase_stop");
156*a0c7f9aaSSamuel Khuvis     create_counter_functions[0] = (ps_create_counter_t)dlsym(
157*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_create_counter");
158*a0c7f9aaSSamuel Khuvis     sample_counter_functions[0] = (ps_sample_counter_t)dlsym(
159*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_sample_counter");
160*a0c7f9aaSSamuel Khuvis     set_metadata_functions[0] =
161*a0c7f9aaSSamuel Khuvis         (ps_set_metadata_t)dlsym(RTLD_DEFAULT, "ps_tool_set_metadata");
162*a0c7f9aaSSamuel Khuvis     get_timer_data_functions[0] = (ps_get_timer_data_t)dlsym(
163*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_get_timer_data");
164*a0c7f9aaSSamuel Khuvis     get_counter_data_functions[0] = (ps_get_counter_data_t)dlsym(
165*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_get_counter_data");
166*a0c7f9aaSSamuel Khuvis     get_metadata_functions[0] = (ps_get_metadata_t)dlsym(
167*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_get_metadata");
168*a0c7f9aaSSamuel Khuvis     free_timer_data_functions[0] = (ps_free_timer_data_t)dlsym(
169*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_free_timer_data");
170*a0c7f9aaSSamuel Khuvis     free_counter_data_functions[0] = (ps_free_counter_data_t)dlsym(
171*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_free_counter_data");
172*a0c7f9aaSSamuel Khuvis     free_metadata_functions[0] = (ps_free_metadata_t)dlsym(
173*a0c7f9aaSSamuel Khuvis         RTLD_DEFAULT, "ps_tool_free_metadata");
174*a0c7f9aaSSamuel Khuvis #endif
175*a0c7f9aaSSamuel Khuvis     perfstubs_initialized = PERFSTUBS_SUCCESS;
176*a0c7f9aaSSamuel Khuvis     /* Increment the number of tools */
177*a0c7f9aaSSamuel Khuvis     num_tools_registered = 1;
178*a0c7f9aaSSamuel Khuvis #endif //PERFSTUBS_OFF
179*a0c7f9aaSSamuel Khuvis }
180*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
181*a0c7f9aaSSamuel Khuvis #pragma GCC diagnostic pop  // Restore diagnostics state
182*a0c7f9aaSSamuel Khuvis #endif
183*a0c7f9aaSSamuel Khuvis 
184*a0c7f9aaSSamuel Khuvis char * ps_make_timer_name_(const char * file,
185*a0c7f9aaSSamuel Khuvis     const char * func, int line) {
186*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
187*a0c7f9aaSSamuel Khuvis     /* The length of the line number as a string is floor(log10(abs(num))) */
188*a0c7f9aaSSamuel Khuvis     int string_length = (strlen(file) + strlen(func) + floor(log10(abs(line))) + 11);
189*a0c7f9aaSSamuel Khuvis     char * name = (char*)calloc(string_length, sizeof(char));
190*a0c7f9aaSSamuel Khuvis     sprintf(name, "%s [{%s} {%d,0}]", func, file, line);
191*a0c7f9aaSSamuel Khuvis     return (name);
192*a0c7f9aaSSamuel Khuvis     #else
193*a0c7f9aaSSamuel Khuvis     return NULL;
194*a0c7f9aaSSamuel Khuvis     #endif
195*a0c7f9aaSSamuel Khuvis }
196*a0c7f9aaSSamuel Khuvis 
197*a0c7f9aaSSamuel Khuvis // used internally to the class
198*a0c7f9aaSSamuel Khuvis void ps_register_thread_internal(void) {
199*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
200*a0c7f9aaSSamuel Khuvis     	int i;
201*a0c7f9aaSSamuel Khuvis     for (i = 0 ; i < num_tools_registered ; i++) {
202*a0c7f9aaSSamuel Khuvis         register_thread_functions[i]();
203*a0c7f9aaSSamuel Khuvis     }
204*a0c7f9aaSSamuel Khuvis     thread_seen = 1;
205*a0c7f9aaSSamuel Khuvis #endif
206*a0c7f9aaSSamuel Khuvis }
207*a0c7f9aaSSamuel Khuvis 
208*a0c7f9aaSSamuel Khuvis /* Initialization */
209*a0c7f9aaSSamuel Khuvis void ps_initialize_(void) {
210*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
211*a0c7f9aaSSamuel Khuvis     int i;
212*a0c7f9aaSSamuel Khuvis     initialize_library();
213*a0c7f9aaSSamuel Khuvis     for (i = 0 ; i < num_tools_registered ; i++) {
214*a0c7f9aaSSamuel Khuvis         initialize_functions[i]();
215*a0c7f9aaSSamuel Khuvis     }
216*a0c7f9aaSSamuel Khuvis     /* No need to register the main thread */
217*a0c7f9aaSSamuel Khuvis     thread_seen = 1;
218*a0c7f9aaSSamuel Khuvis #endif
219*a0c7f9aaSSamuel Khuvis }
220*a0c7f9aaSSamuel Khuvis 
221*a0c7f9aaSSamuel Khuvis void ps_finalize_(void) {
222*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
223*a0c7f9aaSSamuel Khuvis     int i;
224*a0c7f9aaSSamuel Khuvis     for (i = 0 ; i < num_tools_registered ; i++) {
225*a0c7f9aaSSamuel Khuvis         finalize_functions[i]();
226*a0c7f9aaSSamuel Khuvis     }
227*a0c7f9aaSSamuel Khuvis     #endif
228*a0c7f9aaSSamuel Khuvis }
229*a0c7f9aaSSamuel Khuvis 
230*a0c7f9aaSSamuel Khuvis void ps_register_thread_(void) {
231*a0c7f9aaSSamuel Khuvis #ifndef PERFSTUBS_OFF
232*a0c7f9aaSSamuel Khuvis     if (thread_seen == 0) {
233*a0c7f9aaSSamuel Khuvis         ps_register_thread_internal();
234*a0c7f9aaSSamuel Khuvis     }
235*a0c7f9aaSSamuel Khuvis #endif
236*a0c7f9aaSSamuel Khuvis }
237*a0c7f9aaSSamuel Khuvis 
238*a0c7f9aaSSamuel Khuvis void* ps_timer_create_(const char *timer_name) {
239*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
240*a0c7f9aaSSamuel Khuvis     void ** objects = (void**)calloc(num_tools_registered, sizeof(void*));
241*a0c7f9aaSSamuel Khuvis     int i;
242*a0c7f9aaSSamuel Khuvis     for (i = 0 ; i < num_tools_registered ; i++) {
243*a0c7f9aaSSamuel Khuvis         objects[i] = (void*)timer_create_functions[i](timer_name);
244*a0c7f9aaSSamuel Khuvis     }
245*a0c7f9aaSSamuel Khuvis     return (void*)(objects);
246*a0c7f9aaSSamuel Khuvis     #else
247*a0c7f9aaSSamuel Khuvis     return NULL;
248*a0c7f9aaSSamuel Khuvis     #endif
249*a0c7f9aaSSamuel Khuvis }
250*a0c7f9aaSSamuel Khuvis 
251*a0c7f9aaSSamuel Khuvis void ps_timer_create_fortran_(void ** object, const char *timer_name) {
252*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
253*a0c7f9aaSSamuel Khuvis     *object = ps_timer_create_(timer_name);
254*a0c7f9aaSSamuel Khuvis     #endif
255*a0c7f9aaSSamuel Khuvis }
256*a0c7f9aaSSamuel Khuvis 
257*a0c7f9aaSSamuel Khuvis void ps_timer_start_(const void *timer) {
258*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
259*a0c7f9aaSSamuel Khuvis     void ** objects = (void**)(timer);
260*a0c7f9aaSSamuel Khuvis     int i;
261*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
262*a0c7f9aaSSamuel Khuvis         timer_start_functions[i](objects[i]);
263*a0c7f9aaSSamuel Khuvis     }
264*a0c7f9aaSSamuel Khuvis     #endif
265*a0c7f9aaSSamuel Khuvis }
266*a0c7f9aaSSamuel Khuvis 
267*a0c7f9aaSSamuel Khuvis void ps_timer_start_fortran_(const void **timer) {
268*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
269*a0c7f9aaSSamuel Khuvis     ps_timer_start_(*timer);
270*a0c7f9aaSSamuel Khuvis     #endif
271*a0c7f9aaSSamuel Khuvis }
272*a0c7f9aaSSamuel Khuvis 
273*a0c7f9aaSSamuel Khuvis void ps_timer_stop_(const void *timer) {
274*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
275*a0c7f9aaSSamuel Khuvis     void ** objects = (void**)(timer);
276*a0c7f9aaSSamuel Khuvis     int i;
277*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
278*a0c7f9aaSSamuel Khuvis         timer_stop_functions[i](objects[i]);
279*a0c7f9aaSSamuel Khuvis     }
280*a0c7f9aaSSamuel Khuvis     #endif
281*a0c7f9aaSSamuel Khuvis }
282*a0c7f9aaSSamuel Khuvis 
283*a0c7f9aaSSamuel Khuvis void ps_timer_stop_fortran_(const void **timer) {
284*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
285*a0c7f9aaSSamuel Khuvis     ps_timer_stop_(*timer);
286*a0c7f9aaSSamuel Khuvis     #endif
287*a0c7f9aaSSamuel Khuvis }
288*a0c7f9aaSSamuel Khuvis 
289*a0c7f9aaSSamuel Khuvis void ps_set_parameter_(const char * parameter_name, int64_t parameter_value) {
290*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
291*a0c7f9aaSSamuel Khuvis     int i;
292*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
293*a0c7f9aaSSamuel Khuvis         set_parameter_functions[i](parameter_name, parameter_value);
294*a0c7f9aaSSamuel Khuvis     }
295*a0c7f9aaSSamuel Khuvis     #endif
296*a0c7f9aaSSamuel Khuvis }
297*a0c7f9aaSSamuel Khuvis 
298*a0c7f9aaSSamuel Khuvis void ps_dynamic_phase_start_(const char *phase_prefix, int iteration_index) {
299*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
300*a0c7f9aaSSamuel Khuvis     int i;
301*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
302*a0c7f9aaSSamuel Khuvis         dynamic_phase_start_functions[i](phase_prefix, iteration_index);
303*a0c7f9aaSSamuel Khuvis     }
304*a0c7f9aaSSamuel Khuvis     #endif
305*a0c7f9aaSSamuel Khuvis }
306*a0c7f9aaSSamuel Khuvis 
307*a0c7f9aaSSamuel Khuvis void ps_dynamic_phase_stop_(const char *phase_prefix, int iteration_index) {
308*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
309*a0c7f9aaSSamuel Khuvis     int i;
310*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
311*a0c7f9aaSSamuel Khuvis         dynamic_phase_stop_functions[i](phase_prefix, iteration_index);
312*a0c7f9aaSSamuel Khuvis     }
313*a0c7f9aaSSamuel Khuvis     #endif
314*a0c7f9aaSSamuel Khuvis }
315*a0c7f9aaSSamuel Khuvis 
316*a0c7f9aaSSamuel Khuvis void* ps_create_counter_(const char *name) {
317*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
318*a0c7f9aaSSamuel Khuvis     void ** objects = (void**)calloc(num_tools_registered, sizeof(void*));
319*a0c7f9aaSSamuel Khuvis     int i;
320*a0c7f9aaSSamuel Khuvis     for (i = 0 ; i < num_tools_registered ; i++) {
321*a0c7f9aaSSamuel Khuvis         objects[i] = (void*)create_counter_functions[i](name);
322*a0c7f9aaSSamuel Khuvis     }
323*a0c7f9aaSSamuel Khuvis     return (void*)(objects);
324*a0c7f9aaSSamuel Khuvis     #else
325*a0c7f9aaSSamuel Khuvis     return NULL;
326*a0c7f9aaSSamuel Khuvis     #endif
327*a0c7f9aaSSamuel Khuvis }
328*a0c7f9aaSSamuel Khuvis 
329*a0c7f9aaSSamuel Khuvis void ps_create_counter_fortran_(void ** object, const char *name) {
330*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
331*a0c7f9aaSSamuel Khuvis     *object = ps_create_counter_(name);
332*a0c7f9aaSSamuel Khuvis     #endif
333*a0c7f9aaSSamuel Khuvis }
334*a0c7f9aaSSamuel Khuvis 
335*a0c7f9aaSSamuel Khuvis void ps_sample_counter_(const void *counter, const double value) {
336*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
337*a0c7f9aaSSamuel Khuvis     void ** objects = (void**)(counter);
338*a0c7f9aaSSamuel Khuvis     int i;
339*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
340*a0c7f9aaSSamuel Khuvis         sample_counter_functions[i](objects[i], value);
341*a0c7f9aaSSamuel Khuvis     }
342*a0c7f9aaSSamuel Khuvis     #endif
343*a0c7f9aaSSamuel Khuvis }
344*a0c7f9aaSSamuel Khuvis 
345*a0c7f9aaSSamuel Khuvis void ps_sample_counter_fortran_(const void **counter, const double value) {
346*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
347*a0c7f9aaSSamuel Khuvis     ps_sample_counter_(*counter, value);
348*a0c7f9aaSSamuel Khuvis     #endif
349*a0c7f9aaSSamuel Khuvis }
350*a0c7f9aaSSamuel Khuvis 
351*a0c7f9aaSSamuel Khuvis void ps_set_metadata_(const char *name, const char *value) {
352*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
353*a0c7f9aaSSamuel Khuvis     int i;
354*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
355*a0c7f9aaSSamuel Khuvis         set_metadata_functions[i](name, value);
356*a0c7f9aaSSamuel Khuvis     }
357*a0c7f9aaSSamuel Khuvis     #endif
358*a0c7f9aaSSamuel Khuvis }
359*a0c7f9aaSSamuel Khuvis 
360*a0c7f9aaSSamuel Khuvis void ps_dump_data_(void) {
361*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
362*a0c7f9aaSSamuel Khuvis     int i;
363*a0c7f9aaSSamuel Khuvis     for (i = 0; i < num_tools_registered ; i++) {
364*a0c7f9aaSSamuel Khuvis         dump_data_functions[i]();
365*a0c7f9aaSSamuel Khuvis     }
366*a0c7f9aaSSamuel Khuvis     #endif
367*a0c7f9aaSSamuel Khuvis }
368*a0c7f9aaSSamuel Khuvis 
369*a0c7f9aaSSamuel Khuvis void ps_get_timer_data_(ps_tool_timer_data_t *timer_data, int tool_id) {
370*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
371*a0c7f9aaSSamuel Khuvis     if (tool_id < num_tools_registered) {
372*a0c7f9aaSSamuel Khuvis         get_timer_data_functions[tool_id](timer_data);
373*a0c7f9aaSSamuel Khuvis     }
374*a0c7f9aaSSamuel Khuvis     #endif
375*a0c7f9aaSSamuel Khuvis }
376*a0c7f9aaSSamuel Khuvis 
377*a0c7f9aaSSamuel Khuvis void ps_get_counter_data_(ps_tool_counter_data_t *counter_data, int tool_id) {
378*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
379*a0c7f9aaSSamuel Khuvis     if (tool_id < num_tools_registered) {
380*a0c7f9aaSSamuel Khuvis         get_counter_data_functions[tool_id](counter_data);
381*a0c7f9aaSSamuel Khuvis     }
382*a0c7f9aaSSamuel Khuvis     #endif
383*a0c7f9aaSSamuel Khuvis }
384*a0c7f9aaSSamuel Khuvis 
385*a0c7f9aaSSamuel Khuvis void ps_get_metadata_(ps_tool_metadata_t *metadata, int tool_id) {
386*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
387*a0c7f9aaSSamuel Khuvis     if (tool_id < num_tools_registered) {
388*a0c7f9aaSSamuel Khuvis         get_metadata_functions[tool_id](metadata);
389*a0c7f9aaSSamuel Khuvis     }
390*a0c7f9aaSSamuel Khuvis     #endif
391*a0c7f9aaSSamuel Khuvis }
392*a0c7f9aaSSamuel Khuvis 
393*a0c7f9aaSSamuel Khuvis void ps_free_timer_data_(ps_tool_timer_data_t *timer_data, int tool_id) {
394*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
395*a0c7f9aaSSamuel Khuvis     if (tool_id < num_tools_registered) {
396*a0c7f9aaSSamuel Khuvis         free_timer_data_functions[tool_id](timer_data);
397*a0c7f9aaSSamuel Khuvis     }
398*a0c7f9aaSSamuel Khuvis     #endif
399*a0c7f9aaSSamuel Khuvis }
400*a0c7f9aaSSamuel Khuvis 
401*a0c7f9aaSSamuel Khuvis void ps_free_counter_data_(ps_tool_counter_data_t *counter_data, int tool_id) {
402*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
403*a0c7f9aaSSamuel Khuvis     if (tool_id < num_tools_registered) {
404*a0c7f9aaSSamuel Khuvis         free_counter_data_functions[tool_id](counter_data);
405*a0c7f9aaSSamuel Khuvis     }
406*a0c7f9aaSSamuel Khuvis     #endif
407*a0c7f9aaSSamuel Khuvis }
408*a0c7f9aaSSamuel Khuvis 
409*a0c7f9aaSSamuel Khuvis void ps_free_metadata_(ps_tool_metadata_t *metadata, int tool_id) {
410*a0c7f9aaSSamuel Khuvis     #ifndef PERFSTUBS_OFF
411*a0c7f9aaSSamuel Khuvis     if (tool_id < num_tools_registered) {
412*a0c7f9aaSSamuel Khuvis         free_metadata_functions[tool_id](metadata);
413*a0c7f9aaSSamuel Khuvis     }
414*a0c7f9aaSSamuel Khuvis     #endif
415*a0c7f9aaSSamuel Khuvis }
416