shim_profile.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 \
  53. (((void *) &__profile_end - (void *) &__profile) / sizeof(struct shim_profile))
  54. #define PROFILES (&__profile)
  55. #define DEFINE_PROFILE_CATEGORY(prof, rprof) \
  56. _DEFINE_PROFILE_CATEGORY(prof, rprof)
  57. #define _DEFINE_PROFILE_CATEGORY(prof, rprof) \
  58. extern struct shim_profile profile_##rprof; \
  59. struct shim_profile profile_##prof \
  60. __attribute__((section(".profile"))) = { \
  61. .name = #prof, \
  62. .root = &profile_##rprof, \
  63. .type = CATEGORY, \
  64. };
  65. #define DEFINE_PROFILE_CATEGORY_DISABLED(prof, rprof) \
  66. _DEFINE_PROFILE_CATEGORY(prof, rprof)
  67. #define _DEFINE_PROFILE_CATEGORY_DISABLED(prof, rprof) \
  68. extern struct shim_profile profile_##rprof; \
  69. struct shim_profile profile_##prof \
  70. __attribute__((section(".profile"))) = { \
  71. .name = #prof, \
  72. .disabled = true, \
  73. .root = &profile_##rprof, \
  74. .type = CATEGORY, \
  75. };
  76. #define DEFINE_PROFILE_OCCURENCE(prof, rprof) \
  77. _DEFINE_PROFILE_OCCURENCE(prof, rprof)
  78. #define _DEFINE_PROFILE_OCCURENCE(prof, rprof) \
  79. extern struct shim_profile profile_##rprof; \
  80. struct shim_profile profile_##prof \
  81. __attribute__((section(".profile"))) = { \
  82. .name = #prof, \
  83. .root = &profile_##rprof, \
  84. .type = OCCURENCE, \
  85. };
  86. #define DEFINE_PROFILE_INTERVAL(prof, rprof) \
  87. _DEFINE_PROFILE_INTERVAL(prof, rprof)
  88. #define _DEFINE_PROFILE_INTERVAL(prof, rprof) \
  89. extern struct shim_profile profile_##rprof; \
  90. struct shim_profile profile_##prof \
  91. __attribute__((section(".profile"))) = { \
  92. .name = #prof, \
  93. .root = &profile_##rprof, \
  94. .type = INTERVAL, \
  95. };
  96. #define profile_ profile_root
  97. #define INC_PROFILE_OCCURENCE(prof) _INC_PROFILE_OCCURENCE(prof)
  98. #define _INC_PROFILE_OCCURENCE(prof) \
  99. ({ \
  100. extern struct shim_profile profile_##prof; \
  101. profile_##prof.disabled ? 0 : \
  102. atomic_inc_return(&profile_##prof.val.occurence.count); \
  103. })
  104. #define ADD_PROFILE_OCCURENCE(prof, num) _ADD_PROFILE_OCCURENCE(prof, num)
  105. #define _ADD_PROFILE_OCCURENCE(prof, num) \
  106. ({ \
  107. extern struct shim_profile profile_##prof; \
  108. profile_##prof.disabled ? 0 : \
  109. atomic_add_return(num, &profile_##prof.val.occurence.count); \
  110. })
  111. #define BEGIN_PROFILE_INTERVAL() \
  112. unsigned long _interval; \
  113. do { _interval = DkSystemTimeQuery(); } while (0)
  114. #define BEGIN_PROFILE_INTERVAL_SET(val) \
  115. unsigned long _interval; \
  116. do { _interval = (val); } while (0)
  117. #define SET_PROFILE_INTERVAL(val) \
  118. do { _interval = (val); } while (0)
  119. #define GET_PROFILE_INTERVAL() DkSystemTimeQuery()
  120. #define UPDATE_PROFILE_INTERVAL() \
  121. ({ \
  122. unsigned long _c = DkSystemTimeQuery(); \
  123. unsigned long _t = _c - _interval; \
  124. _interval = _c; \
  125. _t; \
  126. })
  127. #define ASSIGN_PROFILE_INTERVAL(prof) _ASSIGN_PROFILE_INTERVAL(prof)
  128. #define _ASSIGN_PROFILE_INTERVAL(prof) \
  129. extern struct shim_profile profile_##prof; \
  130. struct shim_profile *_profile = &profile_##prof;
  131. #define SAVE_PROFILE_INTERVAL_ASSIGNED() \
  132. ({ \
  133. _profile->disabled ? 0 : ({ \
  134. unsigned long _t = UPDATE_PROFILE_INTERVAL(); \
  135. atomic_inc(&_profile->val.interval.count); \
  136. atomic_add(_t, &_profile->val.interval.time); \
  137. _t; }); \
  138. })
  139. #define SAVE_PROFILE_INTERVAL(prof) _SAVE_PROFILE_INTERVAL(prof)
  140. #define _SAVE_PROFILE_INTERVAL(prof) \
  141. ({ \
  142. extern struct shim_profile profile_##prof; \
  143. profile_##prof.disabled ? 0 : ({ \
  144. unsigned long _t = UPDATE_PROFILE_INTERVAL(); \
  145. atomic_inc(&profile_##prof.val.interval.count); \
  146. atomic_add(_t, &profile_##prof.val.interval.time); \
  147. _t; }); \
  148. })
  149. #define SAVE_PROFILE_INTERVAL_SINCE(prof, since) \
  150. _SAVE_PROFILE_INTERVAL_SINCE(prof, since)
  151. #define _SAVE_PROFILE_INTERVAL_SINCE(prof, since) \
  152. ({ \
  153. extern struct shim_profile profile_##prof; \
  154. profile_##prof.disabled ? 0 : ({ \
  155. unsigned long _c = DkSystemTimeQuery(); \
  156. unsigned long _t = _c - (since); \
  157. atomic_inc(&profile_##prof.val.interval.count); \
  158. atomic_add(_t, &profile_##prof.val.interval.time); \
  159. _t; }); \
  160. })
  161. #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) \
  162. _SAVE_PROFILE_INTERVAL_SET(prof, begin, end)
  163. #define _SAVE_PROFILE_INTERVAL_SET(prof, begin, end) \
  164. ({ \
  165. extern struct shim_profile profile_##prof; \
  166. profile_##prof.disabled ? 0 : ({ \
  167. unsigned long _t = (end) - (begin); \
  168. atomic_inc(&profile_##prof.val.interval.count); \
  169. atomic_add(_t, &profile_##prof.val.interval.time); \
  170. _t; }); \
  171. })
  172. #else
  173. #define DEFINE_PROFILE_CATEGORY(prof, rprof)
  174. #define DEFINE_PROFILE_OCCURENCE(prof, rprof)
  175. #define DEFINE_PROFILE_INTERVAL(prof, rprof)
  176. #define INC_PROFILE_OCCURENCE(prof) ({ do {} while (0); 0; })
  177. #define ADD_PROFILE_OCCURENCE(prof, val) ({ do {} while (0); 0; })
  178. #define BEGIN_PROFILE_INTERVAL() do {} while (0)
  179. #define BEGIN_PROFILE_INTERVAL_SET(val) do {} while (0)
  180. #define SET_PROFILE_INTERVAL(val) do {} while (0)
  181. #define GET_PROFILE_INTERVAL() (0)
  182. #define UPDATE_PROFILE_INTERVAL() ({ do {} while (0); 0; })
  183. #define ASSIGN_PROFILE_INTERVAL(prof) do {} while (0)
  184. #define SAVE_PROFILE_INTERVAL_ASSIGNED() ({ do {} while (0); 0; })
  185. #define SAVE_PROFILE_INTERVAL(prof) ({ do {} while (0); 0; })
  186. #define SAVE_PROFILE_INTERVAL_SINCE(prof, time) ({ do {} while (0); 0; })
  187. #define SAVE_PROFILE_INTERVAL_SET(prof, begin, end) ({ do {} while (0); 0; })
  188. #endif
  189. #endif /* _SHIM_PROFILE_H_ */