coz/libcoz/progress_point.h

185 lines
4.8 KiB
C++

/*
* 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(CAUSAL_RUNTIME_PROGRESS_POINT_H)
#define CAUSAL_RUNTIME_PROGRESS_POINT_H
#include <memory>
#include <string>
#include "coz.h"
#include "inspect.h"
#include "perf.h"
#include "util.h"
#include "ccutil/log.h"
/// Enum wrapper around defines for progress point types
enum class progress_point_type {
throughput = COZ_COUNTER_TYPE_THROUGHPUT,
begin = COZ_COUNTER_TYPE_BEGIN,
end = COZ_COUNTER_TYPE_END
};
/**
* A progress point to measure throughput
*/
class throughput_point {
public:
class saved;
/// Create a throughput progress point with a given name
throughput_point(const std::string& name) : _name(name) {}
/// Save the state of this progress point
saved* save() const {
return new saved(this);
}
/// Add one to the number of visits to this progress point
void visit(size_t visits=1) {
__atomic_add_fetch(&_counter.count, visits, __ATOMIC_RELAXED);
}
/// Get the number of visits to this progress point
size_t get_count() const {
return __atomic_load_n(&_counter.count, __ATOMIC_RELAXED);
}
/// Get a pointer to the counter struct (used by source progress points)
coz_counter_t* get_counter_struct() {
return &_counter;
}
/// Get the name of this progress point
const std::string& get_name() const {
return _name;
}
class saved {
public:
saved() {}
/// Save the state of a throughput point
saved(const throughput_point* origin) : _origin(origin), _start_count(origin->get_count()) {}
/// Log the change in this progress point since it was saved
void log(std::ostream& os) const {
os << "throughput-point\t"
<< "name=" << _origin->get_name() << "\t"
<< "delta=" << get_delta() << "\n";
}
size_t get_delta() const {
return _origin->get_count() - _start_count;
}
protected:
const throughput_point* _origin;
size_t _start_count;
};
private:
const std::string _name;
coz_counter_t _counter;
};
/**
* A progress point to measure latency with two counters
*/
class latency_point {
public:
class saved;
/// Create a latency progress point with a given name
latency_point(const std::string& name) : _name(name) {}
/// Save the state of this progress point
saved* save() const {
return new saved(this);
}
/// Add one visit to the begin progress point
void visit_begin(size_t visits=1) {
__atomic_add_fetch(&_begin_counter.count, visits, __ATOMIC_RELAXED);
}
/// Add one visit to the end progress point
void visit_end(size_t visits=1) {
__atomic_add_fetch(&_end_counter.count, visits, __ATOMIC_RELAXED);
}
/// Get the number of visits to the begin progress point
size_t get_begin_count() const {
return __atomic_load_n(&_begin_counter.count, __ATOMIC_RELAXED);
}
/// Get the number of visits to the end progress point
size_t get_end_count() const {
return __atomic_load_n(&_end_counter.count, __ATOMIC_RELAXED);
}
/// Get a pointer to the begin point's counter struct (used by source progress points)
coz_counter_t* get_begin_counter_struct() {
return &_begin_counter;
}
/// Get a pointer to the end point's counter struct (used by source progress points)
coz_counter_t* get_end_counter_struct() {
return &_end_counter;
}
/// Get the name of this progress point
const std::string& get_name() const {
return _name;
}
class saved {
public:
saved() {}
/// Save the state of a throughput point
saved(const latency_point* origin) : _origin(origin),
_begin_start_count(origin->get_begin_count()),
_end_start_count(origin->get_end_count()) {}
/// Log the change in this progress point since it was saved
virtual void log(std::ostream& os) const {
os << "latency-point\t"
<< "name=" << _origin->get_name() << "\t"
<< "arrivals=" << get_begin_delta() << "\t"
<< "departures=" << get_end_delta() << "\t"
<< "difference=" << get_difference() << "\n";
}
virtual size_t get_begin_delta() const {
return _origin->get_begin_count() - _begin_start_count;
}
virtual size_t get_end_delta() const {
return _origin->get_end_count() - _end_start_count;
}
virtual size_t get_difference() const {
return _origin->get_begin_count() - _origin->get_end_count();
}
protected:
const latency_point* _origin;
size_t _begin_start_count;
size_t _end_start_count;
};
private:
const std::string _name;
coz_counter_t _begin_counter;
coz_counter_t _end_counter;
};
#endif