all commits for a clean git history
This commit is contained in:
93
Programs/coz.h
Normal file
93
Programs/coz.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 <dlfcn.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h> /* 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
|
||||
Reference in New Issue
Block a user