1994-02-07 01:05:54 +00:00
|
|
|
|
/* profile.c --- generate periodic events for profiling of Emacs Lisp code.
|
2017-01-01 03:14:01 +00:00
|
|
|
|
Copyright (C) 1992, 1994, 1999, 2001-2017 Free Software Foundation,
|
2013-01-01 09:11:05 +00:00
|
|
|
|
Inc.
|
1994-02-07 01:05:54 +00:00
|
|
|
|
|
2008-05-09 23:19:13 +00:00
|
|
|
|
Author: Boaz Ben-Zvi <boaz@lcs.mit.edu>
|
1994-02-07 01:05:54 +00:00
|
|
|
|
|
1996-01-15 09:18:04 +00:00
|
|
|
|
This file is part of GNU Emacs.
|
|
|
|
|
|
2008-05-09 23:19:13 +00:00
|
|
|
|
GNU Emacs is free software: you can redistribute it and/or modify
|
1996-01-15 09:18:04 +00:00
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2016-03-10 07:34:52 -08:00
|
|
|
|
the Free Software Foundation, either version 3 of the License, or (at
|
|
|
|
|
your option) any later version.
|
1996-01-15 09:18:04 +00:00
|
|
|
|
|
|
|
|
|
GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2017-09-13 15:52:52 -07:00
|
|
|
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
1994-02-07 01:05:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
Adapt the MS-DOS build to the latest changes.
msdos/mainmake.v2 (bootstrap-clean): Do a maintainer-clean in lib, not
bootstrap-clean (which doesn't exist).
msdos/inttypes.h (PRIuMAX) [__DJGPP__ < 2.04]: Define to "llu".
msdos/sedleim.inp (MKDIR_P): Edit to DOS "md" command.
msdos/sed1v2.inp: (LIB_CLOCK_GETTIME): Edit to empty.
Remove lines that invoke PAXCTL.
(clean): Fix recipe not to run Unixy shell commands.
msdos/sed2v2.inp (GETTIMEOFDAY_TIMEZONE): Edit to 'struct timezone'.
(HAVE_STRNCASECMP): Edit to 1.
msdos/sed3v2.inp (LIB_CLOCK_GETTIME): Edit to empty.
(C_SWITCH_SYSTEM): Add "-I../msdos".
msdos/sedlibmk.inp (GNULIB_GETTIMEOFDAY, GNULIB_PSELECT)
(GNULIB_SELECT, HAVE_STRUCT_TIMEVAL, HAVE_SYS_SELECT_H)
(HAVE_SYS_TIME_H, NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H)
(NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H, NEXT_SYS_SELECT_H)
(NEXT_SYS_TIME_H, REPLACE_GETTIMEOFDAY, REPLACE_PSELECT)
(REPLACE_STRUCT_TIMEVAL): Edit to appropriate values.
(BUILT_SOURCES): Edit out sys/select.h and sys/time.h.
(mostlyclean-local, distclean-generic): Fix recipe not to run
Unixy shell commands.
src/sysselect.h [DOS_NT]: Don't include sys/select.h.
src/s/ms-w32.h (select, pselect): Don't define here, they are
defined in sysselect.h
src/sysselect.h (pselect) [!HAVE_PSELECT]: Redirect to sys_select.
src/sysdep.c: Don't include dos.h and dosfns.h.
src/process.c (sys_select):
src/msdos.c (sys_select): Accept one more argument and ignore it.
src/msdos.c (event_timestamp, sys_select): Use gnulib's gettime;
adapt data types and code to that.
src/dosfns.c:
src/msdos.c (gettime, settime): Define away the prototypes in dos.h,
which clashes with the gnulib function of the same name.
lisp/emacs-lisp/timer.el (timer-until): Subtract results of
float-time, instead of taking float-time of the result of
time-subtract, since float-time signals an error for negative time
arguments.
2012-06-30 18:32:51 +03:00
|
|
|
|
** To be run as an emacs subprocess. Input string that starts with:
|
1994-02-07 01:05:54 +00:00
|
|
|
|
** 'z' -- resets the watch (to zero).
|
|
|
|
|
** 'p' -- return time (on stdout) as string with format <sec>.<micro-sec>
|
|
|
|
|
** 'q' -- exit.
|
|
|
|
|
**
|
|
|
|
|
** abstraction : a stopwatch
|
|
|
|
|
** operations: reset_watch, get_time
|
|
|
|
|
*/
|
2012-06-22 14:17:42 -07:00
|
|
|
|
|
A simpler, centralized INLINE.
* lib-src/profile.c (INLINE): New macro.
(SYSTIME_INLINE): Remove.
* src/conf_post.h (INLINE): Define only if not already defined.
This allows us to use a single INLINE, defined by one file
per executable.
* src/emacs.c (INLINE): Define it.
Also, include category.h, charset.h, composite.h, dispextern.h,
syntax.h, systime.h, so that their INLINE definitions are expanded
properly for Emacs.
* src/blockinput.h, src/keyboard.c (BLOCKINPUT_INLINE):
* src/buffer.h, src/buffer.c (BUFFER_INLINE):
* src/category.h, src/category.c (CATEGORY_INLINE):
* src/character.h, src/character.c (CHARACTER_INLINE):
* src/charset.h, src/charset.c (CHARSET_INLINE):
* src/composite.h, src/composite.c (COMPOSITE_INLINE):
* src/dispextern.h, src/dispnew.c (DISPEXTERN_INLINE):
* src/frame.h, src/frame.c (FRAME_INLINE):
* src/intervals.h, src/intervals.c (INTERVALS_INLINE):
* src/keyboard.h, src/keyboard.c (KEYBOARD_INLINE):
* src/lisp.h, src/alloc.c (LISP_INLINE):
* src/process.h, src/process.c (PROCESS_INLINE):
* src/syntax.h, src/syntax.c (SYNTAX_INLINE):
* src/systime.h, src/sysdep.c (SYSTIME_INLINE):
* src/termhooks.h, src/terminal.h (TERMHOOKS_INLINE):
* src/window.h, src/window.c (WINDOW_INLINE):
Remove. All uses replaced with INLINE.
2013-09-20 08:34:36 -07:00
|
|
|
|
#define INLINE EXTERN_INLINE
|
|
|
|
|
#include <config.h>
|
Use C99-style 'extern inline' if available.
* lib-src/profile.c (SYSTIME_INLINE): Define.
* nt/config.nt: Sync with autogen/config.in.
(_GL_INLINE, _GL_EXTERN_INLINE, _GL_INLINE_HEADER_BEGIN)
(_GL_INLINE_HEADER_END): New macros.
* src/buffer.h (BUFFER_INLINE):
* src/category.h (CATEGORY_INLINE):
* src/character.h (CHARACTER_INLINE):
* src/charset.h (CHARSET_INLINE):
* src/composite.h (COMPOSITE_INLINE):
* src/dispextern.h (DISPEXTERN_INLINE):
* src/lisp.h (LISP_INLINE):
* src/systime.h (SYSTIME_INLINE):
New macro, replacing 'static inline' in this header.
* src/buffer.h, src/category.h, src/character.h, src/charset.h:
* src/composite.h, src/dispextern.h, lisp.h, systime.h:
Use INLINE_HEADER_BEGIN, INLINE_HEADER_END.
* src/alloc.c (LISP_INLINE):
* src/buffer.c (BUFFER_INLINE):
* src/category.c (CATEGORY_INLINE):
* src/character.c (CHARACTER_INLINE):
* src/charset.c (CHARSET_INLINE):
* src/composite.c (COMPOSITE_INLINE):
* src/dispnew.c (DISPEXTERN_INLINE):
* src/sysdep.c (SYSTIME_INLINE):
Define to EXTERN_INLINE, so that the corresponding functions
are compiled into code.
* src/conf_post.h (INLINE, EXTERN_INLINE, INLINE_HEADER_BEGIN)
(INLINE_HEADER_END): New macros.
* src/lisp.h (PSEUDOVECTOR_FLAG): Now a macro as well as a constant,
since it's used in non-static inline functions now.
2012-08-02 00:31:34 -07:00
|
|
|
|
|
2012-06-22 14:17:42 -07:00
|
|
|
|
#include <inttypes.h>
|
Limit <config.h>’s includes
This follows up on recent problems with the fact that config.h
includes stdlib.h etc.; some files need to include stdlib.h later.
config.h generally should limit itself to includes that are
universally safe; outside of MS-Windows, only stdbool.h makes
the cut among the files currently included. So, move the
other includes to just the files that need them (Bug#24506).
* configure.ac (config_opsysfile): Remove, as this generic hook
is no longer needed.
* lib-src/etags.c, src/unexmacosx.c, src/w32.c, src/w32notify.c:
* src/w32proc.c (_GNU_SOURCE):
Remove, as it’s OK for config.h to do this now.
* src/conf_post.h: Include <ms-w32.h>, instead of the generic
config_opsysfile, for simplicity as this old way of configuring is
now done only for the MS-Windows port. Do not include <ms-w32.h>
if DEFER_MS_W32_H, for the benefit of the few files that want its
effects later. Do not include <alloca.h>, <string.h>, or
<stdlib.h>. Other files modified to include these headers as
needed, or to not include headers that are no longer needed.
* src/lisp.h: Include <alloca.h> and <string.h> here, since
some of the inline functions need them.
* src/regex.c: Include <alloca.h> if not emacs. (If emacs,
we can rely on SAFE_ALLOCA.) There is no longer any need to
worry about HAVE_ALLOCA_H.
* src/unexmacosx.c: Rely on config.h not including stdlib.h.
* src/w32.c, src/w32notify.c, src/w32proc.c (DEFER_MS_W32_H):
Define before including <config.h> first, and include <ms-w32.h>
after the troublesome headers.
2016-09-30 12:14:04 -07:00
|
|
|
|
#include <stdlib.h>
|
2012-06-22 14:17:42 -07:00
|
|
|
|
|
|
|
|
|
#include <intprops.h>
|
2001-10-08 04:52:12 +00:00
|
|
|
|
#include <systime.h>
|
Use unlocked stdio more systematically
This can improve performance significantly on stdio-bottlenecked code.
E.g., make-docfile is 3x faster on my Fedora 25 x86-64 desktop.
* admin/merge-gnulib (GNULIB_MODULES): Add unlocked-io.
* lib-src/ebrowse.c, lib-src/emacsclient.c, lib-src/etags.c:
* lib-src/hexl.c, lib-src/make-docfile.c, lib-src/movemail.c:
* lib-src/profile.c, lib-src/update-game-score.c:
Include unlocked-io.h instead of stdio.h, since these programs are
single-threaded.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib/unlocked-io.h, m4/unlocked-io.m4: New files, copied from Gnulib.
* src/charset.c, src/cm.c, src/emacs.c, src/image.c, src/keyboard.c:
* src/lread.c, src/term.c:
Include sysstdio.h, possibly instead of stdio.h, to define
the unlocked functions if the system does not provide them.
* src/charset.c, src/lread.c (getc_unlocked):
Remove, since sysstdio.h now defines it if needed.
* src/cm.c (cmputc, cmcheckmagic):
* src/dispnew.c (update_frame, update_frame_with_menu)
(update_frame_1, Fsend_string_to_terminal, Fding, bitch_at_user):
* src/emacs.c (main, Fdump_emacs):
* src/fileio.c (Fdo_auto_save, Fset_binary_mode):
* src/image.c (slurp_file, png_read_from_file, png_load_body)
(our_stdio_fill_input_buffer):
* src/keyboard.c (record_char, kbd_buffer_get_event, handle_interrupt):
* src/lread.c (readbyte_from_file):
* src/minibuf.c (read_minibuf_noninteractive):
* src/print.c (printchar_to_stream, strout)
(Fredirect_debugging_output):
* src/sysdep.c (reset_sys_modes, procfs_ttyname)
(procfs_get_total_memory):
* src/term.c (tty_ring_bell, tty_send_additional_strings)
(tty_set_terminal_modes, tty_reset_terminal_modes)
(tty_update_end, tty_clear_end_of_line, tty_write_glyphs)
(tty_write_glyphs_with_face, tty_insert_glyphs)
(tty_menu_activate):
* src/xfaces.c (Fx_load_color_file):
Use unlocked stdio when it should be safe.
* src/sysstdio.h (clearerr_unlocked, feof_unlocked, ferror_unlocked)
(fflush_unlocked, fgets_unlocked, fputc_unlocked, fputs_unlocked)
(fread_unlocked, fwrite_unlocked, getc_unlocked, getchar_unlocked)
(putc_unlocked, putchar_unloced): Provide substitutes if not declared.
2017-06-22 11:21:20 -07:00
|
|
|
|
#include <unlocked-io.h>
|
1994-02-07 01:05:54 +00:00
|
|
|
|
|
2013-08-27 11:47:55 -07:00
|
|
|
|
static struct timespec TV1;
|
1994-02-07 01:05:54 +00:00
|
|
|
|
static int watch_not_started = 1; /* flag */
|
2012-06-22 14:17:42 -07:00
|
|
|
|
static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "."
|
2013-08-27 11:47:55 -07:00
|
|
|
|
+ LOG10_TIMESPEC_RESOLUTION];
|
1994-02-07 01:05:54 +00:00
|
|
|
|
|
|
|
|
|
/* Reset the stopwatch to zero. */
|
|
|
|
|
|
2011-02-21 10:06:25 -08:00
|
|
|
|
static void
|
2010-07-02 17:50:23 -07:00
|
|
|
|
reset_watch (void)
|
1994-02-07 01:05:54 +00:00
|
|
|
|
{
|
2013-08-27 11:47:55 -07:00
|
|
|
|
TV1 = current_timespec ();
|
1994-02-07 01:05:54 +00:00
|
|
|
|
watch_not_started = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This call returns the time since the last reset_watch call. The time
|
2012-06-22 14:17:42 -07:00
|
|
|
|
is returned as a string with the format <seconds>.<nanoseconds>
|
1994-02-23 17:43:05 +00:00
|
|
|
|
If reset_watch was not called yet, exit. */
|
1994-02-07 01:05:54 +00:00
|
|
|
|
|
2011-02-21 10:06:25 -08:00
|
|
|
|
static char *
|
2010-07-02 17:50:23 -07:00
|
|
|
|
get_time (void)
|
1994-02-07 01:05:54 +00:00
|
|
|
|
{
|
2013-08-27 11:47:55 -07:00
|
|
|
|
struct timespec TV2 = timespec_sub (current_timespec (), TV1);
|
|
|
|
|
uintmax_t s = TV2.tv_sec;
|
|
|
|
|
int ns = TV2.tv_nsec;
|
1994-02-07 01:05:54 +00:00
|
|
|
|
if (watch_not_started)
|
2004-05-08 15:26:33 +00:00
|
|
|
|
exit (EXIT_FAILURE); /* call reset_watch first ! */
|
2013-08-27 11:47:55 -07:00
|
|
|
|
sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_TIMESPEC_RESOLUTION, ns);
|
1994-02-07 01:05:54 +00:00
|
|
|
|
return time_string;
|
|
|
|
|
}
|
1995-07-30 07:07:39 +00:00
|
|
|
|
|
1996-07-15 21:27:49 +00:00
|
|
|
|
int
|
2010-07-02 17:50:23 -07:00
|
|
|
|
main (void)
|
1994-02-07 01:05:54 +00:00
|
|
|
|
{
|
1994-02-23 17:43:05 +00:00
|
|
|
|
int c;
|
|
|
|
|
while ((c = getchar ()) != EOF)
|
1994-02-07 01:05:54 +00:00
|
|
|
|
{
|
1994-02-23 17:43:05 +00:00
|
|
|
|
switch (c)
|
1994-02-07 01:05:54 +00:00
|
|
|
|
{
|
|
|
|
|
case 'z':
|
|
|
|
|
reset_watch ();
|
|
|
|
|
break;
|
|
|
|
|
case 'p':
|
|
|
|
|
puts (get_time ());
|
|
|
|
|
break;
|
|
|
|
|
case 'q':
|
2016-11-25 21:24:28 -08:00
|
|
|
|
return EXIT_SUCCESS;
|
1994-02-07 01:05:54 +00:00
|
|
|
|
}
|
1994-02-23 17:43:05 +00:00
|
|
|
|
/* Anything remaining on the line is ignored. */
|
|
|
|
|
while (c != '\n' && c != EOF)
|
|
|
|
|
c = getchar ();
|
1994-02-07 01:05:54 +00:00
|
|
|
|
}
|
2016-11-25 21:24:28 -08:00
|
|
|
|
return EXIT_FAILURE;
|
1994-02-07 01:05:54 +00:00
|
|
|
|
}
|
2003-09-01 15:45:59 +00:00
|
|
|
|
|
2004-05-08 15:26:33 +00:00
|
|
|
|
|
|
|
|
|
/* profile.c ends here */
|