shim_profile.h 9.5 KB

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