/home/users/khuck/src/hpx-lsu/apex/src/apex/apex.cpp

Line% of fetchesSource
1  
//  Copyright (c) 2014 University of Oregon
2  
//
3  
4  
#ifdef APEX_HAVE_HPX
5  
#include <hpx/config.hpp>
6  
#endif
7  
8  
#include "apex.hpp"
9  
#include "apex_api.hpp"
10  
#include "apex_types.h"
11  
#include <iostream>
12  
#include <stdlib.h>
13  
#include <string>
14  
#include <memory>
15  
#if APEX_USE_PLUGINS
16  
#include <dlfcn.h>
17  
#endif
18  
//#include <cxxabi.h> // this is for demangling strings.
19  
20  
#include "concurrency_handler.hpp"
21  
#include "policy_handler.hpp"
22  
#include "thread_instance.hpp"
23  
#include "utils.hpp"
24  
25  
#ifdef APEX_HAVE_TAU
26  
#include "tau_listener.hpp"
27  
#define PROFILING_ON
28  
//#define TAU_GNU
29  
#define TAU_DOT_H_LESS_HEADERS
30  
#include <TAU.h>
31  
#endif
32  
#include "profiler_listener.hpp"
33  
#ifdef APEX_DEBUG
34  
#include "apex_error_handling.hpp"
35  
#endif
36  
#include "address_resolution.hpp"
37  
38  
#ifdef APEX_HAVE_OTF2
39  
#include "otf2_listener.hpp"
40  
#endif
41  
42  
#ifdef APEX_HAVE_RCR
43  
#include "libenergy.h"
44  
#endif
45  
46  
#if APEX_HAVE_PROC
47  
#include "proc_read.h"
48  
#endif
49  
50  
APEX_NATIVE_TLS bool _registered = false;
51  
APEX_NATIVE_TLS bool _exited = false;
52  
static bool _initialized = false;
53  
54  
using namespace std;
55  
56  
namespace apex
57  
{
58  
59  
// Global static pointer used to ensure a single instance of the class.
60  
std::atomic<apex*> apex::m_pInstance(nullptr);
61  
62  
std::atomic<bool> _notify_listeners(true);
63  
std::atomic<bool> _measurement_stopped(false);
64  
#ifdef APEX_DEBUG
65  
std::atomic<unsigned int> _starts(0L);
66  
std::atomic<unsigned int> _stops(0L);
67  
std::atomic<unsigned int> _exit_stops(0L);
68  
std::atomic<unsigned int> _resumes(0L);
69  
std::atomic<unsigned int> _yields(0L);
70  
#endif
71  
72  
/*
73  
 * The destructor will request power data from RCRToolkit
74  
 */
75  
apex::~apex()
76  
{
77  
#ifdef APEX_HAVE_RCR
78  
    //cout << "Getting energy..." << endl;
79  
    energyDaemonTerm();
80  
#endif
81  
    for (unsigned int i = listeners.size(); i > 0 ; i--) {
82  
        event_listener * el = listeners[i-1];
83  
        listeners.pop_back();
84  
        delete el;
85  
    }
86  
#if APEX_HAVE_PROC
87  
    if (pd_reader != nullptr) {
88  
        delete pd_reader;
89  
    }
90  
#endif
91  
    m_pInstance = nullptr;
92  
}
93  
94  
int apex::get_node_id()
95  
{
96  
    return m_node_id;
97  
}
98  
99  
int apex::get_num_ranks()
100  
{
101  
    return m_num_ranks;
102  
}
103  
104  
#ifdef APEX_HAVE_HPX
105  
static void init_hpx_runtime_ptr(void) {
106  
    if (apex_options::disable() == true) { return; }
107  
    apex * instance = apex::instance();
108  
    if(instance != nullptr) {
109  
        hpx::runtime * runtime = hpx::get_runtime_ptr();
110  
        instance->set_hpx_runtime(runtime);
111  
    }
112  
}
113  
#endif
114  
115  
/*
116  
 * This private method is used to perform whatever initialization
117  
 * needs to happen.
118  
 */
119  
void apex::_initialize()
120  
{
121  
#ifdef APEX_DEBUG
122  
    apex_register_signal_handler();
123  
    //apex_test_signal_handler();
124  
#endif
125  
    this->m_pInstance = this;
126  
    this->m_policy_handler = nullptr;
127  
    stringstream ss;
128  
    ss << "locality#" << this->m_node_id;
129  
    this->m_my_locality = string(ss.str());
130  
    stringstream tmp;
131  
#if defined (GIT_TAG)
132  
    tmp << GIT_TAG;
133  
#else
134  
    tmp << APEX_VERSION_MAJOR + (APEX_VERSION_MINOR/10.0);
135  
#endif
136  
#if defined (GIT_COMMIT_HASH)
137  
    tmp << "-" << GIT_COMMIT_HASH ;
138  
#endif
139  
#if defined (GIT_BRANCH)
140  
    tmp << "-" << GIT_BRANCH ;
141  
#endif
142  
    tmp << std::endl << "Built on: " << __TIME__ << " " << __DATE__;
143  
    tmp << std::endl << "C++ Language Standard version : " << __cplusplus;
144  
#if defined(__clang__)
145  
    /* Clang/LLVM. ---------------------------------------------- */
146  
    tmp << std::endl << "Clang Compiler version : " << __VERSION__;
147  
#elif defined(__ICC) || defined(__INTEL_COMPILER)
148  
    /* Intel ICC/ICPC. ------------------------------------------ */
149  
    tmp << std::endl << "Intel Compiler version : " << __VERSION__;
150  
#elif defined(__GNUC__) || defined(__GNUG__)
151  
    /* GNU GCC/G++. --------------------------------------------- */
152  
    tmp << std::endl << "GCC Compiler version : " << __VERSION__;
153  
#elif defined(__HP_cc) || defined(__HP_aCC)
154  
    /* Hewlett-Packard C/aC++. ---------------------------------- */
155  
    tmp << std::endl << "HP Compiler version : " << __HP_aCC;
156  
#elif defined(__IBMC__) || defined(__IBMCPP__)
157  
    /* IBM XL C/C++. -------------------------------------------- */
158  
    tmp << std::endl << "IBM Compiler version : " << __xlC__;
159  
#elif defined(_MSC_VER)
160  
    /* Microsoft Visual Studio. --------------------------------- */
161  
    tmp << std::endl << "Microsoft Compiler version : " << _MSC_FULL_VER;
162  
#elif defined(__PGI)
163  
    /* Portland Group PGCC/PGCPP. ------------------------------- */
164  
    tmp << std::endl << "PGI Compiler version : " << __VERSION__;
165  
#elif defined(__SUNPRO_CC)
166  
    /* Oracle Solaris Studio. ----------------------------------- */
167  
    tmp << std::endl << "Oracle Compiler version : " << __SUNPRO_CC;
168  
#endif
169  
170  
    this->version_string = std::string(tmp.str().c_str());
171  
#ifdef APEX_HAVE_HPX
172  
    this->m_hpx_runtime = nullptr;
173  
    hpx::register_startup_function(init_hpx_runtime_ptr);
174  
#endif
175  
#ifdef APEX_HAVE_RCR
176  
    energyDaemonInit();
177  
#endif
178  
#ifdef APEX_HAVE_MSR
179  
    apex_init_msr();
180  
#endif
181  
#ifdef APEX_HAVE_TAU
182  
    if (apex_options::use_tau())
183  
    {
184  
        // before spawning any other threads, initialize TAU.
185  
        char * tmp = const_cast<char*>("APEX");
186  
        char * argv[] = {tmp};
187  
        int argc = 1;
188  
        tau_listener::initialize_tau(argc, argv);
189  
    }
190  
#endif
191  
    {
192  
        //write_lock_type l(listener_mutex);
193  
        this->the_profiler_listener = new profiler_listener();
194  
        // this is always the first listener!
195  
   	    listeners.push_back(the_profiler_listener);
196  
#ifdef APEX_HAVE_TAU
197  
        if (apex_options::use_tau())
198  
        {
199  
            listeners.push_back(new tau_listener());
200  
        }
201  
#endif
202  
#ifdef APEX_HAVE_OTF2
203  
        if (apex_options::use_otf2())
204  
        {
205  
            listeners.push_back(new otf2_listener());
206  
        }
207  
#endif
208  
        startup_throttling();
209  
        if (apex_options::use_policy())
210  
        {
211  
            this->m_policy_handler = new policy_handler();
212  
            listeners.push_back(this->m_policy_handler);
213  
        }
214  
        if (apex_options::use_concurrency() > 0)
215  
        {
216  
            listeners.push_back(new concurrency_handler(apex_options::concurrency_period(), apex_options::use_concurrency()));
217  
        }
218  
    }
219  
#if APEX_HAVE_PROC
220  
    if (apex_options::use_proc_cpuinfo() ||
221  
        apex_options::use_proc_meminfo() ||
222  
        apex_options::use_proc_net_dev() ||
223  
        apex_options::use_proc_self_status() ||
224  
        apex_options::use_proc_stat()) {
225  
        pd_reader = new proc_data_reader();
226  
    } else {
227  
        pd_reader = nullptr;
228  
    }
229  
#endif
230  
    this->resize_state(1);
231  
    this->set_state(0, APEX_BUSY);
232  
}
233  
234  
apex* apex::instance()
235  
{
236  
    static std::mutex init_mutex;
237  
    // Only allow one instance of class to be generated.
238  
    if (m_pInstance == nullptr) {
239  
        if (_measurement_stopped) {
240  
            return nullptr;
241  
        } else {
242  
            unique_lock<mutex> l(init_mutex);
243  
            if (m_pInstance == nullptr) {
244  
                m_pInstance = new apex();
245  
            }
246  
        }
247  
    }
248  
    return m_pInstance;
249  
}
250  
251  
/* This function is used to set up thread-specific data structures
252  
 * for each of the asynchronous threads in APEX. For example, the
253  
 * proc_read thread needs a queue for processing sampled values.
254  
 */
255  
void apex::async_thread_setup() {
256  
    apex* instance = apex::instance();
257  
	instance->the_profiler_listener->async_thread_setup();
258  
}
259  
260  
// special case - for cleanup only!
261  
apex* apex::__instance()
262  
{
263  
    return m_pInstance;
264  
}
265  
266  
policy_handler * apex::get_policy_handler(void) const
267  
{
268  
    return this->m_policy_handler;
269  
}
270  
271  
policy_handler * apex::get_policy_handler(uint64_t const& period)
272  
{
273  
    if(apex_options::use_policy() && period_handlers.count(period) == 0)
274  
    {
275  
        period_handlers[period] = new policy_handler(period);
276  
        //write_lock_type l(listener_mutex);
277  
        listeners.push_back(period_handlers[period]);
278  
    }
279  
    return period_handlers[period];
280  
}
281  
282  
#ifdef APEX_HAVE_HPX
283  
void apex::set_hpx_runtime(hpx::runtime * hpx_runtime) {
284  
    m_hpx_runtime = hpx_runtime;
285  
}
286  
287  
hpx::runtime * apex::get_hpx_runtime(void) {
288  
    return m_hpx_runtime;
289  
}
290  
#endif
291  
292  
int initialize_worker_thread_for_TAU(void) {
293  
#ifdef APEX_HAVE_TAU
294  
  if (apex_options::use_tau())
295  
  {
296  
    //if (thread_instance::get_id() > 0) {
297  
      TAU_REGISTER_THREAD();
298  
    //}
299  
    Tau_create_top_level_timer_if_necessary();
300  
  }
301  
#endif
302  
  return 0;
303  
}
304  
305  
uint64_t init(const char * thread_name, uint64_t comm_rank, uint64_t comm_size) {
306  
    // if APEX is disabled, do nothing.
307  
    if (apex_options::disable() == true) { return APEX_ERROR; }
308  
    // protect against multiple initializations
309  
    if (_registered || _initialized) { return APEX_ERROR; }
310  
    _registered = true;
311  
    _initialized = true;
312  
    apex* instance = apex::instance(); // get/create the Apex static instance
313  
    // assign the rank and size.  Why not in the constructor?
314  
    // because, if we registered a startup policy, the default
315  
    // constructor was called, without the correct comm_rank and comm_size.
316  
	if (comm_rank < comm_size && comm_size > 0) { // simple validation
317  
      instance->set_node_id(comm_rank);
318  
      instance->set_num_ranks(comm_size);
319  
	}
320  
    if (!instance || _exited) return APEX_ERROR; // protect against calls after finalization
321  
    init_plugins();
322  
    startup_event_data data(comm_rank, comm_size);
323  
    if (_notify_listeners) {
324  
        //read_lock_type l(instance->listener_mutex);
325  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
326  
            instance->listeners[i]->on_startup(data);
327  
        }
328  
    }
329  
#if HAVE_TAU_disabled
330  
    // start top-level timers for threads
331  
    if (thread_name) {
332  
      start(thread_name);
333  
    } else {
334  
      start("APEX MAIN THREAD");
335  
    }
336  
#else
337  
    APEX_UNUSED(thread_name);
338  
#endif
339  
    if (apex_options::use_screen_output() && instance->get_node_id() == 0) {
340  
	  std::cout << version() << std::endl;
341  
      apex_options::print_options();
342  
	}
343  
    if (apex_options::throttle_energy() && apex_options::throttle_concurrency() ) {
344  
      setup_power_cap_throttling();
345  
    }
346  
    // this code should be absorbed from "new node" event to "on_startup" event.
347  
    node_event_data node_data(comm_rank, thread_instance::get_id());
348  
    if (_notify_listeners) {
349  
        //read_lock_type l(instance->listener_mutex);
350  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
351  
            instance->listeners[i]->on_new_node(node_data);
352  
        }
353  
    }
354  
    /* register the finalization function, for program exit */
355  
    std::atexit(finalize);
356  
    return APEX_NOERROR;
357  
}
358  
359  
string& version() {
360  
    // if APEX is disabled, do nothing.
361  
    if (apex_options::disable() == true) { static string tmp("disabled"); return tmp; }
362  
    apex* instance = apex::instance(); // get the Apex static instance
363  
    return instance->version_string;
364  
}
365  
366  
profiler* start(const std::string &timer_name)
367  
{
368  
    // if APEX is disabled, do nothing.
369  
    if (apex_options::disable() == true) { return nullptr; }
370  
    if (starts_with(timer_name, string("apex_internal"))) {
371  
        return profiler::get_disabled_profiler(); // don't process our own events - queue scrubbing tasks.
372  
    }
373  
#ifdef APEX_HAVE_HPX
374  
    // Finalize at the _start_ of HPX shutdown so that we can stop any
375  
    // outstanding hpx::util::interval_timer instances. If any are left
376  
    // running, HPX shutdown will never complete.
377  
    if (starts_with(timer_name, string("shutdown_all"))) {
378  
        finalize();
379  
        return profiler::get_disabled_profiler();
380  
    }
381  
#endif
382  
#ifdef APEX_DEBUG
383  
    _starts++;
384  
#endif
385  
    // if APEX is suspended, do nothing.
386  
    if (apex_options::suspend() == true) { return profiler::get_disabled_profiler(); }
387  
    apex* instance = apex::instance(); // get the Apex static instance
388  
    if (!instance || _exited) return nullptr; // protect against calls after finalization
389  
    if (_notify_listeners) {
390  
        bool success = true;
391  
		task_identifier * id = new task_identifier(timer_name);
392  
        //read_lock_type l(instance->listener_mutex);
393  
		//cout << thread_instance::get_id() << " Start : " << id->get_name() << endl; fflush(stdout);
394  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
395  
            success = instance->listeners[i]->on_start(id);
396  
            if (!success && i == 0) {
397  
				//cout << thread_instance::get_id() << " *** Not success! " << id->get_name() << endl; fflush(stdout);
398  
                return profiler::get_disabled_profiler();
399  
            }
400  
        }
401  
    }
402  
#ifdef APEX_DEBUG
403  
    thread_instance::instance().add_open_profiler(thread_instance::instance().get_current_profiler());
404  
#endif
405  
    return thread_instance::instance().get_current_profiler();
406  
}
407  
408  
profiler* start(apex_function_address function_address) {
409  
    // if APEX is disabled, do nothing.
410  
    if (apex_options::disable() == true) { return nullptr; }
411  
#ifdef APEX_DEBUG
412  
    _starts++;
413  
#endif
414  
    // if APEX is suspended, do nothing.
415  
    if (apex_options::suspend() == true) { return profiler::get_disabled_profiler(); }
416  
    apex* instance = apex::instance(); // get the Apex static instance
417  
    if (!instance || _exited) return nullptr; // protect against calls after finalization
418  
    if (_notify_listeners) {
419  
        bool success = true;
420  
		task_identifier * id = new task_identifier(function_address);
421  
		//cout << thread_instance::get_id() << " Start : " << id->get_name() << endl; fflush(stdout);
422  
        //read_lock_type l(instance->listener_mutex);
423  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
424  
            success = instance->listeners[i]->on_start(id);
425  
            if (!success && i == 0) {
426  
				//cout << thread_instance::get_id() << " *** Not success! " << id->get_name() << endl; fflush(stdout);
427  
                return profiler::get_disabled_profiler();
428  
            }
429  
        }
430  
    }
431  
#ifdef APEX_DEBUG
432  
    /*
433  
    if (instance->get_node_id() == 0) {
434  
        printf("%lu Start: %s %p\n", thread_instance::get_id(), lookup_address((uintptr_t)function_address, false)->c_str(), thread_instance::instance().get_current_profiler());
435  
        fflush(stdout);
436  
    }
437  
    */
438  
#endif
439  
#ifdef APEX_DEBUG
440  
    thread_instance::instance().add_open_profiler(thread_instance::instance().get_current_profiler());
441  
#endif
442  
    return thread_instance::instance().get_current_profiler();
443  
}
444  
445  
profiler* resume(const std::string &timer_name) {
446  
    // if APEX is disabled, do nothing.
447  
    if (apex_options::disable() == true) { return nullptr; }
448  
#ifdef APEX_DEBUG
449  
    _resumes++;
450  
#endif
451  
    // if APEX is suspended, do nothing.
452  
    if (apex_options::suspend() == true) { return profiler::get_disabled_profiler(); }
453  
    apex* instance = apex::instance(); // get the Apex static instance
454  
    if (!instance || _exited) return nullptr; // protect against calls after finalization
455  
    if (starts_with(timer_name, string("apex_internal"))) {
456  
        return profiler::get_disabled_profiler(); // don't process our own events
457  
    }
458  
    if (_notify_listeners) {
459  
        task_identifier * id = new task_identifier(timer_name);
460  
        try {
461  
            //read_lock_type l(instance->listener_mutex);
462  
            for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
463  
                instance->listeners[i]->on_resume(id);
464  
            }
465  
        } catch (disabled_profiler_exception e) { return profiler::get_disabled_profiler(); }
466  
    }
467  
#ifdef APEX_DEBUG
468  
    thread_instance::instance().add_open_profiler(thread_instance::instance().get_current_profiler());
469  
#endif
470  
    return thread_instance::instance().get_current_profiler();
471  
}
472  
473  
profiler* resume(apex_function_address function_address) {
474  
    // if APEX is disabled, do nothing.
475  
    if (apex_options::disable() == true) { return nullptr; }
476  
#ifdef APEX_DEBUG
477  
    _resumes++;
478  
#endif
479  
    // if APEX is suspended, do nothing.
480  
    if (apex_options::suspend() == true) { return profiler::get_disabled_profiler(); }
481  
    apex* instance = apex::instance(); // get the Apex static instance
482  
    if (!instance || _exited) return nullptr; // protect against calls after finalization
483  
    if (_notify_listeners) {
484  
        task_identifier * id = new task_identifier(function_address);
485  
        try {
486  
            //read_lock_type l(instance->listener_mutex);
487  
            for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
488  
                instance->listeners[i]->on_resume(id);
489  
            }
490  
        } catch (disabled_profiler_exception e) { return profiler::get_disabled_profiler(); }
491  
    }
492  
#ifdef APEX_DEBUG
493  
/*
494  
    if (instance->get_node_id() == 0) {
495  
        printf("%lu Resume: %s %p\n", thread_instance::get_id(), lookup_address((uintptr_t)function_address, false)->c_str(), thread_instance::instance().get_current_profiler());
496  
        fflush(stdout);
497  
    }
498  
*/
499  
#endif
500  
#ifdef APEX_DEBUG
501  
    thread_instance::instance().add_open_profiler(thread_instance::instance().get_current_profiler());
502  
#endif
503  
    return thread_instance::instance().get_current_profiler();
504  
}
505  
506  
void reset(const std::string &timer_name) {
507  
    // if APEX is disabled, do nothing.
508  
    if (apex_options::disable() == true) { return; }
509  
    apex* instance = apex::instance(); // get the Apex static instance
510  
    if (!instance || _exited) return; // protect against calls after finalization
511  
    task_identifier * id = new task_identifier(timer_name);
512  
    instance->the_profiler_listener->reset(id);
513  
}
514  
515  
void reset(apex_function_address function_address) {
516  
    // if APEX is disabled, do nothing.
517  
    if (apex_options::disable() == true) { return; }
518  
    apex* instance = apex::instance(); // get the Apex static instance
519  
    if (!instance || _exited) return; // protect against calls after finalization
520  
	if (function_address == APEX_NULL_FUNCTION_ADDRESS) {
521  
        instance->the_profiler_listener->reset_all();
522  
	} else {
523  
    	task_identifier * id = new task_identifier(function_address);
524  
    	instance->the_profiler_listener->reset(id);
525  
    }
526  
}
527  
528  
void set_state(apex_thread_state state) {
529  
    // if APEX is disabled, do nothing.
530  
    if (apex_options::disable() == true) { return; }
531  
    apex* instance = apex::instance(); // get the Apex static instance
532  
    if (!instance || _exited) return; // protect against calls after finalization
533  
    instance->set_state(thread_instance::get_id(), state);
534  
}
535  
536  
void stop(profiler* the_profiler) {
537  
	//cout << thread_instance::get_id() << " Stop  : " << the_profiler->task_id->get_name() << endl; fflush(stdout);
538  
    // if APEX is disabled, do nothing.
539  
    if (apex_options::disable() == true) { return; }
540  
#ifdef APEX_DEBUG
541  
    _stops++;
542  
#endif
543  
    if (the_profiler == profiler::get_disabled_profiler()) return; // profiler was throttled.
544  
545  
    apex* instance = apex::instance(); // get the Apex static instance
546  
    if (!instance || _exited) return; // protect against calls after finalization
547  
    if (the_profiler == nullptr || the_profiler->stopped) return;
548  
#ifdef APEX_DEBUG
549  
    thread_instance::instance().remove_open_profiler(thread_instance::instance().get_id(), the_profiler);
550  
    thread_instance::instance().clear_current_profiler();
551  
#endif
552  
	if (_measurement_stopped) { return; } // somehow we are slipping through...
553  
    std::shared_ptr<profiler> p{the_profiler};
554  
    /*
555  
    std::shared_ptr<profiler> p;
556  
    // A null profiler is OK, it means the application didn't store it. We have it.
557  
    if (the_profiler == nullptr) {
558  
        p = std::make_shared<profiler>(thread_instance::instance().pop_current_profiler());
559  
    } else {
560  
        p = std::make_shared<profiler>(thread_instance::instance().pop_current_profiler(the_profiler));
561  
    }
562  
    if (p == nullptr) return;
563  
    */
564  
#ifdef APEX_DEBUG
565  
    /*
566  
    if (instance->get_node_id() == 0) {
567  
        printf("%lu Stop:  %s %p\n", thread_instance::get_id(), lookup_address((uintptr_t)p->action_address, false)->c_str(), the_profiler);
568  
        fflush(stdout);
569  
    }
570  
    */
571  
#endif
572  
    if (_notify_listeners) {
573  
        //read_lock_type l(instance->listener_mutex);
574  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
575  
            instance->listeners[i]->on_stop(p);
576  
        }
577  
    }
578  
}
579  
580  
void yield(profiler* the_profiler)
581  
{
582  
    // if APEX is disabled, do nothing.
583  
    if (apex_options::disable() == true) { return; }
584  
#ifdef APEX_DEBUG
585  
    _yields++;
586  
#endif
587  
    if (the_profiler == profiler::get_disabled_profiler()) return; // profiler was throttled.
588  
589  
    apex* instance = apex::instance(); // get the Apex static instance
590  
    if (!instance || _exited) return; // protect against calls after finalization
591  
    if (the_profiler == nullptr || the_profiler->stopped) return;
592  
#ifdef APEX_DEBUG
593  
    thread_instance::instance().remove_open_profiler(thread_instance::instance().get_id(), the_profiler);
594  
    thread_instance::instance().clear_current_profiler();
595  
#endif
596  
	if (_measurement_stopped) { return; } // somehow we are slipping through...
597  
    std::shared_ptr<profiler> p{the_profiler};
598  
    /*
599  
    std::shared_ptr<profiler> p;
600  
    if (the_profiler == nullptr) {
601  
        p = std::make_shared<profiler>(thread_instance::instance().pop_current_profiler());
602  
    } else {
603  
        p = std::make_shared<profiler>(thread_instance::instance().pop_current_profiler(the_profiler));
604  
    }
605  
    if (p == nullptr) return;
606  
    */
607  
#ifdef APEX_DEBUG
608  
    /*
609  
    if (instance->get_node_id() == 0) {
610  
        printf("%lu Yield:  %s\n", thread_instance::get_id(), lookup_address((uintptr_t)p->action_address, false)->c_str());
611  
        fflush(stdout);
612  
    }
613  
    */
614  
#endif
615  
    if (_notify_listeners) {
616  
        //read_lock_type l(instance->listener_mutex);
617  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
618  
            instance->listeners[i]->on_yield(p);
619  
        }
620  
    }
621  
}
622  
623  
void sample_value(const std::string &name, double value)
624  
{
625  
    // if APEX is disabled, do nothing.
626  
    if (apex_options::disable() == true) { return; }
627  
    // if APEX is suspended, do nothing.
628  
    if (apex_options::suspend() == true) { return; }
629  
    apex* instance = apex::instance(); // get the Apex static instance
630  
    if (!instance || _exited) return; // protect against calls after finalization
631  
    // parse the counter name
632  
    // either /threadqueue{locality#0/total}/length
633  
    // or     /threadqueue{locality#0/worker-thread#0}/length
634  
    sample_value_event_data* data = nullptr;
635  
    if (name.find(instance->m_my_locality) != name.npos)
636  
    {
637  
        if (name.find("worker-thread") != name.npos)
638  
        {
639  
            string tmp_name = string(name.c_str());
640  
            // tokenize by / character
641  
            char* token = strtok(const_cast<char*>(tmp_name.c_str()), "/");
642  
            while (token!=nullptr) {
643  
              if (strstr(token, "worker-thread")==NULL)
644  
              {
645  
                break;
646  
              }
647  
              token = strtok(NULL, "/");
648  
            }
649  
            int tid = 0;
650  
            if (token != nullptr) {
651  
              // strip the trailing close bracket
652  
              token = strtok(token, "}");
653  
              tid = thread_instance::map_name_to_id(token);
654  
            }
655  
            if (tid != -1)
656  
            {
657  
                data = new sample_value_event_data(tid, name, value);
658  
                //Tau_trigger_context_event_thread((char*)name.c_str(), value, tid);
659  
            }
660  
            else
661  
            {
662  
                data = new sample_value_event_data(0, name, value);
663  
                //Tau_trigger_context_event_thread((char*)name.c_str(), value, 0);
664  
            }
665  
        }
666  
        else
667  
        {
668  
            data = new sample_value_event_data(0, name, value);
669  
            //Tau_trigger_context_event_thread((char*)name.c_str(), value, 0);
670  
        }
671  
    }
672  
    else
673  
    {
674  
        // what if it doesn't?
675  
        data = new sample_value_event_data(0, name, value);
676  
    }
677  
    if (_notify_listeners) {
678  
        //read_lock_type l(instance->listener_mutex);
679  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
680  
            instance->listeners[i]->on_sample_value(*data);
681  
        }
682  
    }
683  
    delete(data);
684  
}
685  
686  
void new_task(const std::string &timer_name, uint64_t task_id)
687  
{
688  
    // if APEX is disabled, do nothing.
689  
    if (apex_options::disable() == true) { return; }
690  
    // if APEX is suspended, do nothing.
691  
    if (apex_options::suspend() == true) { return; }
692  
    apex* instance = apex::instance(); // get the Apex static instance
693  
    if (!instance || _exited) return; // protect against calls after finalization
694  
    if (_notify_listeners) {
695  
        task_identifier * id = new task_identifier(timer_name);
696  
        //read_lock_type l(instance->listener_mutex);
697  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
698  
            instance->listeners[i]->on_new_task(id, task_id);
699  
        }
700  
    }
701  
}
702  
703  
void new_task(apex_function_address function_address, uint64_t task_id) {
704  
    // if APEX is disabled, do nothing.
705  
    if (apex_options::disable() == true) { return; }
706  
    // if APEX is suspended, do nothing.
707  
    if (apex_options::suspend() == true) { return; }
708  
    apex* instance = apex::instance(); // get the Apex static instance
709  
    if (!instance || _exited) return; // protect against calls after finalization
710  
    if (_notify_listeners) {
711  
        task_identifier * id = new task_identifier(function_address);
712  
        //read_lock_type l(instance->listener_mutex);
713  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
714  
            instance->listeners[i]->on_new_task(id, task_id);
715  
        }
716  
    }
717  
}
718  
719  
std::atomic<int> custom_event_count(APEX_CUSTOM_EVENT_1);
720  
721  
apex_event_type register_custom_event(const std::string &name) {
722  
    // if APEX is disabled, do nothing.
723  
    if (apex_options::disable() == true) { return APEX_CUSTOM_EVENT_1; }
724  
    apex* instance = apex::instance(); // get the Apex static instance
725  
    if (!instance || _exited) return APEX_CUSTOM_EVENT_1; // protect against calls after finalization
726  
    if (custom_event_count == APEX_MAX_EVENTS) {
727  
      std::cerr << "Cannot register more than MAX Events! (set to " << APEX_MAX_EVENTS << ")" << std::endl;
728  
    }
729  
    write_lock_type l(instance->custom_event_mutex);
730  
    instance->custom_event_names[custom_event_count] = name;
731  
    int tmp = custom_event_count;
732  
    custom_event_count++;
733  
    return (apex_event_type)tmp;
734  
}
735  
736  
void custom_event(apex_event_type event_type, void * custom_data) {
737  
    // if APEX is disabled, do nothing.
738  
    if (apex_options::disable() == true) { return; }
739  
    apex* instance = apex::instance(); // get the Apex static instance
740  
    if (!instance || _exited) return; // protect against calls after finalization
741  
    custom_event_data data(event_type, custom_data);
742  
    if (_notify_listeners) {
743  
        //read_lock_type l(instance->listener_mutex);
744  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
745  
            instance->listeners[i]->on_custom_event(data);
746  
        }
747  
    }
748  
}
749  
750  
#ifdef APEX_HAVE_HPX
751  
hpx::runtime * get_hpx_runtime_ptr(void) {
752  
    apex * instance = apex::instance();
753  
    if (!instance || _exited) {
754  
        return nullptr;
755  
    }
756  
    hpx::runtime * runtime = instance->get_hpx_runtime();
757  
    return runtime;
758  
}
759  
#endif
760  
761  
void init_plugins(void) {
762  
    if (apex_options::disable() == true) { return; }
763  
#ifdef APEX_USE_PLUGINS
764  
    std::string plugin_names_str{apex_options::plugins()};
765  
    std::string plugins_prefix{apex_options::plugins_path()};
766  
    std::string plugins_suffix{".so"};
767  
    if(plugin_names_str.empty()) {
768  
        return;
769  
    }
770  
    std::vector<std::string> plugin_names;
771  
    std::vector<std::string> plugin_paths;
772  
    split( plugin_names_str, ':', plugin_names);
773  
    for(const std::string & plugin_name : plugin_names) {
774  
        plugin_paths.push_back(plugins_prefix + "/" + plugin_name + plugins_suffix);
775  
    }
776  
    for(const std::string & plugin_path : plugin_paths) {
777  
        const char * path = plugin_path.c_str();
778  
        void * plugin_handle = dlopen(path, RTLD_NOW);
779  
        if(!plugin_handle) {
780  
            std::cerr << "Error loading plugin " << path << ": " << dlerror() << std::endl;
781  
            continue;
782  
        }
783  
        int (*init_fn)() = (int (*)()) ((uintptr_t) dlsym(plugin_handle, "apex_plugin_init"));
784  
        if(!init_fn) {
785  
            std::cerr << "Error loading apex_plugin_init from " << path << ": " << dlerror() << std::endl;
786  
            dlclose(plugin_handle);
787  
            continue;
788  
        }
789  
        int (*finalize_fn)() = (int (*)()) ((uintptr_t) dlsym(plugin_handle, "apex_plugin_finalize"));
790  
        if(!finalize_fn) {
791  
            std::cerr << "Error loading apex_plugin_finalize from " << path << ": " << dlerror() << std::endl;
792  
            dlclose(plugin_handle);
793  
            continue;
794  
        }
795  
        apex * instance = apex::instance();
796  
        if(!instance) {
797  
            std::cerr << "Error getting APEX instance while registering finalize function from " << path << std::endl;
798  
            continue;
799  
        }
800  
        instance->finalize_functions.push_back(finalize_fn);
801  
        int result = init_fn();
802  
        if(result != 0) {
803  
            std::cerr << "Error: apex_plugin_init for " << path << " returned " << result << std::endl;
804  
            dlclose(plugin_handle);
805  
            continue;
806  
        }
807  
    }
808  
#endif
809  
}
810  
811  
void finalize_plugins(void) {
812  
    if (apex_options::disable() == true) { return; }
813  
#ifdef APEX_USE_PLUGINS
814  
    apex * instance = apex::instance();
815  
    if(!instance) return;
816  
    for(int (*finalize_function)() : instance->finalize_functions) {
817  
        int result = finalize_function();
818  
        if(result != 0) {
819  
            std::cerr << "Error: plugin finalize function returned " << result << std::endl;
820  
            continue;
821  
        }
822  
    }
823  
#endif
824  
}
825  
826  
void track_power(void)
827  
{
828  
    // if APEX is disabled, do nothing.
829  
    if (apex_options::disable() == true) { return; }
830  
#ifdef APEX_HAVE_TAU
831  
    TAU_TRACK_POWER();
832  
#endif
833  
}
834  
835  
void track_power_here(void)
836  
{
837  
    // if APEX is disabled, do nothing.
838  
    if (apex_options::disable() == true) { return; }
839  
#ifdef APEX_HAVE_TAU
840  
    TAU_TRACK_POWER_HERE();
841  
#endif
842  
}
843  
844  
void enable_tracking_power(void)
845  
{
846  
    // if APEX is disabled, do nothing.
847  
    if (apex_options::disable() == true) { return; }
848  
#ifdef APEX_HAVE_TAU
849  
    TAU_ENABLE_TRACKING_POWER();
850  
#endif
851  
}
852  
853  
void disable_tracking_power(void)
854  
{
855  
    // if APEX is disabled, do nothing.
856  
    if (apex_options::disable() == true) { return; }
857  
#ifdef APEX_HAVE_TAU
858  
    TAU_DISABLE_TRACKING_POWER();
859  
#endif
860  
}
861  
862  
void set_interrupt_interval(int seconds)
863  
{
864  
    // if APEX is disabled, do nothing.
865  
    if (apex_options::disable() == true) { return; }
866  
#ifdef APEX_HAVE_TAU
867  
    TAU_SET_INTERRUPT_INTERVAL(seconds);
868  
#else
869  
    APEX_UNUSED(seconds);
870  
#endif
871  
}
872  
873  
void finalize()
874  
{
875  
	//cout << thread_instance::get_id() << " *** Finalize! " << endl; fflush(stdout);
876  
    // if APEX is disabled, do nothing.
877  
    if (apex_options::disable() == true) { return; }
878  
    // prevent re-entry, be extra strict about race conditions - it is possible.
879  
    mutex shutdown_mutex;
880  
    static bool finalized = false;
881  
    {
882  
        unique_lock<mutex> l(shutdown_mutex);
883  
        if (finalized) { return; };
884  
        finalized = true;
885  
    }
886  
    // if not done already...
887  
    shutdown_throttling();
888  
    apex* instance = apex::instance(); // get the Apex static instance
889  
    if (!instance) return; // protect against calls after finalization
890  
    finalize_plugins();
891  
#if APEX_HAVE_PROC
892  
    if (instance->pd_reader != nullptr) {
893  
        instance->pd_reader->stop_reading();
894  
    }
895  
#endif
896  
    exit_thread();
897  
#if APEX_HAVE_MSR
898  
    apex_finalize_msr();
899  
#endif
900  
    if (!_measurement_stopped)
901  
    {
902  
        _measurement_stopped = true;
903  
#ifdef APEX_DEBUG
904  
        std::cout << instance->get_node_id() << " Starts  : " << _starts  << std::endl;
905  
        std::cout << instance->get_node_id() << " Resumes : " << _resumes << std::endl;
906  
        std::cout << instance->get_node_id() << " Yields  : " << _yields  << std::endl;
907  
        std::cout << instance->get_node_id() << " Stops   : " << _stops   << std::endl;
908  
        std::cout << instance->get_node_id() << " Exit Stops   : " << _exit_stops   << std::endl;
909  
        unsigned int ins = _starts + _resumes;
910  
        unsigned int outs = _yields + _stops + _exit_stops;
911  
        if (ins != outs) {
912  
            std::cout << std::endl;
913  
            std::cout << " ------->>> ERROR! missing ";
914  
            if (ins > outs) {
915  
              std::cout << (ins - outs) << " stops. <<<-------" << std::endl;
916  
            } else {
917  
              std::cout << (outs - ins) << " starts. <<<-------" << std::endl;
918  
            }
919  
            std::cout << std::endl;
920  
            //assert(ins == outs);
921  
            cout << "Profilers that were not stopped:" << endl;
922  
            for (auto tmp : thread_instance::get_open_profilers()) {
923  
                cout << tmp << endl;
924  
            }
925  
        }
926  
#endif
927  
        shutdown_event_data data(instance->get_node_id(), thread_instance::get_id());
928  
        _notify_listeners = false;
929  
        {
930  
            //read_lock_type l(instance->listener_mutex);
931  
            for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
932  
                instance->listeners[i]->on_shutdown(data);
933  
            }
934  
        }
935  
    }
936  
}
937  
938  
void cleanup(void) {
939  
    // if APEX is disabled, do nothing.
940  
    if (apex_options::disable() == true) { return; }
941  
    apex* instance = apex::__instance(); // get the Apex static instance
942  
    if (!instance || _exited) return; // protect against multiple calls
943  
    if (!_measurement_stopped) {
944  
        finalize();
945  
    }
946  
    delete(instance);
947  
}
948  
949  
void register_thread(const std::string &name)
950  
{
951  
    // if APEX is disabled, do nothing.
952  
    if (apex_options::disable() == true) { return; }
953  
    apex* instance = apex::instance(); // get the Apex static instance
954  
    if (!instance || _exited) return; // protect against calls after finalization
955  
    if (_registered) return; // protect against multiple registrations on the same thread
956  
    _registered = true;
957  
    thread_instance::set_name(name);
958  
    instance->resize_state(thread_instance::get_id());
959  
    instance->set_state(thread_instance::get_id(), APEX_BUSY);
960  
    new_thread_event_data data(name);
961  
    if (_notify_listeners) {
962  
            //read_lock_type l(instance->listener_mutex);
963  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
964  
            instance->listeners[i]->on_new_thread(data);
965  
        }
966  
    }
967  
#ifdef APEX_HAVE_TAU_disabled
968  
    // start top-level timers for threads
969  
    string::size_type index = name.find("#");
970  
    if (index!=std::string::npos)
971  
    {
972  
        string short_name = name.substr(0,index);
973  
        start(short_name);
974  
    }
975  
    else
976  
    {
977  
        start(name);
978  
    }
979  
#endif
980  
}
981  
982  
void exit_thread(void)
983  
{
984  
    // if APEX is disabled, do nothing.
985  
    if (apex_options::disable() == true) { return; }
986  
    apex* instance = apex::instance(); // get the Apex static instance
987  
    if (!instance || _exited) return; // protect against calls after finalization
988  
    _exited = true;
989  
    /*
990  
    // pop any remaining timers, and stop them
991  
    std::shared_ptr<profiler> p;
992  
    while(true && !thread_instance::instance().profiler_stack_empty()) {
993  
        p = std::make_shared<profiler>(thread_instance::instance().pop_current_profiler());
994  
        if (p == nullptr) { break; }
995  
#ifdef APEX_DEBUG
996  
        _exit_stops++;
997  
#endif
998  
        if (_notify_listeners) {
999  
            //read_lock_type l(instance->listener_mutex);
1000  
            for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
1001  
                instance->listeners[i]->on_stop(p);
1002  
            }
1003  
        }
1004  
    }
1005  
    */
1006  
    event_data data;
1007  
    if (_notify_listeners) {
1008  
            //read_lock_type l(instance->listener_mutex);
1009  
        for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
1010  
            instance->listeners[i]->on_exit_thread(data);
1011  
        }
1012  
    }
1013  
}
1014  
1015  
apex_policy_handle* register_policy(const apex_event_type when,
1016  
                    std::function<int(apex_context const&)> f)
1017  
{
1018  
    // if APEX is disabled, do nothing.
1019  
    if (apex_options::disable() == true) { return nullptr; }
1020  
    int id = -1;
1021  
    policy_handler * handler = apex::instance()->get_policy_handler();
1022  
    if(handler != nullptr)
1023  
    {
1024  
        id = handler->register_policy(when, f);
1025  
    }
1026  
    apex_policy_handle * handle = new apex_policy_handle();
1027  
    handle->id = id;
1028  
    handle->event_type = when;
1029  
    handle->period = 0;
1030  
    return handle;
1031  
}
1032  
1033  
std::set<apex_policy_handle*> register_policy(std::set<apex_event_type> when,
1034  
                    std::function<int(apex_context const&)> f)
1035  
{
1036  
    // if APEX is disabled, do nothing.
1037  
    if (apex_options::disable() == true) { return std::set<apex_policy_handle*>(); }
1038  
    std::set<apex_event_type>::iterator it;
1039  
    std::set<apex_policy_handle*> handles;
1040  
    for (it = when.begin(); it != when.end(); ++it)
1041  
    {
1042  
        handles.insert(register_policy(*it,f));
1043  
    }
1044  
    return handles;
1045  
}
1046  
1047  
/* How to do it with a chrono object. */
1048  
1049  
/*
1050  
template <typename Rep, typename Period>
1051  
int register_policy(std::chrono::duration<Rep, Period> const& period,
1052  
                    std::function<int(apex_context const&)> f)
1053  
*/
1054  
1055  
apex_policy_handle* register_periodic_policy(unsigned long period_microseconds,
1056  
                    std::function<int(apex_context const&)> f)
1057  
 {
1058  
    // if APEX is disabled, do nothing.
1059  
    if (apex_options::disable() == true) { return nullptr; }
1060  
    int id = -1;
1061  
    policy_handler * handler = apex::instance()->get_policy_handler(period_microseconds);
1062  
    if(handler != nullptr)
1063  
    {
1064  
        id = handler->register_policy(APEX_PERIODIC, f);
1065  
    }
1066  
    apex_policy_handle * handle = new apex_policy_handle();
1067  
    handle->id = id;
1068  
    handle->event_type = APEX_PERIODIC;
1069  
    handle->period = period_microseconds;
1070  
    return handle;
1071  
}
1072  
1073  
void deregister_policy(apex_policy_handle * handle) {
1074  
    // if APEX is disabled, do nothing.
1075  
    if (apex_options::disable() == true) { return; }
1076  
    // disable processing of policy for now
1077  
    //_notify_listeners = false;
1078  
    policy_handler * handler = apex::instance()->get_policy_handler();
1079  
    if(handler != nullptr) {
1080  
        handler->deregister_policy(handle);
1081  
    }
1082  
    //_notify_listeners = true;
1083  
    delete(handle);
1084  
}
1085  
1086  
apex_profile* get_profile(apex_function_address action_address) {
1087  
    // if APEX is disabled, do nothing.
1088  
    if (apex_options::disable() == true) { return nullptr; }
1089  
	task_identifier id(action_address);
1090  
    profile * tmp = apex::__instance()->the_profiler_listener->get_profile(id);
1091  
    if (tmp != nullptr)
1092  
        return tmp->get_profile();
1093  
    return nullptr;
1094  
}
1095  
1096  
apex_profile* get_profile(const std::string &timer_name) {
1097  
    // if APEX is disabled, do nothing.
1098  
    if (apex_options::disable() == true) { return nullptr; }
1099  
	task_identifier id(timer_name);
1100  
    profile * tmp = apex::__instance()->the_profiler_listener->get_profile(id);
1101  
    if (tmp != nullptr)
1102  
        return tmp->get_profile();
1103  
    return nullptr;
1104  
}
1105  
1106  
double current_power_high(void) {
1107  
    double power = 0.0;
1108  
#ifdef APEX_HAVE_RCR
1109  
    power = (double)rcr_current_power_high();
1110  
    //std::cout << "Read power from RCR: " << power << std::endl;
1111  
#elif APEX_HAVE_MSR
1112  
    power = msr_current_power_high();
1113  
    //std::cout << "Read power from MSR: " << power << std::endl;
1114  
#elif APEX_HAVE_PROC
1115  
    power = (double)read_power();
1116  
    //std::cout << "Read power from Cray Power Monitoring and Management: " << power << std::endl;
1117  
#else
1118  
    //std::cout << "NO POWER READING! Did you configure with RCR, MSR or Cray?" << std::endl;
1119  
#endif
1120  
    return power;
1121  
}
1122  
1123  
/*
1124  
std::vector<std::string> get_available_profiles() {
1125  
    return apex::__instance()->the_profiler_listener->get_available_profiles();
1126  
}
1127  
*/
1128  
1129  
void print_options() {
1130  
    // if APEX is disabled, do nothing.
1131  
    if (apex_options::disable() == true) { return; }
1132  
    print_options();
1133  
    return;
1134  
}
1135  
1136  
void send (uint64_t tag, uint64_t size, uint64_t target) {
1137  
    // if APEX is disabled, do nothing.
1138  
    if (apex_options::disable() == true) { return ; }
1139  
    // if APEX is suspended, do nothing.
1140  
    if (apex_options::suspend() == true) { return ; }
1141  
	// if APEX hasn't been initialized, do nothing.
1142  
    if (!_initialized) { return ; }
1143  
    // get the Apex static instance
1144  
    apex* instance = apex::instance();
1145  
    // protect against calls after finalization
1146  
    if (!instance || _exited) { return ; }
1147  
1148  
    if (_notify_listeners) {
1149  
		// eventually, we want to use the thread id, but for now, just use 0.
1150  
        //message_event_data data(tag, size, instance->get_node_id(), thread_instance::get_id(), target);
1151  
        message_event_data data(tag, size, instance->get_node_id(), 0, target);
1152  
        if (_notify_listeners) {
1153  
            //read_lock_type l(instance->listener_mutex);
1154  
            for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
1155  
                instance->listeners[i]->on_send(data);
1156  
            }
1157  
        }
1158  
    }
1159  
}
1160  
1161  
void recv (uint64_t tag, uint64_t size, uint64_t source_rank, uint64_t source_thread) {
1162  
    // if APEX is disabled, do nothing.
1163  
    if (apex_options::disable() == true) { return ; }
1164  
    // if APEX is suspended, do nothing.
1165  
    if (apex_options::suspend() == true) { return ; }
1166  
	// if APEX hasn't been initialized, do nothing.
1167  
    if (!_initialized) { return ; }
1168  
    // get the Apex static instance
1169  
    apex* instance = apex::instance();
1170  
    // protect against calls after finalization
1171  
    if (!instance || _exited) { return ; }
1172  
1173  
    if (_notify_listeners) {
1174  
		// eventually, we want to use the thread id, but for now, just use 0.
1175  
        //message_event_data data(tag, size, source_rank, source_thread, instance->get_node_id());
1176  
        message_event_data data(tag, size, source_rank, 0, instance->get_node_id());
1177  
        if (_notify_listeners) {
1178  
            //read_lock_type l(instance->listener_mutex);
1179  
            for (unsigned int i = 0 ; i < instance->listeners.size() ; i++) {
1180  
                instance->listeners[i]->on_recv(data);
1181  
            }
1182  
        }
1183  
    }
1184  
}
1185  
1186  
} // apex namespace
1187  
1188  
using namespace apex;
1189  
1190  
extern "C" {
1191  
1192  
    int apex_init(const char * thread_name, unsigned long int comm_rank, unsigned long int comm_size)
1193  
    {
1194  
        return init(thread_name, comm_rank, comm_size);
1195  
    }
1196  
1197  
    int apex_init_(unsigned long int comm_rank, unsigned long int comm_size) {
1198  
        return init("FORTRAN thread", comm_rank, comm_size);
1199  
    }
1200  
1201  
    int apex_init__(unsigned long int comm_rank, unsigned long int comm_size) {
1202  
        return init("FORTRAN thread", comm_rank, comm_size);
1203  
    }
1204  
1205  
    void apex_cleanup()
1206  
    {
1207  
        cleanup();
1208  
    }
1209  
1210  
    void apex_finalize()
1211  
    {
1212  
        finalize();
1213  
    }
1214  
1215  
    void apex_finalize_() { finalize(); }
1216  
1217  
    void apex_finalize__() { finalize(); }
1218  
1219  
    const char * apex_version()
1220  
    {
1221  
        return version().c_str();
1222  
    }
1223  
1224  
    apex_profiler_handle apex_start(apex_profiler_type type, void * identifier)
1225  
    {
1226  
      assert(identifier);
1227  
      if (type == APEX_FUNCTION_ADDRESS) {
1228  
          return reinterpret_cast<apex_profiler_handle>(start((apex_function_address)identifier));
1229  
      } else if (type == APEX_NAME_STRING) {
1230  
          string tmp((const char *)identifier);
1231  
          return reinterpret_cast<apex_profiler_handle>(start(tmp));
1232  
      }
1233  
      return APEX_NULL_PROFILER_HANDLE;
1234  
    }
1235  
1236  
    void apex_start_(apex_profiler_type type, void * identifier, apex_profiler_handle profiler) {
1237  
      apex_profiler_handle p = apex_start(type, identifier);
1238  
      if (profiler != nullptr) profiler = p;
1239  
    }
1240  
1241  
    apex_profiler_handle apex_resume(apex_profiler_type type, void * identifier)
1242  
    {
1243  
      assert(identifier);
1244  
      if (type == APEX_FUNCTION_ADDRESS) {
1245  
          return reinterpret_cast<apex_profiler_handle>(resume((apex_function_address)identifier));
1246  
      } else if (type == APEX_NAME_STRING) {
1247  
          string tmp((const char *)identifier);
1248  
          return reinterpret_cast<apex_profiler_handle>(resume(tmp));
1249  
      }
1250  
      return APEX_NULL_PROFILER_HANDLE;
1251  
    }
1252  
1253  
    void apex_reset(apex_profiler_type type, void * identifier) {
1254  
        if (type == APEX_FUNCTION_ADDRESS) {
1255  
            reset((apex_function_address)(identifier));
1256  
        } else {
1257  
            string tmp((const char *)identifier);
1258  
            reset(tmp);
1259  
        }
1260  
    }
1261  
1262  
    void apex_set_state(apex_thread_state state) {
1263  
        set_state(state);
1264  
    }
1265  
1266  
    void apex_stop(apex_profiler_handle the_profiler)
1267  
    {
1268  
        stop(reinterpret_cast<profiler*>(the_profiler));
1269  
    }
1270  
1271  
    void apex_stop_(apex_profiler_handle the_profiler)
1272  
    {
1273  
        stop(reinterpret_cast<profiler*>(the_profiler));
1274  
    }
1275  
1276  
    void apex_yield(apex_profiler_handle the_profiler)
1277  
    {
1278  
        yield(reinterpret_cast<profiler*>(the_profiler));
1279  
    }
1280  
1281  
    void apex_sample_value(const char * name, double value)
1282  
    {
1283  
        string tmp(name);
1284  
        sample_value(tmp, value);
1285  
    }
1286  
1287  
    void apex_new_task(apex_profiler_type type, void * identifier,
1288  
                       unsigned long long task_id) {
1289  
        if (type == APEX_FUNCTION_ADDRESS) {
1290  
            new_task((apex_function_address)(identifier), task_id);
1291  
        } else {
1292  
            string tmp((const char *)identifier);
1293  
            new_task(tmp, task_id);
1294  
        }
1295  
    }
1296  
1297  
    apex_event_type apex_register_custom_event(const char * name)
1298  
    {
1299  
        string tmp(name);
1300  
        return register_custom_event(tmp);
1301  
    }
1302  
1303  
    void apex_custom_event(apex_event_type event_type, void * custom_data)
1304  
    {
1305  
        custom_event(event_type, custom_data);
1306  
    }
1307  
1308  
    void apex_register_thread(const char * name)
1309  
    {
1310  
        if (name) {
1311  
            string tmp(name);
1312  
            register_thread(tmp);
1313  
        } else {
1314  
            string tmp("APEX WORKER THREAD");
1315  
            register_thread(tmp);
1316  
        }
1317  
    }
1318  
1319  
    void apex_exit_thread(void)
1320  
    {
1321  
        exit_thread();
1322  
    }
1323  
1324  
    void apex_track_power(void)
1325  
    {
1326  
        track_power();
1327  
    }
1328  
1329  
    void apex_track_power_here(void)
1330  
    {
1331  
        track_power_here();
1332  
    }
1333  
1334  
    void apex_enable_tracking_power(void)
1335  
    {
1336  
        enable_tracking_power();
1337  
    }
1338  
1339  
    void apex_disable_tracking_power(void)
1340  
    {
1341  
        disable_tracking_power();
1342  
    }
1343  
1344  
    void apex_set_interrupt_interval(int seconds)
1345  
    {
1346  
        set_interrupt_interval(seconds);
1347  
    }
1348  
1349  
    apex_policy_handle* apex_register_policy(const apex_event_type when, int (f)(apex_context const)) {
1350  
        return register_policy(when, f);
1351  
    }
1352  
1353  
    apex_policy_handle* apex_register_periodic_policy(unsigned long period, int (f)(apex_context const)) {
1354  
        return register_periodic_policy(period, f);
1355  
    }
1356  
1357  
    void apex_deregister_policy(apex_policy_handle * handle) {
1358  
        return deregister_policy(handle);
1359  
    }
1360  
1361  
    apex_profile* apex_get_profile(apex_profiler_type type, void * identifier) {
1362  
        assert(identifier);
1363  
        if (type == APEX_FUNCTION_ADDRESS) {
1364  
            return get_profile((apex_function_address)(identifier));
1365  
        } else {
1366  
            string tmp((const char *)identifier);
1367  
            return get_profile(tmp);
1368  
        }
1369  
        return nullptr;
1370  
    }
1371  
1372  
    double apex_current_power_high() {
1373  
        return current_power_high();
1374  
    }
1375  
1376  
    void apex_print_options() {
1377  
        apex_options::print_options();
1378  
        return;
1379  
    }
1380  
1381  
    void apex_send (uint64_t tag, uint64_t size, uint64_t target) {
1382  
        return send(tag, size, target);
1383  
    }
1384  
1385  
    void apex_recv (uint64_t tag, uint64_t size, uint64_t source_rank, uint64_t source_thread) {
1386  
        return recv(tag, size, source_rank, source_thread);
1387  
    }
1388  
1389  
} // extern "C"
1390  
1391  
1392  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.