profile.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* profile.c --- generate periodic events for profiling of Emacs Lisp code.
  2. Copyright (C) 1992, 1994, 1999, 2001-2015 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
  9. (at 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 <stdio.h>
  29. #include <intprops.h>
  30. #include <systime.h>
  31. static struct timespec TV1;
  32. static int watch_not_started = 1; /* flag */
  33. static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "."
  34. + LOG10_TIMESPEC_RESOLUTION];
  35. /* Reset the stopwatch to zero. */
  36. static void
  37. reset_watch (void)
  38. {
  39. TV1 = current_timespec ();
  40. watch_not_started = 0;
  41. }
  42. /* This call returns the time since the last reset_watch call. The time
  43. is returned as a string with the format <seconds>.<nanoseconds>
  44. If reset_watch was not called yet, exit. */
  45. static char *
  46. get_time (void)
  47. {
  48. struct timespec TV2 = timespec_sub (current_timespec (), TV1);
  49. uintmax_t s = TV2.tv_sec;
  50. int ns = TV2.tv_nsec;
  51. if (watch_not_started)
  52. exit (EXIT_FAILURE); /* call reset_watch first ! */
  53. sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_TIMESPEC_RESOLUTION, ns);
  54. return time_string;
  55. }
  56. int
  57. main (void)
  58. {
  59. int c;
  60. while ((c = getchar ()) != EOF)
  61. {
  62. switch (c)
  63. {
  64. case 'z':
  65. reset_watch ();
  66. break;
  67. case 'p':
  68. puts (get_time ());
  69. break;
  70. case 'q':
  71. exit (EXIT_SUCCESS);
  72. }
  73. /* Anything remaining on the line is ignored. */
  74. while (c != '\n' && c != EOF)
  75. c = getchar ();
  76. }
  77. exit (EXIT_FAILURE);
  78. }
  79. /* profile.c ends here */