123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- /* 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 <http://www.gnu.org/licenses/>. */
- /*
- * 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 <atomic.h>
- struct shim_profile {
- const char* name;
- enum { CATEGORY, OCCURENCE, INTERVAL } type;
- bool disabled;
- struct shim_profile* root;
- union {
- struct {
- struct atomic_int count;
- } occurence;
- struct {
- struct atomic_int count;
- struct atomic_int 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_CATEGORY(prof, rprof) _DEFINE_PROFILE_CATEGORY(prof, rprof)
- #define _DEFINE_PROFILE_CATEGORY(prof, rprof) \
- extern struct shim_profile profile_##rprof; \
- struct shim_profile profile_##prof __attribute__((section(".profile"))) = { \
- .name = #prof, \
- .root = &profile_##rprof, \
- .type = CATEGORY, \
- };
- #define DEFINE_PROFILE_CATEGORY_DISABLED(prof, rprof) _DEFINE_PROFILE_CATEGORY(prof, rprof)
- #define _DEFINE_PROFILE_CATEGORY_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 = CATEGORY, \
- };
- #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 : atomic_inc_return(&profile_##prof.val.occurence.count); \
- })
- #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 : atomic_add_return(num, &profile_##prof.val.occurence.count); \
- })
- #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_CATEGORY(prof, rprof)
- #define DEFINE_PROFILE_OCCURENCE(prof, rprof)
- #define DEFINE_PROFILE_INTERVAL(prof, rprof)
- #define INC_PROFILE_OCCURENCE(prof) do {} while (0)
- #define ADD_PROFILE_OCCURENCE(prof, val) do {} while (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)
- #define ASSIGN_PROFILE_INTERVAL(prof) do {} while (0)
- #define SAVE_PROFILE_INTERVAL_ASSIGNED() do {} while (0)
- #define SAVE_PROFILE_INTERVAL(prof) do {} while (0)
- #define SAVE_PROFILE_INTERVAL_SINCE(prof, time) do {} while (0)
- #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) do {} while (0)
- #endif
- #endif /* _SHIM_PROFILE_H_ */
|