y_profiling.inc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #if defined _INC_y_profiling
  2. #endinput
  3. #endif
  4. #define _INC_y_profiling
  5. /**
  6. * <library name="y_profiling">
  7. * <section>
  8. * Description
  9. * </section>
  10. * Runs any functions named as profilings when the Profiling_Run function is called.
  11. * <section>
  12. * Version
  13. * </section>
  14. * 1.0
  15. * </library>
  16. *//** *//*
  17. Legal:
  18. Version: MPL 1.1
  19. The contents of this file are subject to the Mozilla Public License Version
  20. 1.1 the "License"; you may not use this file except in compliance with
  21. the License. You may obtain a copy of the License at
  22. http://www.mozilla.org/MPL/
  23. Software distributed under the License is distributed on an "AS IS" basis,
  24. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  25. for the specific language governing rights and limitations under the
  26. License.
  27. The Original Code is the YSI framework.
  28. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  29. Portions created by the Initial Developer are Copyright C 2011
  30. the Initial Developer. All Rights Reserved.
  31. Contributors:
  32. Y_Less
  33. koolk
  34. JoeBullet/Google63
  35. g_aSlice/Slice
  36. Misiur
  37. samphunter
  38. tianmeta
  39. maddinat0r
  40. spacemud
  41. Crayder
  42. Dayvison
  43. Ahmad45123
  44. Zeex
  45. irinel1996
  46. Yiin-
  47. Chaprnks
  48. Konstantinos
  49. Masterchen09
  50. Southclaws
  51. PatchwerkQWER
  52. m0k1
  53. paulommu
  54. udan111
  55. Thanks:
  56. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  57. ZeeX - Very productive conversations.
  58. koolk - IsPlayerinAreaEx code.
  59. TheAlpha - Danish translation.
  60. breadfish - German translation.
  61. Fireburn - Dutch translation.
  62. yom - French translation.
  63. 50p - Polish translation.
  64. Zamaroht - Spanish translation.
  65. Los - Portuguese translation.
  66. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes for
  67. me to strive to better.
  68. Pixels^ - Running XScripters where the idea was born.
  69. Matite - Pestering me to release it and using it.
  70. Very special thanks to:
  71. Thiadmer - PAWN, whose limits continue to amaze me!
  72. Kye/Kalcor - SA:MP.
  73. SA:MP Team past, present and future - SA:MP.
  74. Optional plugins:
  75. Gamer_Z - GPS.
  76. Incognito - Streamer.
  77. Me - sscanf2, fixes2, Whirlpool.
  78. */
  79. #include "y_debug"
  80. CHAIN_HOOK(Profiling)
  81. #undef CHAIN_ORDER
  82. #define CHAIN_ORDER CHAIN_NEXT(Profiling)
  83. #if defined YSI_PROFILINGS
  84. #if defined INCLUDE_PROFILINGS
  85. #error Incompatible profiling options (YSI_PROFILINGS + INCLUDE_PROFILINGS)
  86. #endif
  87. #if !defined RUN_PROFILINGS
  88. #define RUN_PROFILINGS
  89. #endif
  90. #endif
  91. #if defined INCLUDE_PROFILINGS
  92. #define RUN_PROFILINGS
  93. #define Debug_PrintP printf
  94. #elseif defined RUN_PROFILINGS
  95. #define _AUTO_RUN_PROFILINGS
  96. #define Debug_PrintP printf
  97. #else
  98. #if _DEBUG > 0 || defined _YSI_SPECIAL_DEBUG
  99. #define RUN_PROFILINGS
  100. #define _AUTO_RUN_PROFILINGS
  101. #define Debug_PrintP printf
  102. #else
  103. #define Debug_PrintP(%0);
  104. #endif
  105. #endif
  106. #if defined LIGHT_PROFILE_REPORT
  107. #define PROFILE_REPORT(%0);
  108. #else
  109. #define PROFILE_REPORT(%0) printf(%0)
  110. #endif
  111. #if defined RUN_PROFILINGS
  112. #define PROFILE_INIT__%0(%1) @yP_%0();@yP_%0()
  113. #define PROFILE__%0(%1) __TZ:@y_P%0();__TZ:@y_P%0(%1)RUN_TIMING(#%0)y_P@%0();static y_P@%0()
  114. #define PROFILE_CLOSE__%0(%1) @P_y%0();@P_y%0()
  115. #define __TZ:%0[%2](%1);%0[%2](%1)RUN_TIMING(%3)%4[%5](%6);%9[%5](%6) %0(%1);%0(%1)RUN_TIMING(%3,%2)%4(%6);static %4(%6)
  116. #else
  117. #define PROFILE_INIT__%0(%1) static stock yP_@%0()
  118. #define PROFILE__%0(%1) static stock __TZ:y_P@%0()
  119. #define PROFILE_CLOSE__%0(%1) static stock P_y@%0()
  120. #define __TZ:%0[%2](%1) __TZ:%0_%2(%1)
  121. #endif
  122. #if YSI_KEYWORD(ProfileInit)
  123. #define ProfileInit:%1() PROFILE_INIT__ %1()
  124. #endif
  125. #if YSI_KEYWORD(Profile)
  126. #define Profile:%1() PROFILE__ %1()
  127. #endif
  128. #if YSI_KEYWORD(ProfileClose)
  129. #define ProfileClose:%1() PROFILE_CLOSE__ %1()
  130. #endif
  131. #define @yP_%0\32; @yP_
  132. #define @y_P%0\32; @y_P
  133. #define @P_y%0\32; @P_y
  134. #define yP_@%0\32; yP_@
  135. #define y_P@%0\32; y_P@
  136. #define P_y@%0\32; P_y@
  137. // These all need to come AFTER the types are defined in case the have profilings.
  138. #include "y_utils"
  139. #include "..\YSI_Coding\y_va"
  140. #define Y_PROFILING_PROFILE_SEARCH _A<@y_P>
  141. #define Y_PROFILING_INIT _C<@yP_>
  142. #define Y_PROFILING_PROFILE _C<@y_P>
  143. #define Y_PROFILING_CLOSE _C<@P_y>
  144. static stock
  145. bool:YSI_g_sInProfile = false;
  146. /*-------------------------------------------------------------------------*//**
  147. * <param name="profilings">Number of profilings run.</param>
  148. * <returns>
  149. * Wether all profilings were sucessful or not.
  150. * </returns>
  151. * <remarks>
  152. * -
  153. *
  154. * native Profiling_Run(&profilings, &fails, buffer[33] = "");
  155. *
  156. * </remarks>
  157. *//*------------------------------------------------------------------------**/
  158. stock bool:Profiling_Run(&profilings)
  159. {
  160. P:3("bool:Profiling_Run called: %i", profilings);
  161. #if defined RUN_PROFILINGS
  162. P:2("Profiling_Run() called");
  163. new
  164. idx,
  165. buffer[32];
  166. while ((idx = AMX_GetPublicNamePrefix(idx, buffer, Y_PROFILING_PROFILE_SEARCH)))
  167. {
  168. buffer[0] = Y_PROFILING_INIT,
  169. CallLocalFunction(buffer, ""),
  170. // Call the test.
  171. buffer[0] = Y_PROFILING_PROFILE;
  172. P:5("Profiling_Run(): Calling %s", unpack(buffer[1]));
  173. YSI_g_sInProfile = true,
  174. CallLocalFunction(buffer, ""),
  175. YSI_g_sInProfile = false,
  176. buffer[0] = Y_PROFILING_CLOSE,
  177. CallLocalFunction(buffer, ""),
  178. ++profilings;
  179. PROFILE_REPORT(" ");
  180. }
  181. #else
  182. #pragma unused profilings
  183. #endif
  184. }
  185. forward OnProfilingsComplete(profilings, fails);
  186. #if defined RUN_PROFILINGS
  187. #if defined _AUTO_RUN_PROFILINGS
  188. public OnScriptInit()
  189. {
  190. Profiling_RunAll();
  191. return Profiling_OnScriptInit();
  192. }
  193. CHAIN_FORWARD:Profiling_OnScriptInit() = 1;
  194. #undef OnScriptInit
  195. #define OnScriptInit(%0) CHAIN_PUBLIC:Profiling_OnScriptInit(%0)
  196. #endif
  197. public OnRuntimeError(code, &bool:suppress)
  198. {
  199. if (YSI_g_sInProfile)
  200. {
  201. // Fail the current profile if we see any runtime errors. Requires the
  202. // crashdetect plugin to function, but not to compile and run.
  203. P:P("Error: Runtime error detected");
  204. }
  205. return Profiling_OnRuntimeError(code, suppress);
  206. }
  207. CHAIN_FORWARD:Profiling_OnRuntimeError(code, &bool:suppress) = 1;
  208. #if defined _ALS_OnRuntimeError
  209. #undef OnRuntimeError
  210. #else
  211. #define _ALS_OnRuntimeError
  212. #endif
  213. #define OnRuntimeError(%0) CHAIN_PUBLIC:Profiling_OnRuntimeError(%0)
  214. #endif
  215. stock Profiling_RunAll()
  216. {
  217. // Disable error messages (as we're likely to generate them).
  218. new
  219. startTime,
  220. endTime,
  221. profilings;
  222. // The timing will be inaccurate since it will include many prints, but it
  223. // isn't that important to be accurate.
  224. startTime = GetTickCount();
  225. PROFILE_REPORT(" ");
  226. PROFILE_REPORT(" ||========================|| ");
  227. PROFILE_REPORT(" || STARTING PROFILINGS... || ");
  228. PROFILE_REPORT(" ||========================|| ");
  229. PROFILE_REPORT(" ");
  230. Profiling_Run(profilings);
  231. printf("*** Profilings: %d", profilings);
  232. PROFILE_REPORT(" ");
  233. PROFILE_REPORT(" ||======================|| ");
  234. PROFILE_REPORT(" || PROFILINGS COMPLETE! || ");
  235. PROFILE_REPORT(" ||======================|| ");
  236. PROFILE_REPORT(" ");
  237. endTime = GetTickCount();
  238. printf("*** Time: %dms", endTime - startTime);
  239. PROFILE_REPORT(" ");
  240. CallLocalFunction("OnProfilingsComplete", "i", profilings);
  241. #if defined PROFILE_AUTO_EXIT
  242. SendRconCommand("exit");
  243. #endif
  244. }