mirror of the now-defunct rocklinux.org
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.

145 lines
2.7 KiB

  1. /* Bash (wallclock-time) profiler. Written by Clifford Wolf.
  2. *
  3. * Usage:
  4. * gcc -shared -fPIC -Wall -o bash_profiler.so bash_profiler.c
  5. * enable -f ./bash_profiler.so bprof
  6. *
  7. * bprof a start; idle_in_a; brof a stop
  8. * bprof b start; idle_in_b; brof b stop
  9. * bprof a start; idle_in_a; brof a stop
  10. *
  11. * bprof all print
  12. * enable -d bprof
  13. */
  14. /* Some declarations copied from bash-2.05b headers */
  15. #include <stdint.h>
  16. typedef struct word_desc {
  17. char *word;
  18. int flags;
  19. } WORD_DESC;
  20. typedef struct word_list {
  21. struct word_list *next;
  22. WORD_DESC *word;
  23. } WORD_LIST;
  24. typedef int sh_builtin_func_t(WORD_LIST *);
  25. #define BUILTIN_ENABLED 0x1
  26. struct builtin {
  27. char *name;
  28. sh_builtin_func_t *function;
  29. int flags;
  30. char * const *long_doc;
  31. const char *short_doc;
  32. char *handle;
  33. };
  34. /* my hellobash builtin */
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <stdlib.h>
  38. #include <sys/time.h>
  39. long long mytime()
  40. {
  41. struct timeval tv;
  42. gettimeofday(&tv, 0);
  43. return tv.tv_sec*1000 + tv.tv_usec/1000;
  44. }
  45. struct bprofent;
  46. struct bprofent {
  47. char *id;
  48. int recursive;
  49. int count, running;
  50. long long tv_sum, tv_start;
  51. struct bprofent *next;
  52. };
  53. struct bprofent *bprofent_list = 0;
  54. int bprof_builtin(WORD_LIST *list)
  55. {
  56. struct bprofent *this = bprofent_list;
  57. char *mode, *name;
  58. if ( !list || !list->next ) {
  59. fprintf(stderr, "Usage: bprof {id|all} {start|stop|print}\n");
  60. return 1;
  61. }
  62. name = list->word->word;
  63. mode = list->next->word->word;
  64. if ( !strcmp(mode, "print") && !strcmp(name, "all") ) {
  65. while ( this ) {
  66. printf("%7d %7Ld %10.3f %s", this->count, this->tv_sum,
  67. (float)this->tv_sum/this->count, this->id);
  68. if (this->running)
  69. printf(" (active)");
  70. if (this->recursive)
  71. printf(" (recursive)");
  72. printf("\n");
  73. this = this->next;
  74. }
  75. return 0;
  76. }
  77. while ( this ) {
  78. if ( !strcmp(this->id, name) ) break;
  79. this = this->next;
  80. }
  81. if ( !this ) {
  82. this = calloc(1, sizeof(struct bprofent));
  83. this->id = strdup(name);
  84. this->next = bprofent_list;
  85. bprofent_list = this;
  86. }
  87. if ( !strcmp(mode, "start") ) {
  88. if (this->running++ == 0)
  89. this->tv_start = mytime();
  90. if (this->running > 1)
  91. this->recursive = 1;
  92. } else if ( !strcmp(mode, "stop") ) {
  93. if (--this->running == 0) {
  94. this->tv_sum += mytime() - this->tv_start;
  95. this->count++;
  96. }
  97. } else if ( !strcmp(mode, "print") ) {
  98. printf("%7d %7Ld %10.3f %s", this->count, this->tv_sum,
  99. (float)this->tv_sum/this->count, this->id);
  100. if (this->running)
  101. printf(" (active)");
  102. if (this->recursive)
  103. printf(" (recursive)");
  104. printf("\n");
  105. }
  106. return 0;
  107. }
  108. char *bprof_doc[] = {
  109. "bash profiler",
  110. 0
  111. };
  112. struct builtin bprof_struct = {
  113. "bprof",
  114. &bprof_builtin,
  115. BUILTIN_ENABLED,
  116. bprof_doc,
  117. "bash profiler",
  118. 0
  119. };