profiler_unittest.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
  2. // Copyright (c) 2005, Google Inc.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // ---
  31. // Author: Craig Silverstein
  32. //
  33. // Does some simple arithmetic and a few libc routines, so we can profile it.
  34. // Define WITH_THREADS to add pthread functionality as well (otherwise, btw,
  35. // the num_threads argument to this program is ingored).
  36. #include "config_for_unittests.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #ifdef HAVE_UNISTD_H
  40. #include <unistd.h> // for fork()
  41. #endif
  42. #include <sys/wait.h> // for wait()
  43. #include "gperftools/profiler.h"
  44. #include "base/simple_mutex.h"
  45. #include "tests/testutil.h"
  46. static volatile int result = 0;
  47. static int g_iters = 0; // argv[1]
  48. Mutex mutex(Mutex::LINKER_INITIALIZED);
  49. static void test_other_thread() {
  50. #ifndef NO_THREADS
  51. ProfilerRegisterThread();
  52. int i, m;
  53. char b[128];
  54. MutexLock ml(&mutex);
  55. for (m = 0; m < 1000000; ++m) { // run millions of times
  56. for (i = 0; i < g_iters; ++i ) {
  57. result ^= i;
  58. }
  59. snprintf(b, sizeof(b), "other: %d", result); // get some libc action
  60. }
  61. #endif
  62. }
  63. static void test_main_thread() {
  64. int i, m;
  65. char b[128];
  66. MutexLock ml(&mutex);
  67. for (m = 0; m < 1000000; ++m) { // run millions of times
  68. for (i = 0; i < g_iters; ++i ) {
  69. result ^= i;
  70. }
  71. snprintf(b, sizeof(b), "same: %d", result); // get some libc action
  72. }
  73. }
  74. int main(int argc, char** argv) {
  75. if ( argc <= 1 ) {
  76. fprintf(stderr, "USAGE: %s <iters> [num_threads] [filename]\n", argv[0]);
  77. fprintf(stderr, " iters: How many million times to run the XOR test.\n");
  78. fprintf(stderr, " num_threads: how many concurrent threads.\n");
  79. fprintf(stderr, " 0 or 1 for single-threaded mode,\n");
  80. fprintf(stderr, " -# to fork instead of thread.\n");
  81. fprintf(stderr, " filename: The name of the output profile.\n");
  82. fprintf(stderr, (" If you don't specify, set CPUPROFILE "
  83. "in the environment instead!\n"));
  84. return 1;
  85. }
  86. g_iters = atoi(argv[1]);
  87. int num_threads = 1;
  88. const char* filename = NULL;
  89. if (argc > 2) {
  90. num_threads = atoi(argv[2]);
  91. }
  92. if (argc > 3) {
  93. filename = argv[3];
  94. }
  95. if (filename) {
  96. ProfilerStart(filename);
  97. }
  98. test_main_thread();
  99. ProfilerFlush(); // just because we can
  100. // The other threads, if any, will run only half as long as the main thread
  101. if(num_threads > 0) {
  102. RunManyThreads(test_other_thread, num_threads);
  103. } else {
  104. // Or maybe they asked to fork. The fork test is only interesting
  105. // when we use CPUPROFILE to name, so check for that
  106. #ifdef HAVE_UNISTD_H
  107. for (; num_threads < 0; ++num_threads) { // -<num_threads> to fork
  108. if (filename) {
  109. printf("FORK test only makes sense when no filename is specified.\n");
  110. return 2;
  111. }
  112. switch (fork()) {
  113. case -1:
  114. printf("FORK failed!\n");
  115. return 1;
  116. case 0: // child
  117. return execl(argv[0], argv[0], argv[1], NULL);
  118. default:
  119. wait(NULL); // we'll let the kids run one at a time
  120. }
  121. }
  122. #else
  123. fprintf(stderr, "%s was compiled without support for fork() and exec()\n", argv[0]);
  124. #endif
  125. }
  126. test_main_thread();
  127. if (filename) {
  128. ProfilerStop();
  129. }
  130. return 0;
  131. }