shim_profile.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * shim_profile.h
  15. *
  16. * This file includes macros and types for profiling the library OS
  17. * performance.
  18. */
  19. #ifndef _SHIM_PROFILE_H_
  20. #define _SHIM_PROFILE_H_
  21. #ifdef PROFILE
  22. #include <atomic.h>
  23. struct shim_profile {
  24. const char* name;
  25. enum { CATEGORY, OCCURENCE, INTERVAL } type;
  26. bool disabled;
  27. struct shim_profile* root;
  28. union {
  29. struct {
  30. struct atomic_int count;
  31. } occurence;
  32. struct {
  33. struct atomic_int count;
  34. struct atomic_int time;
  35. } interval;
  36. } val;
  37. } __attribute__((aligned(64)));
  38. struct profile_val {
  39. int idx;
  40. union {
  41. struct {
  42. unsigned int count;
  43. } occurence;
  44. struct {
  45. unsigned int count;
  46. unsigned long time;
  47. } interval;
  48. } val;
  49. };
  50. extern struct shim_profile __profile;
  51. extern struct shim_profile __profile_end;
  52. #define N_PROFILE (((void*)&__profile_end - (void*)&__profile) / sizeof(struct shim_profile))
  53. #define PROFILES (&__profile)
  54. #define DEFINE_PROFILE_CATEGORY(prof, rprof) _DEFINE_PROFILE_CATEGORY(prof, rprof)
  55. #define _DEFINE_PROFILE_CATEGORY(prof, rprof) \
  56. extern struct shim_profile profile_##rprof; \
  57. struct shim_profile profile_##prof __attribute__((section(".profile"))) = { \
  58. .name = #prof, \
  59. .root = &profile_##rprof, \
  60. .type = CATEGORY, \
  61. };
  62. #define DEFINE_PROFILE_CATEGORY_DISABLED(prof, rprof) _DEFINE_PROFILE_CATEGORY(prof, rprof)
  63. #define _DEFINE_PROFILE_CATEGORY_DISABLED(prof, rprof) \
  64. extern struct shim_profile profile_##rprof; \
  65. struct shim_profile profile_##prof __attribute__((section(".profile"))) = { \
  66. .name = #prof, \
  67. .disabled = true, \
  68. .root = &profile_##rprof, \
  69. .type = CATEGORY, \
  70. };
  71. #define DEFINE_PROFILE_OCCURENCE(prof, rprof) _DEFINE_PROFILE_OCCURENCE(prof, rprof)
  72. #define _DEFINE_PROFILE_OCCURENCE(prof, rprof) \
  73. extern struct shim_profile profile_##rprof; \
  74. struct shim_profile profile_##prof __attribute__((section(".profile"))) = { \
  75. .name = #prof, \
  76. .root = &profile_##rprof, \
  77. .type = OCCURENCE, \
  78. };
  79. #define DEFINE_PROFILE_INTERVAL(prof, rprof) _DEFINE_PROFILE_INTERVAL(prof, rprof)
  80. #define _DEFINE_PROFILE_INTERVAL(prof, rprof) \
  81. extern struct shim_profile profile_##rprof; \
  82. struct shim_profile profile_##prof __attribute__((section(".profile"))) = { \
  83. .name = #prof, \
  84. .root = &profile_##rprof, \
  85. .type = INTERVAL, \
  86. };
  87. #define profile_ profile_root
  88. #define INC_PROFILE_OCCURENCE(prof) _INC_PROFILE_OCCURENCE(prof)
  89. #define _INC_PROFILE_OCCURENCE(prof) \
  90. ({ \
  91. extern struct shim_profile profile_##prof; \
  92. profile_##prof.disabled ? 0 : atomic_inc_return(&profile_##prof.val.occurence.count); \
  93. })
  94. #define ADD_PROFILE_OCCURENCE(prof, num) _ADD_PROFILE_OCCURENCE(prof, num)
  95. #define _ADD_PROFILE_OCCURENCE(prof, num) \
  96. ({ \
  97. extern struct shim_profile profile_##prof; \
  98. profile_##prof.disabled ? 0 : atomic_add_return(num, &profile_##prof.val.occurence.count); \
  99. })
  100. #define BEGIN_PROFILE_INTERVAL() \
  101. unsigned long _interval; \
  102. do { \
  103. _interval = DkSystemTimeQuery(); \
  104. } while (0)
  105. #define BEGIN_PROFILE_INTERVAL_SET(val) \
  106. unsigned long _interval; \
  107. do { \
  108. _interval = (val); \
  109. } while (0)
  110. #define SET_PROFILE_INTERVAL(val) \
  111. do { \
  112. _interval = (val); \
  113. } while (0)
  114. #define GET_PROFILE_INTERVAL() DkSystemTimeQuery()
  115. #define UPDATE_PROFILE_INTERVAL() \
  116. ({ \
  117. unsigned long _c = DkSystemTimeQuery(); \
  118. unsigned long _t = _c - _interval; \
  119. _interval = _c; \
  120. _t; \
  121. })
  122. #define ASSIGN_PROFILE_INTERVAL(prof) _ASSIGN_PROFILE_INTERVAL(prof)
  123. #define _ASSIGN_PROFILE_INTERVAL(prof) \
  124. extern struct shim_profile profile_##prof; \
  125. struct shim_profile* _profile = &profile_##prof;
  126. #define SAVE_PROFILE_INTERVAL_ASSIGNED() \
  127. ({ \
  128. _profile->disabled ? 0 : ({ \
  129. unsigned long _t = UPDATE_PROFILE_INTERVAL(); \
  130. atomic_inc(&_profile->val.interval.count); \
  131. atomic_add(_t, &_profile->val.interval.time); \
  132. _t; \
  133. }); \
  134. })
  135. #define SAVE_PROFILE_INTERVAL(prof) _SAVE_PROFILE_INTERVAL(prof)
  136. #define _SAVE_PROFILE_INTERVAL(prof) \
  137. ({ \
  138. extern struct shim_profile profile_##prof; \
  139. profile_##prof.disabled ? 0 : ({ \
  140. unsigned long _t = UPDATE_PROFILE_INTERVAL(); \
  141. atomic_inc(&profile_##prof.val.interval.count); \
  142. atomic_add(_t, &profile_##prof.val.interval.time); \
  143. _t; \
  144. }); \
  145. })
  146. #define SAVE_PROFILE_INTERVAL_SINCE(prof, since) _SAVE_PROFILE_INTERVAL_SINCE(prof, since)
  147. #define _SAVE_PROFILE_INTERVAL_SINCE(prof, since) \
  148. ({ \
  149. extern struct shim_profile profile_##prof; \
  150. profile_##prof.disabled ? 0 : ({ \
  151. unsigned long _c = DkSystemTimeQuery(); \
  152. unsigned long _t = _c - (since); \
  153. atomic_inc(&profile_##prof.val.interval.count); \
  154. atomic_add(_t, &profile_##prof.val.interval.time); \
  155. _t; \
  156. }); \
  157. })
  158. #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) _SAVE_PROFILE_INTERVAL_SET(prof, begin, end)
  159. #define _SAVE_PROFILE_INTERVAL_SET(prof, begin, end) \
  160. ({ \
  161. extern struct shim_profile profile_##prof; \
  162. profile_##prof.disabled ? 0 : ({ \
  163. unsigned long _t = (end) - (begin); \
  164. atomic_inc(&profile_##prof.val.interval.count); \
  165. atomic_add(_t, &profile_##prof.val.interval.time); \
  166. _t; \
  167. }); \
  168. })
  169. #else
  170. #define DEFINE_PROFILE_CATEGORY(prof, rprof)
  171. #define DEFINE_PROFILE_OCCURENCE(prof, rprof)
  172. #define DEFINE_PROFILE_INTERVAL(prof, rprof)
  173. #define INC_PROFILE_OCCURENCE(prof) do {} while (0)
  174. #define ADD_PROFILE_OCCURENCE(prof, val) do {} while (0)
  175. #define BEGIN_PROFILE_INTERVAL() do {} while (0)
  176. #define BEGIN_PROFILE_INTERVAL_SET(val) do {} while (0)
  177. #define SET_PROFILE_INTERVAL(val) do {} while (0)
  178. #define GET_PROFILE_INTERVAL() 0
  179. #define UPDATE_PROFILE_INTERVAL() do {} while (0)
  180. #define ASSIGN_PROFILE_INTERVAL(prof) do {} while (0)
  181. #define SAVE_PROFILE_INTERVAL_ASSIGNED() do {} while (0)
  182. #define SAVE_PROFILE_INTERVAL(prof) do {} while (0)
  183. #define SAVE_PROFILE_INTERVAL_SINCE(prof, time) do {} while (0)
  184. #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) do {} while (0)
  185. #endif
  186. #endif /* _SHIM_PROFILE_H_ */