profile.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* profile.c --- generate periodic events for profiling of Emacs Lisp code.
  2. Copyright (C) 1992, 1994, 1999, 2001-2017 Free Software Foundation,
  3. Inc.
  4. Author: Boaz Ben-Zvi <boaz@lcs.mit.edu>
  5. This file is part of GNU Emacs.
  6. GNU Emacs is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or (at
  9. your option) any later version.
  10. GNU Emacs is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
  16. /**
  17. ** To be run as an emacs subprocess. Input string that starts with:
  18. ** 'z' -- resets the watch (to zero).
  19. ** 'p' -- return time (on stdout) as string with format <sec>.<micro-sec>
  20. ** 'q' -- exit.
  21. **
  22. ** abstraction : a stopwatch
  23. ** operations: reset_watch, get_time
  24. */
  25. #define INLINE EXTERN_INLINE
  26. #include <config.h>
  27. #include <inttypes.h>
  28. #include <stdlib.h>
  29. #include <intprops.h>
  30. #include <systime.h>
  31. #include <unlocked-io.h>
  32. static struct timespec TV1;
  33. static int watch_not_started = 1; /* flag */
  34. static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "."
  35. + LOG10_TIMESPEC_RESOLUTION];
  36. /* Reset the stopwatch to zero. */
  37. static void
  38. reset_watch (void)
  39. {
  40. TV1 = current_timespec ();
  41. watch_not_started = 0;
  42. }
  43. /* This call returns the time since the last reset_watch call. The time
  44. is returned as a string with the format <seconds>.<nanoseconds>
  45. If reset_watch was not called yet, exit. */
  46. static char *
  47. get_time (void)
  48. {
  49. struct timespec TV2 = timespec_sub (current_timespec (), TV1);
  50. uintmax_t s = TV2.tv_sec;
  51. int ns = TV2.tv_nsec;
  52. if (watch_not_started)
  53. exit (EXIT_FAILURE); /* call reset_watch first ! */
  54. sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_TIMESPEC_RESOLUTION, ns);
  55. return time_string;
  56. }
  57. int
  58. main (void)
  59. {
  60. int c;
  61. while ((c = getchar ()) != EOF)
  62. {
  63. switch (c)
  64. {
  65. case 'z':
  66. reset_watch ();
  67. break;
  68. case 'p':
  69. puts (get_time ());
  70. break;
  71. case 'q':
  72. return EXIT_SUCCESS;
  73. }
  74. /* Anything remaining on the line is ignored. */
  75. while (c != '\n' && c != EOF)
  76. c = getchar ();
  77. }
  78. return EXIT_FAILURE;
  79. }
  80. /* profile.c ends here */