/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ /* Copyright (C) 2014 Stony Brook University This file is part of Graphene Library OS. Graphene Library OS is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Graphene Library OS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* * shim_profile.h * * This file includes macros and types for profiling the library OS * performance. */ #ifndef _SHIM_PROFILE_H_ #define _SHIM_PROFILE_H_ #ifdef PROFILE #include struct shim_profile { const char * name; enum { CATAGORY, OCCURENCE, INTERVAL } type; bool disabled; struct shim_profile * root; union { struct { struct shim_atomic count; } occurence; struct { struct shim_atomic count; struct shim_atomic time; } interval; } val; } __attribute__((aligned(64))); struct profile_val { int idx; union { struct { unsigned int count; } occurence; struct { unsigned int count; unsigned long time; } interval; } val; }; extern struct shim_profile __profile; extern struct shim_profile __profile_end; #define N_PROFILE \ (((void *) &__profile_end - (void *) &__profile) / sizeof(struct shim_profile)) #define PROFILES (&__profile) #define DEFINE_PROFILE_CATAGORY(prof, rprof) \ _DEFINE_PROFILE_CATAGORY(prof, rprof) #define _DEFINE_PROFILE_CATAGORY(prof, rprof) \ extern struct shim_profile profile_##rprof; \ struct shim_profile profile_##prof \ __attribute__((section(".profile"))) = { \ .name = #prof, \ .root = &profile_##rprof, \ .type = CATAGORY, \ }; #define DEFINE_PROFILE_CATAGORY_DISABLED(prof, rprof) \ _DEFINE_PROFILE_CATAGORY(prof, rprof) #define _DEFINE_PROFILE_CATAGORY_DISABLED(prof, rprof) \ extern struct shim_profile profile_##rprof; \ struct shim_profile profile_##prof \ __attribute__((section(".profile"))) = { \ .name = #prof, \ .disabled = true, \ .root = &profile_##rprof, \ .type = CATAGORY, \ }; #define DEFINE_PROFILE_OCCURENCE(prof, rprof) \ _DEFINE_PROFILE_OCCURENCE(prof, rprof) #define _DEFINE_PROFILE_OCCURENCE(prof, rprof) \ extern struct shim_profile profile_##rprof; \ struct shim_profile profile_##prof \ __attribute__((section(".profile"))) = { \ .name = #prof, \ .root = &profile_##rprof, \ .type = OCCURENCE, \ }; #define DEFINE_PROFILE_INTERVAL(prof, rprof) \ _DEFINE_PROFILE_INTERVAL(prof, rprof) #define _DEFINE_PROFILE_INTERVAL(prof, rprof) \ extern struct shim_profile profile_##rprof; \ struct shim_profile profile_##prof \ __attribute__((section(".profile"))) = { \ .name = #prof, \ .root = &profile_##rprof, \ .type = INTERVAL, \ }; #define profile_ profile_root #define INC_PROFILE_OCCURENCE(prof) _INC_PROFILE_OCCURENCE(prof) #define _INC_PROFILE_OCCURENCE(prof) \ ({ \ extern struct shim_profile profile_##prof; \ profile_##prof.disabled ? 0 : ({ \ unsigned long _c; \ _c = atomic_read(&profile_##prof.val.occurence.count); \ atomic_inc(&profile_##prof.val.occurence.count); \ _c + 1; }); \ }) #define ADD_PROFILE_OCCURENCE(prof, num) _ADD_PROFILE_OCCURENCE(prof, num) #define _ADD_PROFILE_OCCURENCE(prof, num) \ ({ \ extern struct shim_profile profile_##prof; \ profile_##prof.disabled ? 0 : ({ \ unsigned long _c, _num = (num); \ _c = atomic_read(&profile_##prof.val.occurence.count); \ atomic_add(_num, &profile_##prof.val.occurence.count); \ _c + _num; }); \ }) #define BEGIN_PROFILE_INTERVAL() \ unsigned long _interval; \ do { _interval = DkSystemTimeQuery(); } while (0) #define BEGIN_PROFILE_INTERVAL_SET(val) \ unsigned long _interval; \ do { _interval = val; } while (0) #define SET_PROFILE_INTERVAL(val) \ do { _interval = val; } while (0) #define GET_PROFILE_INTERVAL() DkSystemTimeQuery() #define UPDATE_PROFILE_INTERVAL() \ ({ \ unsigned long _c = DkSystemTimeQuery(); \ unsigned long _t = _c - _interval; \ _interval = _c; \ _t; \ }) #define ASSIGN_PROFILE_INTERVAL(prof) _ASSIGN_PROFILE_INTERVAL(prof) #define _ASSIGN_PROFILE_INTERVAL(prof) \ extern struct shim_profile profile_##prof; \ struct shim_profile *_profile = &profile_##prof; #define SAVE_PROFILE_INTERVAL_ASSIGNED() \ ({ \ _profile->disabled ? 0 : ({ \ unsigned long _t = UPDATE_PROFILE_INTERVAL(); \ atomic_inc(&_profile->val.interval.count); \ atomic_add(_t, &_profile->val.interval.time); \ _t; }); \ }) #define SAVE_PROFILE_INTERVAL(prof) _SAVE_PROFILE_INTERVAL(prof) #define _SAVE_PROFILE_INTERVAL(prof) \ ({ \ extern struct shim_profile profile_##prof; \ profile_##prof.disabled ? 0 : ({ \ unsigned long _t = UPDATE_PROFILE_INTERVAL(); \ atomic_inc(&profile_##prof.val.interval.count); \ atomic_add(_t, &profile_##prof.val.interval.time); \ _t; }); \ }) #define SAVE_PROFILE_INTERVAL_SINCE(prof, since) \ _SAVE_PROFILE_INTERVAL_SINCE(prof, since) #define _SAVE_PROFILE_INTERVAL_SINCE(prof, since) \ ({ \ extern struct shim_profile profile_##prof; \ profile_##prof.disabled ? 0 : ({ \ unsigned long _c = DkSystemTimeQuery(); \ unsigned long _t = _c - (since); \ atomic_inc(&profile_##prof.val.interval.count); \ atomic_add(_t, &profile_##prof.val.interval.time); \ _t; }); \ }) #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) \ _SAVE_PROFILE_INTERVAL_SET(prof, begin, end) #define _SAVE_PROFILE_INTERVAL_SET(prof, begin, end) \ ({ \ extern struct shim_profile profile_##prof; \ profile_##prof.disabled ? 0 : ({ \ unsigned long _t = (end) - (begin); \ atomic_inc(&profile_##prof.val.interval.count); \ atomic_add(_t, &profile_##prof.val.interval.time); \ _t; }); \ }) #else #define DEFINE_PROFILE_CATAGORY(prof, rprof) #define DEFINE_PROFILE_OCCURENCE(prof, rprof) #define DEFINE_PROFILE_INTERVAL(prof, rprof) #define INC_PROFILE_OCCURENCE(prof) ({ do {} while (0); 0; }) #define ADD_PROFILE_OCCURENCE(prof, val) ({ do {} while (0); 0; }) #define BEGIN_PROFILE_INTERVAL() do {} while (0) #define BEGIN_PROFILE_INTERVAL_SET(val) do {} while (0) #define SET_PROFILE_INTERVAL(val) do {} while (0) #define GET_PROFILE_INTERVAL() (0) #define UPDATE_PROFILE_INTERVAL() ({ do {} while (0); 0; }) #define ASSIGN_PROFILE_INTERVAL(prof) do {} while (0) #define SAVE_PROFILE_INTERVAL_ASSIGNED() ({ do {} while (0); 0; }) #define SAVE_PROFILE_INTERVAL(prof) ({ do {} while (0); 0; }) #define SAVE_PROFILE_INTERVAL_SINCE(prof, time) ({ do {} while (0); 0; }) #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) ({ do {} while (0); 0; }) #endif #endif /* _SHIM_PROFILE_H_ */