194 #ifndef _RT_TIMING_HPP
195 #define _RT_TIMING_HPP
199 #if defined(ENABLE_RT_TIMING)
216 #define _RT_LOG(expr) do { cacao::dbg() <<expr;} while (0)
218 #define _RT_LOG(expr)
223 #include <mach/mach.h>
224 #include <mach/mach_time.h>
230 inline timespec operator-(
const timespec &a, timespec b) {
233 if (a.tv_nsec < b.tv_nsec) {
234 int xsec = (b.tv_nsec - a.tv_nsec) / 1000000000L + 1;
235 b.tv_nsec -= 1000000000L * xsec;
238 if (a.tv_nsec - b.tv_nsec > 1000000000L) {
239 int xsec = (a.tv_nsec - b.tv_nsec) / 1000000000L;
240 b.tv_nsec += 1000000000L * xsec;
245 result.tv_sec = a.tv_sec - b.tv_sec;
246 result.tv_nsec = a.tv_nsec - b.tv_nsec;
251 inline timespec operator+(
const timespec a,
const timespec &b) {
253 result.tv_sec = a.tv_sec + b.tv_sec;
254 result.tv_nsec = a.tv_nsec + b.tv_nsec;
255 if (result.tv_nsec > 1000000000L) {
256 result.tv_nsec -= 1000000000L;
264 inline void operator+=(timespec &result,
const timespec &b) {
265 result.tv_sec += b.tv_sec;
266 result.tv_nsec += b.tv_nsec;
267 if (result.tv_nsec > 1000000000L) {
268 result.tv_nsec -= 1000000000L;
273 inline timespec operator/(
const timespec &a,
const int b) {
284 result.tv_sec = a.tv_sec / b;
285 result.tv_nsec = r * 1000000000L / b;
286 result.tv_nsec += a.tv_nsec / b;
294 inline long int operator/(
const timespec &a,
const timespec &b) {
299 return a.tv_sec / b.tv_sec;
302 if (b.tv_nsec == 0) {
305 return a.tv_nsec / b.tv_nsec;
310 inline bool operator==(
const timespec &a,
const timespec &b) {
311 return (a.tv_sec == b.tv_sec) && (a.tv_nsec == b.tv_nsec);
317 inline OStream&
operator<<(OStream &ostr, timespec ts) {
319 if (ts.tv_sec >= 10) {
324 ts.tv_nsec += ts.tv_sec * 1000000000L;
325 if (ts.tv_nsec >= 100000000) {
327 ostr << ts.tv_nsec/1000000;
331 ostr << ts.tv_nsec/1000;
335 ostr <<
setw(5) << unit;
340 inline void rt_timing_gettime_inline(timespec &ts) {
341 if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,&ts) != 0) {
342 fprintf(stderr,
"could not get time by clock_gettime: %s\n",strerror(errno));
348 inline long rt_timing_diff_usec_inline(
const timespec &a,
const timespec &b)
353 diff = (b.tv_nsec - a.tv_nsec) / 1000;
355 while (atime < b.tv_sec) {
381 const char* description;
383 RTEntry() :
name(NULL), description(NULL) {}
385 typedef std::deque<const RTEntry*> RtStack;
387 void print_csv_entry(OStream &O,RtStack &s,timespec ts)
const {
388 for(RtStack::const_iterator
i = s.begin(),
e = s.end() ;
i !=
e; ++
i) {
389 O << (*i)->name <<
'.';
391 O <<
name <<
';' << description <<
';';
401 static timespec invalid_ts;
405 RTEntry(
const char*
name,
const char* description) : name(name), description(description) {
406 _RT_LOG(
"RTEntry() name: " << name <<
nl);
412 _RT_LOG(
"~RTEntry() name: " <<
name <<
nl);
420 virtual void print(OStream &O,timespec ref)
const = 0;
421 void print_csv(OStream &O)
const {
423 print_csv_intern(O,s);
425 static void print_csv_header(OStream &O) {
426 O <<
"name;description;value" <<
nl;
428 virtual void print_csv_intern(OStream &O,RtStack &s)
const = 0;
433 virtual timespec time()
const = 0;
441 class RTGroup :
public RTEntry {
443 typedef std::vector<RTEntry*> RTEntryList;
447 RTGroup(
const char*
name,
const char* description) : RTEntry(name, description) {
448 _RT_LOG(
"RTGroup() name: " << name <<
nl);
454 static RTGroup&
root() {
455 static RTGroup rg(
"vm",
"vm");
465 RTGroup(
const char*
name,
const char* description, RTGroup &group) : RTEntry(name, description) {
470 _RT_LOG(
"~RTGroup() name: " << name <<
nl);
476 void add(RTEntry *re) {
477 members.push_back(re);
480 virtual timespec time()
const {
481 timespec time = {0,0};
482 for(RTEntryList::const_iterator
i = members.begin(),
e = members.end();
i !=
e; ++
i) {
489 virtual void print(OStream &O,timespec ref = invalid_ts)
const {
490 timespec duration = time();
491 if (ref == invalid_ts)
495 for(RTEntryList::const_iterator
i = members.begin(),
e = members.end();
i !=
e; ++
i) {
497 re->print(O,duration);
500 int percent = duration / (ref / 100);
502 <<
setw(10) << duration <<
" "
503 <<
setw(4) << percent <<
"% "
504 <<
setw(20) << name <<
": total time"
508 virtual void print_csv_intern(OStream &O,RtStack &s)
const {
510 for(RTEntryList::const_iterator
i = members.begin(),
e = members.end();
i !=
e; ++
i) {
512 re->print_csv_intern(O,s);
515 print_csv_entry(O,s,time());
524 class RTTimer :
public RTEntry {
534 RTTimer() : RTEntry() {}
541 RTTimer(
const char* name,
const char* description, RTGroup &
parent) : RTEntry(name, description), duration(0) {
543 _RT_LOG(
"RTTimer() name: " << name <<
nl);
551 _RT_LOG(
"~RTTimer() name: " << name <<
nl);
558 inline void start() {
560 startstamp = mach_absolute_time();
562 rt_timing_gettime_inline(startstamp);
573 static mach_timebase_info_data_t sTimebaseInfo;
574 uint64_t elapsed, nano;
576 if ( sTimebaseInfo.denom == 0 ) {
577 (
void) mach_timebase_info(&sTimebaseInfo);
580 elapsed = mach_absolute_time() - startstamp;
581 nano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;
582 duration += (nano / 1000);
585 rt_timing_gettime_inline(stopstamp);
586 duration += rt_timing_diff_usec_inline(startstamp,stopstamp);
590 virtual timespec time()
const {
592 int sec = duration/1000000;
594 ts.tv_nsec = (duration - sec * 1000000) * 1000;
598 virtual void print(OStream &O,timespec ref = invalid_ts)
const {
599 timespec ts = time();
602 if (ref == invalid_ts) {
605 percent = ts / (ref / 100);
608 O <<
setw(10) << ts.tv_nsec/1000 <<
" usec "
609 <<
setw(4) << percent <<
"% "
610 <<
setw(20) << name <<
": " << description <<
nl;
612 virtual void print_csv_intern(OStream &O,RtStack &s)
const {
613 print_csv_entry(O,s,time());
623 #define RT_REGISTER_TIMER(var,name,description) \
624 static inline cacao::RTTimer& var() { \
625 static cacao::RTTimer v(name,description,cacao::RTGroup::root()); \
629 #define RT_REGISTER_GROUP_TIMER(var,name,description,group) \
630 static inline cacao::RTTimer& var() { \
631 static cacao::RTTimer v(name, description, group()); \
635 #define RT_REGISTER_GROUP(var,name,description) \
636 inline cacao::RTGroup& var() { \
637 static cacao::RTGroup v(name,description,cacao::RTGroup::root()); \
641 #define RT_REGISTER_SUBGROUP(var,name,description,group) \
642 inline cacao::RTGroup& var() { \
643 static cacao::RTGroup v(name, description, group()); \
648 #define RT_REGISTER_TIMER_EXTERN(var,name,description) \
649 inline cacao::RTTimer& var() { \
650 static cacao::RTTimer v(name,description,cacao::RTGroup::root()); \
654 #define RT_REGISTER_GROUP_TIMER_EXTERN(var,name,description,group) \
655 inline cacao::RTTimer& var() { \
656 static cacao::RTTimer v(name, description, group()); \
660 #define RT_REGISTER_GROUP_EXTERN(var,name,description) \
661 inline cacao::RTGroup& var() { \
662 static cacao::RTGroup v(name,description,cacao::RTGroup::root()); \
666 #define RT_REGISTER_SUBGROUP_EXTERN(var,name,description,group) \
667 inline cacao::RTGroup& var() { \
668 static cacao::RTGroup v(name, description, group()); \
672 #define RT_DECLARE_TIMER(var) inline cacao::RTTimer& var();
673 #define RT_DECLARE_GROUP(var) inline cacao::RTGroup& var();
675 #define RT_TIMER_START(var) var().start()
676 #define RT_TIMER_STOP(var) var().stop()
677 #define RT_TIMER_STOPSTART(var1,var2) do { var1().stop();var2().start(); } while(0)
681 #define RT_REGISTER_TIMER(var,name,description)
682 #define RT_REGISTER_GROUP_TIMER(var,name,description,group)
683 #define RT_REGISTER_GROUP(var,name,description)
684 #define RT_REGISTER_SUBGROUP(var,name,description,group)
686 #define RT_REGISTER_TIMER_EXTERN(var,name,description)
687 #define RT_REGISTER_GROUP_TIMER_EXTERN(var,name,description,group)
688 #define RT_REGISTER_GROUP_EXTERN(var,name,description)
689 #define RT_REGISTER_SUBGROUP_EXTERN(var,name,description,group)
691 #define RT_DECLARE_TIMER(var)
692 #define RT_DECLARE_GROUP(var)
694 #define RT_TIMER_START(var)
695 #define RT_TIMER_STOP(var)
696 #define RT_TIMER_STOPSTART(var1,var2)
static SetWidth setw(size_t w)
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
JNIEnv jclass jobject const char * name
OStream & operator<<(OStream &OS, const std::string &t)
bool operator==(const ordered_list< T, Allocator > &lhs, const ordered_list< T, Allocator > &rhs)
equality
static SetZero setz(size_t w)