/* * Copyright (c) 2015, Charlie Curtsinger and Emery Berger, * University of Massachusetts Amherst * This file is part of the Coz project. See LICENSE.md file at the top-level * directory of this distribution and at http://github.com/plasma-umass/coz. */ #if !defined(COZ_H) #define COZ_H #ifndef __USE_GNU # define __USE_GNU #endif #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include /* for memcpy hack below */ #if defined(__cplusplus) extern "C" { #endif #define COZ_COUNTER_TYPE_THROUGHPUT 1 #define COZ_COUNTER_TYPE_BEGIN 2 #define COZ_COUNTER_TYPE_END 3 // Declare dlsym as a weak reference so libdl isn't required void* dlsym(void* handle, const char* symbol) __attribute__((weak)); // Counter info struct, containing both a counter and backoff size typedef struct { size_t count; // The actual count size_t backoff; // Used to batch updates to the shared counter. Currently unused. } coz_counter_t; // The type of the _coz_get_counter function typedef coz_counter_t* (*coz_get_counter_t)(int, const char*); // Locate and invoke _coz_get_counter static coz_counter_t* _call_coz_get_counter(int type, const char* name) { static unsigned char _initialized = 0; static coz_get_counter_t fn; // The pointer to _coz_get_counter if(!_initialized) { if(dlsym) { // Locate the _coz_get_counter method void* p = dlsym(RTLD_DEFAULT, "_coz_get_counter"); // Use memcpy to avoid pedantic GCC complaint about storing function pointer in void* memcpy(&fn, &p, sizeof(p)); } _initialized = 1; } // Call the function, or return null if profiler is not found if(fn) return fn(type, name); else return 0; } // Macro to initialize and increment a counter #define COZ_INCREMENT_COUNTER(type, name) \ if(1) { \ static unsigned char _initialized = 0; \ static coz_counter_t* _counter = 0; \ \ if(!_initialized) { \ _counter = _call_coz_get_counter(type, name); \ _initialized = 1; \ } \ if(_counter) { \ __atomic_add_fetch(&_counter->count, 1, __ATOMIC_RELAXED); \ } \ } #define STR2(x) #x #define STR(x) STR2(x) #define COZ_PROGRESS_NAMED(name) COZ_INCREMENT_COUNTER(COZ_COUNTER_TYPE_THROUGHPUT, name) #define COZ_PROGRESS COZ_INCREMENT_COUNTER(COZ_COUNTER_TYPE_THROUGHPUT, __FILE__ ":" STR(__LINE__)) #define COZ_BEGIN(name) COZ_INCREMENT_COUNTER(COZ_COUNTER_TYPE_BEGIN, name) #define COZ_END(name) COZ_INCREMENT_COUNTER(COZ_COUNTER_TYPE_END, name) #if defined(__cplusplus) } #endif #endif