You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /** @file
  25. *
  26. * Profiling self-tests
  27. *
  28. */
  29. /* Forcibly enable assertions */
  30. #undef NDEBUG
  31. #include <string.h>
  32. #include <assert.h>
  33. #include <ipxe/test.h>
  34. #include <ipxe/profile.h>
  35. /** A profiling test */
  36. struct profile_test {
  37. /** Sample values */
  38. const unsigned long *samples;
  39. /** Number of samples */
  40. unsigned int count;
  41. /** Expected mean sample value */
  42. unsigned long mean;
  43. /** Expected standard deviation */
  44. unsigned long stddev;
  45. };
  46. /** Define inline data */
  47. #define DATA(...) { __VA_ARGS__ }
  48. /** Define a profiling test */
  49. #define PROFILE_TEST( name, MEAN, STDDEV, SAMPLES ) \
  50. static const unsigned long name ## _samples[] = SAMPLES; \
  51. static struct profile_test name = { \
  52. .samples = name ## _samples, \
  53. .count = ( sizeof ( name ## _samples ) / \
  54. sizeof ( name ## _samples [0] ) ), \
  55. .mean = MEAN, \
  56. .stddev = STDDEV, \
  57. }
  58. /** Empty data set */
  59. PROFILE_TEST ( empty, 0, 0, DATA() );
  60. /** Single-element data set (zero) */
  61. PROFILE_TEST ( zero, 0, 0, DATA ( 0 ) );
  62. /** Single-element data set (non-zero) */
  63. PROFILE_TEST ( single, 42, 0, DATA ( 42 ) );
  64. /** Multiple identical element data set */
  65. PROFILE_TEST ( identical, 69, 0, DATA ( 69, 69, 69, 69, 69, 69, 69 ) );
  66. /** Small element data set */
  67. PROFILE_TEST ( small, 5, 2, DATA ( 3, 5, 9, 4, 3, 2, 5, 7 ) );
  68. /** Random data set */
  69. PROFILE_TEST ( random, 70198, 394,
  70. DATA ( 69772, 70068, 70769, 69653, 70663, 71078, 70101, 70341,
  71. 70215, 69600, 70020, 70456, 70421, 69972, 70267, 69999,
  72. 69972 ) );
  73. /** Large-valued random data set */
  74. PROFILE_TEST ( large, 93533894UL, 25538UL,
  75. DATA ( 93510333UL, 93561169UL, 93492361UL, 93528647UL,
  76. 93557566UL, 93503465UL, 93540126UL, 93549020UL,
  77. 93502307UL, 93527320UL, 93537152UL, 93540125UL,
  78. 93550773UL, 93586731UL, 93521312UL ) );
  79. /**
  80. * Report a profiling test result
  81. *
  82. * @v test Profiling test
  83. * @v file Test code file
  84. * @v line Test code line
  85. */
  86. static void profile_okx ( struct profile_test *test, const char *file,
  87. unsigned int line ) {
  88. struct profiler profiler;
  89. unsigned long mean;
  90. unsigned long stddev;
  91. unsigned int i;
  92. /* Initialise profiler */
  93. memset ( &profiler, 0, sizeof ( profiler ) );
  94. /* Record sample values */
  95. for ( i = 0 ; i < test->count ; i++ )
  96. profile_update ( &profiler, test->samples[i] );
  97. /* Check resulting statistics */
  98. mean = profile_mean ( &profiler );
  99. stddev = profile_stddev ( &profiler );
  100. DBGC ( test, "PROFILE calculated mean %ld stddev %ld\n", mean, stddev );
  101. okx ( mean == test->mean, file, line );
  102. okx ( stddev == test->stddev, file, line );
  103. }
  104. #define profile_ok( test ) profile_okx ( test, __FILE__, __LINE__ )
  105. /**
  106. * Perform profiling self-tests
  107. *
  108. */
  109. static void profile_test_exec ( void ) {
  110. /* Perform profiling tests */
  111. profile_ok ( &empty );
  112. profile_ok ( &zero );
  113. profile_ok ( &single );
  114. profile_ok ( &identical );
  115. profile_ok ( &small );
  116. profile_ok ( &random );
  117. profile_ok ( &large );
  118. }
  119. /** Profiling self-test */
  120. struct self_test profile_test __self_test = {
  121. .name = "profile",
  122. .exec = profile_test_exec,
  123. };