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.
This commit is contained in:
Paul Eggert 2017-06-22 11:21:20 -07:00
parent 18896f7913
commit f6ef15cf84
27 changed files with 341 additions and 116 deletions

View file

@ -40,7 +40,7 @@ GNULIB_MODULES='
sig2str socklen stat-time std-gnu11 stdalign stddef stdio
stpcpy strftime strtoimax symlink sys_stat
sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub
update-copyright utimens
update-copyright unlocked-io utimens
vla warnings
'

View file

@ -20,21 +20,21 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <getopt.h>
#include <flexmember.h>
#include <min-max.h>
#include <unlocked-io.h>
/* The SunOS compiler doesn't have SEEK_END. */
#ifndef SEEK_END
#define SEEK_END 2
#endif
#include <flexmember.h>
#include <min-max.h>
/* Files are read in chunks of this number of bytes. */
enum { READ_CHUNK_SIZE = 100 * 1024 };

View file

@ -73,7 +73,6 @@ char *w32_getenv (const char *);
#include <stdarg.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
@ -84,6 +83,8 @@ char *w32_getenv (const char *);
#include <signal.h>
#include <errno.h>
#include <unlocked-io.h>
#ifndef VERSION
#define VERSION "unspecified"
#endif

View file

@ -123,6 +123,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
#include <errno.h>
#include <fcntl.h>
#include <binary-io.h>
#include <unlocked-io.h>
#include <c-ctype.h>
#include <c-strcase.h>

View file

@ -22,11 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <binary-io.h>
#include <unlocked-io.h>
static char *progname;

View file

@ -39,10 +39,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <binary-io.h>
#include <intprops.h>
#include <min-max.h>
#include <unlocked-io.h>
#ifdef WINDOWSNT
/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
is really just insurance. */
@ -50,10 +54,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <direct.h>
#endif /* WINDOWSNT */
#include <binary-io.h>
#include <intprops.h>
#include <min-max.h>
#ifdef DOS_NT
/* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
is really just insurance.

View file

@ -59,7 +59,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
@ -69,6 +68,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <unlocked-io.h>
#include "syswait.h"
#ifdef MAIL_USE_POP
#include "pop.h"

View file

@ -34,11 +34,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <intprops.h>
#include <systime.h>
#include <unlocked-io.h>
static struct timespec TV1;
static int watch_not_started = 1; /* flag */

View file

@ -39,7 +39,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <pwd.h>
#include <ctype.h>
@ -47,6 +46,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/stat.h>
#include <getopt.h>
#include <unlocked-io.h>
#ifdef WINDOWSNT
#include "ntlib.h"
#endif

View file

@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings
# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unlocked-io update-copyright utimens vla warnings
MOSTLYCLEANFILES += core *.stackdump
@ -2996,6 +2996,15 @@ EXTRA_DIST += unistd.in.h
endif
## end gnulib module unistd
## begin gnulib module unlocked-io
ifeq (,$(OMIT_GNULIB_MODULE_unlocked-io))
EXTRA_DIST += unlocked-io.h
endif
## end gnulib module unlocked-io
## begin gnulib module update-copyright
ifeq (,$(OMIT_GNULIB_MODULE_update-copyright))

136
lib/unlocked-io.h Normal file
View file

@ -0,0 +1,136 @@
/* Prefer faster, non-thread-safe stdio functions if available.
Copyright (C) 2001-2004, 2009-2017 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Jim Meyering. */
#ifndef UNLOCKED_IO_H
# define UNLOCKED_IO_H 1
/* These are wrappers for functions/macros from the GNU C library, and
from other C libraries supporting POSIX's optional thread-safe functions.
The standard I/O functions are thread-safe. These *_unlocked ones are
more efficient but not thread-safe. That they're not thread-safe is
fine since all of the applications in this package are single threaded.
Also, some code that is shared with the GNU C library may invoke
the *_unlocked functions directly. On hosts that lack those
functions, invoke the non-thread-safe versions instead. */
# include <stdio.h>
# if HAVE_DECL_CLEARERR_UNLOCKED
# undef clearerr
# define clearerr(x) clearerr_unlocked (x)
# else
# define clearerr_unlocked(x) clearerr (x)
# endif
# if HAVE_DECL_FEOF_UNLOCKED
# undef feof
# define feof(x) feof_unlocked (x)
# else
# define feof_unlocked(x) feof (x)
# endif
# if HAVE_DECL_FERROR_UNLOCKED
# undef ferror
# define ferror(x) ferror_unlocked (x)
# else
# define ferror_unlocked(x) ferror (x)
# endif
# if HAVE_DECL_FFLUSH_UNLOCKED
# undef fflush
# define fflush(x) fflush_unlocked (x)
# else
# define fflush_unlocked(x) fflush (x)
# endif
# if HAVE_DECL_FGETS_UNLOCKED
# undef fgets
# define fgets(x,y,z) fgets_unlocked (x,y,z)
# else
# define fgets_unlocked(x,y,z) fgets (x,y,z)
# endif
# if HAVE_DECL_FPUTC_UNLOCKED
# undef fputc
# define fputc(x,y) fputc_unlocked (x,y)
# else
# define fputc_unlocked(x,y) fputc (x,y)
# endif
# if HAVE_DECL_FPUTS_UNLOCKED
# undef fputs
# define fputs(x,y) fputs_unlocked (x,y)
# else
# define fputs_unlocked(x,y) fputs (x,y)
# endif
# if HAVE_DECL_FREAD_UNLOCKED
# undef fread
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
# else
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
# endif
# if HAVE_DECL_FWRITE_UNLOCKED
# undef fwrite
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
# else
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
# endif
# if HAVE_DECL_GETC_UNLOCKED
# undef getc
# define getc(x) getc_unlocked (x)
# else
# define getc_unlocked(x) getc (x)
# endif
# if HAVE_DECL_GETCHAR_UNLOCKED
# undef getchar
# define getchar() getchar_unlocked ()
# else
# define getchar_unlocked() getchar ()
# endif
# if HAVE_DECL_PUTC_UNLOCKED
# undef putc
# define putc(x,y) putc_unlocked (x,y)
# else
# define putc_unlocked(x,y) putc (x,y)
# endif
# if HAVE_DECL_PUTCHAR_UNLOCKED
# undef putchar
# define putchar(x) putchar_unlocked (x)
# else
# define putchar_unlocked(x) putchar (x)
# endif
# undef flockfile
# define flockfile(x) ((void) 0)
# undef ftrylockfile
# define ftrylockfile(x) 0
# undef funlockfile
# define funlockfile(x) ((void) 0)
#endif /* UNLOCKED_IO_H */

View file

@ -158,6 +158,7 @@ AC_DEFUN([gl_EARLY],
# Code from module timespec-sub:
# Code from module u64:
# Code from module unistd:
# Code from module unlocked-io:
# Code from module update-copyright:
# Code from module utimens:
# Code from module vararrays:
@ -399,6 +400,7 @@ AC_DEFUN([gl_INIT],
gl_TIMER_TIME
gl_TIMESPEC
gl_UNISTD_H
gl_FUNC_GLIBC_UNLOCKED_IO
gl_UTIMENS
AC_C_VARARRAYS
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
@ -940,6 +942,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/u64.h
lib/unistd.c
lib/unistd.in.h
lib/unlocked-io.h
lib/utimens.c
lib/utimens.h
lib/verify.h
@ -1044,6 +1047,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/timespec.m4
m4/tm_gmtoff.m4
m4/unistd_h.m4
m4/unlocked-io.m4
m4/utimens.m4
m4/utimes.m4
m4/vararrays.m4

41
m4/unlocked-io.m4 Normal file
View file

@ -0,0 +1,41 @@
# unlocked-io.m4 serial 15
# Copyright (C) 1998-2006, 2009-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl From Jim Meyering.
dnl
dnl See if the glibc *_unlocked I/O macros or functions are available.
dnl Use only those *_unlocked macros or functions that are declared
dnl (because some of them were declared in Solaris 2.5.1 but were removed
dnl in Solaris 2.6, whereas we want binaries built on Solaris 2.5.1 to run
dnl on Solaris 2.6).
AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO],
[
AC_DEFINE([USE_UNLOCKED_IO], [1],
[Define to 1 if you want getc etc. to use unlocked I/O if available.
Unlocked I/O can improve performance in unithreaded apps,
but it is not safe for multithreaded apps.])
dnl Persuade glibc and Solaris <stdio.h> to declare
dnl fgets_unlocked(), fputs_unlocked() etc.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_DECLS_ONCE([clearerr_unlocked])
AC_CHECK_DECLS_ONCE([feof_unlocked])
AC_CHECK_DECLS_ONCE([ferror_unlocked])
AC_CHECK_DECLS_ONCE([fflush_unlocked])
AC_CHECK_DECLS_ONCE([fgets_unlocked])
AC_CHECK_DECLS_ONCE([fputc_unlocked])
AC_CHECK_DECLS_ONCE([fputs_unlocked])
AC_CHECK_DECLS_ONCE([fread_unlocked])
AC_CHECK_DECLS_ONCE([fwrite_unlocked])
AC_CHECK_DECLS_ONCE([getc_unlocked])
AC_CHECK_DECLS_ONCE([getchar_unlocked])
AC_CHECK_DECLS_ONCE([putc_unlocked])
AC_CHECK_DECLS_ONCE([putchar_unlocked])
])

View file

@ -29,7 +29,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
@ -40,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "charset.h"
#include "coding.h"
#include "buffer.h"
#include "sysstdio.h"
/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) ***
@ -198,10 +198,6 @@ static struct
#define GET_TEMP_CHARSET_WORK_DECODER(CODE) \
(temp_charset_work->table.decoder[(CODE)])
#ifndef HAVE_GETC_UNLOCKED
#define getc_unlocked getc
#endif
/* Set to 1 to warn that a charset map is loaded and thus a buffer

View file

@ -19,10 +19,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include "lisp.h"
#include "cm.h"
#include "sysstdio.h"
#include "termchar.h"
#include "tparam.h"
@ -45,8 +45,8 @@ int
cmputc (int c)
{
if (current_tty->termscript)
putc (c & 0177, current_tty->termscript);
putc (c & 0177, current_tty->output);
putc_unlocked (c & 0177, current_tty->termscript);
putc_unlocked (c & 0177, current_tty->output);
return c;
}
@ -117,11 +117,11 @@ cmcheckmagic (struct tty_display_info *tty)
if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1)
emacs_abort ();
if (tty->termscript)
putc ('\r', tty->termscript);
putc ('\r', tty->output);
putc_unlocked ('\r', tty->termscript);
putc_unlocked ('\r', tty->output);
if (tty->termscript)
putc ('\n', tty->termscript);
putc ('\n', tty->output);
putc_unlocked ('\n', tty->termscript);
putc_unlocked ('\n', tty->output);
curX (tty) = 0;
curY (tty)++;
}

View file

@ -3126,9 +3126,9 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
{
if (FRAME_TTY (f)->termscript)
fflush (FRAME_TTY (f)->termscript);
fflush_unlocked (FRAME_TTY (f)->termscript);
if (FRAME_TERMCAP_P (f))
fflush (FRAME_TTY (f)->output);
fflush_unlocked (FRAME_TTY (f)->output);
}
/* Check window matrices for lost pointers. */
@ -3181,8 +3181,8 @@ update_frame_with_menu (struct frame *f, int row, int col)
update_end (f);
if (FRAME_TTY (f)->termscript)
fflush (FRAME_TTY (f)->termscript);
fflush (FRAME_TTY (f)->output);
fflush_unlocked (FRAME_TTY (f)->termscript);
fflush_unlocked (FRAME_TTY (f)->output);
/* Check window matrices for lost pointers. */
#if GLYPH_DEBUG
#if 0
@ -4531,7 +4531,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
ptrdiff_t outq = __fpending (display_output);
if (outq > 900
|| (outq > 20 && ((i - 1) % preempt_count == 0)))
fflush (display_output);
fflush_unlocked (display_output);
}
}
@ -5615,13 +5615,13 @@ when TERMINAL is nil. */)
if (tty->termscript)
{
fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
fflush (tty->termscript);
fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->termscript);
fflush_unlocked (tty->termscript);
}
out = tty->output;
}
fwrite (SDATA (string), 1, SBYTES (string), out);
fflush (out);
fwrite_unlocked (SDATA (string), 1, SBYTES (string), out);
fflush_unlocked (out);
unblock_input ();
return Qnil;
}
@ -5636,7 +5636,7 @@ terminate any keyboard macro currently executing. */)
if (!NILP (arg))
{
if (noninteractive)
putchar (07);
putchar_unlocked (07);
else
ring_bell (XFRAME (selected_frame));
}
@ -5650,7 +5650,7 @@ void
bitch_at_user (void)
{
if (noninteractive)
putchar (07);
putchar_unlocked (07);
else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
{
const char *msg

View file

@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
@ -33,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define MAIN_PROGRAM
#include "lisp.h"
#include "sysstdio.h"
#ifdef WINDOWSNT
#include <fcntl.h>
@ -885,7 +885,7 @@ main (int argc, char **argv)
}
#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
clearerr (stdin);
clearerr_unlocked (stdin);
emacs_backtrace (-1);
@ -983,7 +983,7 @@ main (int argc, char **argv)
int i;
printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
for (i = 0; i < ARRAYELTS (usage_message); i++)
fputs (usage_message[i], stdout);
fputs_unlocked (usage_message[i], stdout);
exit (0);
}
@ -2197,7 +2197,7 @@ You must run Emacs in batch mode in order to dump it. */)
}
#endif
fflush (stdout);
fflush_unlocked (stdout);
/* Tell malloc where start of impure now is. */
/* Also arrange for warnings when nearly out of space. */
#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC

View file

@ -5643,14 +5643,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
{
block_input ();
if (!NILP (BVAR (b, filename)))
{
fwrite (SDATA (BVAR (b, filename)), 1,
SBYTES (BVAR (b, filename)), stream);
}
putc ('\n', stream);
fwrite (SDATA (BVAR (b, auto_save_file_name)), 1,
SBYTES (BVAR (b, auto_save_file_name)), stream);
putc ('\n', stream);
fwrite_unlocked (SDATA (BVAR (b, filename)), 1,
SBYTES (BVAR (b, filename)), stream);
putc_unlocked ('\n', stream);
fwrite_unlocked (SDATA (BVAR (b, auto_save_file_name)), 1,
SBYTES (BVAR (b, auto_save_file_name)), stream);
putc_unlocked ('\n', stream);
unblock_input ();
}
@ -5841,7 +5839,7 @@ effect except for flushing STREAM's data. */)
binmode = NILP (mode) ? O_TEXT : O_BINARY;
if (fp != stdin)
fflush (fp);
fflush_unlocked (fp);
return (set_binary_mode (fileno (fp), binmode) == O_BINARY) ? Qt : Qnil;
}

View file

@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
/* Include this before including <setjmp.h> to work around bugs with
@ -41,6 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "buffer.h"
#include "dispextern.h"
#include "blockinput.h"
#include "sysstdio.h"
#include "systime.h"
#include <epaths.h>
#include "coding.h"
@ -2361,7 +2361,7 @@ slurp_file (int fd, ptrdiff_t *size)
This can happen if the file grows as we read it. */
ptrdiff_t buflen = st.st_size;
buf = xmalloc (buflen + 1);
if (fread (buf, 1, buflen + 1, fp) == buflen)
if (fread_unlocked (buf, 1, buflen + 1, fp) == buflen)
*size = buflen;
else
{
@ -5890,7 +5890,7 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
{
FILE *fp = png_get_io_ptr (png_ptr);
if (fread (data, 1, length, fp) < length)
if (fread_unlocked (data, 1, length, fp) < length)
png_error (png_ptr, "Read error");
}
@ -5959,7 +5959,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
}
/* Check PNG signature. */
if (fread (sig, 1, sizeof sig, fp) != sizeof sig
if (fread_unlocked (sig, 1, sizeof sig, fp) != sizeof sig
|| png_sig_cmp (sig, 0, sizeof sig))
{
fclose (fp);
@ -6598,7 +6598,8 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
{
ptrdiff_t bytes;
bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
bytes = fread_unlocked (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE,
src->file);
if (bytes > 0)
src->mgr.bytes_in_buffer = bytes;
else

View file

@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "intervals.h"
#include "keymap.h"
#include "blockinput.h"
#include "sysstdio.h"
#include "systime.h"
#include "atimer.h"
#include "process.h"
@ -3290,7 +3291,7 @@ record_char (Lisp_Object c)
if (INTEGERP (c))
{
if (XUINT (c) < 0x100)
putc (XUINT (c), dribble);
putc_unlocked (XUINT (c), dribble);
else
fprintf (dribble, " 0x%"pI"x", XUINT (c));
}
@ -3303,15 +3304,15 @@ record_char (Lisp_Object c)
if (SYMBOLP (dribblee))
{
putc ('<', dribble);
fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
SBYTES (SYMBOL_NAME (dribblee)),
dribble);
putc ('>', dribble);
putc_unlocked ('<', dribble);
fwrite_unlocked (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
SBYTES (SYMBOL_NAME (dribblee)),
dribble);
putc_unlocked ('>', dribble);
}
}
fflush (dribble);
fflush_unlocked (dribble);
unblock_input ();
}
}
@ -3769,7 +3770,7 @@ kbd_buffer_get_event (KBOARD **kbp,
detaching from the terminal. */
|| (IS_DAEMON && DAEMON_RUNNING))
{
int c = getchar ();
int c = getchar_unlocked ();
XSETINT (obj, c);
*kbp = current_kboard;
return obj;
@ -10377,7 +10378,7 @@ handle_interrupt (bool in_signal_handler)
sigemptyset (&blocked);
sigaddset (&blocked, SIGINT);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
fflush (stdout);
fflush_unlocked (stdout);
}
reset_all_sys_modes ();

View file

@ -72,10 +72,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define file_tell ftell
#endif
#ifndef HAVE_GETC_UNLOCKED
#define getc_unlocked getc
#endif
/* The objects or placeholders read with the #n=object form.
A hash table maps a number to either a placeholder (while the
@ -474,16 +470,15 @@ readbyte_from_file (int c, Lisp_Object readcharfun)
}
block_input ();
c = getc_unlocked (instream);
/* Interrupted reads have been observed while reading over the network. */
while (c == EOF && ferror (instream) && errno == EINTR)
while ((c = getc_unlocked (instream)) == EOF && errno == EINTR
&& ferror_unlocked (instream))
{
unblock_input ();
maybe_quit ();
block_input ();
clearerr (instream);
c = getc_unlocked (instream);
clearerr_unlocked (instream);
}
unblock_input ();

View file

@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <binary-io.h>
@ -31,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "frame.h"
#include "window.h"
#include "keymap.h"
#include "sysstdio.h"
#include "systty.h"
/* List of buffers for use as minibuffers.
@ -209,15 +209,15 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial,
suppress_echo_on_tty (STDIN_FILENO);
}
fwrite (SDATA (prompt), 1, SBYTES (prompt), stdout);
fflush (stdout);
fwrite_unlocked (SDATA (prompt), 1, SBYTES (prompt), stdout);
fflush_unlocked (stdout);
val = Qnil;
size = 100;
len = 0;
line = xmalloc (size);
while ((c = getchar ()) != '\n' && c != '\r')
while ((c = getchar_unlocked ()) != '\n' && c != '\r')
{
if (c == EOF)
{

View file

@ -228,7 +228,7 @@ printchar_to_stream (unsigned int ch, FILE *stream)
{
if (ASCII_CHAR_P (ch))
{
putc (ch, stream);
putc_unlocked (ch, stream);
#ifdef WINDOWSNT
/* Send the output to a debugger (nothing happens if there
isn't one). */
@ -246,7 +246,7 @@ printchar_to_stream (unsigned int ch, FILE *stream)
if (encode_p)
encoded_ch = code_convert_string_norecord (encoded_ch,
coding_system, true);
fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream);
fwrite_unlocked (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream);
#ifdef WINDOWSNT
if (print_output_debug_flag && stream == stderr)
OutputDebugString (SSDATA (encoded_ch));
@ -298,7 +298,7 @@ printchar (unsigned int ch, Lisp_Object fun)
if (DISP_TABLE_P (Vstandard_display_table))
printchar_to_stream (ch, stdout);
else
fwrite (str, 1, len, stdout);
fwrite_unlocked (str, 1, len, stdout);
noninteractive_need_newline = 1;
}
else
@ -350,7 +350,7 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
}
}
else
fwrite (ptr, 1, size_byte, stdout);
fwrite_unlocked (ptr, 1, size_byte, stdout);
noninteractive_need_newline = 1;
}
@ -801,7 +801,7 @@ append to existing target file. */)
report_file_error ("Cannot open debugging output stream", file);
}
fflush (stderr);
fflush_unlocked (stderr);
if (dup2 (fd, STDERR_FILENO) < 0)
report_file_error ("dup2", file);
if (fd != stderr_dup)

View file

@ -1408,7 +1408,7 @@ reset_sys_modes (struct tty_display_info *tty_out)
{
if (noninteractive)
{
fflush (stdout);
fflush_unlocked (stdout);
return;
}
if (!tty_out->term_initted)
@ -1428,17 +1428,14 @@ reset_sys_modes (struct tty_display_info *tty_out)
}
else
{ /* have to do it the hard way */
int i;
tty_turn_off_insert (tty_out);
for (i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++)
{
fputc (' ', tty_out->output);
}
for (int i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++)
fputc_unlocked (' ', tty_out->output);
}
cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
fflush (tty_out->output);
fflush_unlocked (tty_out->output);
if (tty_out->terminal->reset_terminal_modes_hook)
tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
@ -3079,7 +3076,7 @@ procfs_ttyname (int rdev)
char minor[25]; /* 2 32-bit numbers + dash */
char *endp;
for (; !feof (fdev) && !ferror (fdev); name[0] = 0)
for (; !feof_unlocked (fdev) && !ferror_unlocked (fdev); name[0] = 0)
{
if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
&& major == MAJOR (rdev))
@ -3129,7 +3126,7 @@ procfs_get_total_memory (void)
break;
case 0:
while ((c = getc (fmem)) != EOF && c != '\n')
while ((c = getc_unlocked (fmem)) != EOF && c != '\n')
continue;
done = c == EOF;
break;

View file

@ -33,4 +33,45 @@ extern FILE *emacs_fopen (char const *, char const *);
# define FOPEN_TEXT ""
#endif
/* These are compatible with unlocked-io.h, if both files are included. */
#if !HAVE_DECL_CLEARERR_UNLOCKED
# define clearerr_unlocked(x) clearerr (x)
#endif
#if !HAVE_DECL_FEOF_UNLOCKED
# define feof_unlocked(x) feof (x)
#endif
#if !HAVE_DECL_FERROR_UNLOCKED
# define ferror_unlocked(x) ferror (x)
#endif
#if !HAVE_DECL_FFLUSH_UNLOCKED
# define fflush_unlocked(x) fflush (x)
#endif
#if !HAVE_DECL_FGETS_UNLOCKED
# define fgets_unlocked(x,y,z) fgets (x,y,z)
#endif
#if !HAVE_DECL_FPUTC_UNLOCKED
# define fputc_unlocked(x,y) fputc (x,y)
#endif
#if !HAVE_DECL_FPUTS_UNLOCKED
# define fputs_unlocked(x,y) fputs (x,y)
#endif
#if !HAVE_DECL_FREAD_UNLOCKED
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
#endif
#if !HAVE_DECL_FWRITE_UNLOCKED
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
#endif
#if !HAVE_DECL_GETC_UNLOCKED
# define getc_unlocked(x) getc (x)
#endif
#if !HAVE_DECL_GETCHAR_UNLOCKED
# define getchar_unlocked() getchar ()
#endif
#if !HAVE_DECL_PUTC_UNLOCKED
# define putc_unlocked(x,y) putc (x,y)
#endif
#if !HAVE_DECL_PUTCHAR_UNLOCKED
# define putchar_unlocked(x) putchar (x)
#endif
#endif /* EMACS_SYSSTDIO_H */

View file

@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/time.h>
@ -45,6 +44,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "keymap.h"
#include "blockinput.h"
#include "syssignal.h"
#include "sysstdio.h"
#ifdef MSDOS
#include "msdos.h"
static int been_here = -1;
@ -146,7 +146,7 @@ tty_ring_bell (struct frame *f)
OUTPUT (tty, (tty->TS_visible_bell && visible_bell
? tty->TS_visible_bell
: tty->TS_bell));
fflush (tty->output);
fflush_unlocked (tty->output);
}
}
@ -167,9 +167,10 @@ tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
Lisp_Object string = XCAR (extra_codes);
if (STRINGP (string))
{
fwrite (SDATA (string), 1, SBYTES (string), tty->output);
fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->output);
if (tty->termscript)
fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
fwrite_unlocked (SDATA (string), 1, SBYTES (string),
tty->termscript);
}
}
}
@ -197,7 +198,7 @@ tty_set_terminal_modes (struct terminal *terminal)
OUTPUT_IF (tty, tty->TS_keypad_mode);
losecursor (tty);
tty_send_additional_strings (terminal, Qtty_mode_set_strings);
fflush (tty->output);
fflush_unlocked (tty->output);
}
}
@ -220,7 +221,7 @@ tty_reset_terminal_modes (struct terminal *terminal)
/* Output raw CR so kernel can track the cursor hpos. */
current_tty = tty;
cmputc ('\r');
fflush (tty->output);
fflush_unlocked (tty->output);
}
}
@ -235,7 +236,7 @@ tty_update_end (struct frame *f)
tty_show_cursor (tty);
tty_turn_off_insert (tty);
tty_background_highlight (tty);
fflush (tty->output);
fflush_unlocked (tty->output);
}
/* The implementation of set_terminal_window for termcap frames. */
@ -497,8 +498,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
for (i = curX (tty); i < first_unused_hpos; i++)
{
if (tty->termscript)
fputc (' ', tty->termscript);
fputc (' ', tty->output);
fputc_unlocked (' ', tty->termscript);
fputc_unlocked (' ', tty->output);
}
cmplus (tty, first_unused_hpos - curX (tty));
}
@ -771,11 +772,11 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
if (coding->produced > 0)
{
block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
clearerr_unlocked (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
fwrite_unlocked (conversion_buffer, 1, coding->produced,
tty->termscript);
unblock_input ();
}
string += n;
@ -832,11 +833,11 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
if (coding->produced > 0)
{
block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
clearerr_unlocked (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
fwrite_unlocked (conversion_buffer, 1, coding->produced,
tty->termscript);
unblock_input ();
}
@ -918,11 +919,11 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
if (coding->produced > 0)
{
block_input ();
fwrite (conversion_buffer, 1, coding->produced, tty->output);
if (ferror (tty->output))
clearerr (tty->output);
fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
clearerr_unlocked (tty->output);
if (tty->termscript)
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
fwrite_unlocked (conversion_buffer, 1, coding->produced,
tty->termscript);
unblock_input ();
}
@ -3327,7 +3328,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
which calls tty_show_cursor. Re-hide it, so it doesn't show
through the menus. */
tty_hide_cursor (tty);
fflush (tty->output);
fflush_unlocked (tty->output);
}
sf->mouse_moved = 0;
@ -3335,7 +3336,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
while (statecount--)
free_saved_screen (state[statecount].screen_behind);
tty_show_cursor (tty); /* Turn cursor back on. */
fflush (tty->output);
fflush_unlocked (tty->output);
/* Clean up any mouse events that are waiting inside Emacs event queue.
These events are likely to be generated before the menu was even

View file

@ -6232,7 +6232,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
int red, green, blue;
int num;
while (fgets (buf, sizeof (buf), fp) != NULL) {
while (fgets_unlocked (buf, sizeof (buf), fp) != NULL) {
if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3)
{
#ifdef HAVE_NTGUI