aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-06-22 11:21:20 -0700
committerPaul Eggert2017-06-22 11:22:53 -0700
commitf6ef15cf84c1288e972ef0e6165b97e34d6033b6 (patch)
tree7f3fcd101a6c1a02965ebe6fd8dbf070f8340f53 /src
parent18896f79136bb7d6d4c0c6b1d066b4e82644db6a (diff)
downloademacs-f6ef15cf84c1288e972ef0e6165b97e34d6033b6.tar.gz
emacs-f6ef15cf84c1288e972ef0e6165b97e34d6033b6.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/charset.c6
-rw-r--r--src/cm.c14
-rw-r--r--src/dispnew.c22
-rw-r--r--src/emacs.c8
-rw-r--r--src/fileio.c16
-rw-r--r--src/image.c11
-rw-r--r--src/keyboard.c19
-rw-r--r--src/lread.c11
-rw-r--r--src/minibuf.c8
-rw-r--r--src/print.c10
-rw-r--r--src/sysdep.c15
-rw-r--r--src/sysstdio.h41
-rw-r--r--src/term.c47
-rw-r--r--src/xfaces.c2
14 files changed, 130 insertions, 100 deletions
diff --git a/src/charset.c b/src/charset.c
index 9d15375dd79..d0840f7d2a9 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -29,7 +29,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29#include <config.h> 29#include <config.h>
30 30
31#include <errno.h> 31#include <errno.h>
32#include <stdio.h>
33#include <stdlib.h> 32#include <stdlib.h>
34#include <unistd.h> 33#include <unistd.h>
35#include <limits.h> 34#include <limits.h>
@@ -40,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40#include "charset.h" 39#include "charset.h"
41#include "coding.h" 40#include "coding.h"
42#include "buffer.h" 41#include "buffer.h"
42#include "sysstdio.h"
43 43
44/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) *** 44/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) ***
45 45
@@ -198,10 +198,6 @@ static struct
198 198
199#define GET_TEMP_CHARSET_WORK_DECODER(CODE) \ 199#define GET_TEMP_CHARSET_WORK_DECODER(CODE) \
200 (temp_charset_work->table.decoder[(CODE)]) 200 (temp_charset_work->table.decoder[(CODE)])
201
202#ifndef HAVE_GETC_UNLOCKED
203#define getc_unlocked getc
204#endif
205 201
206 202
207/* Set to 1 to warn that a charset map is loaded and thus a buffer 203/* Set to 1 to warn that a charset map is loaded and thus a buffer
diff --git a/src/cm.c b/src/cm.c
index efa50b0f58d..9a90f37445c 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -19,10 +19,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20 20
21#include <config.h> 21#include <config.h>
22#include <stdio.h>
23 22
24#include "lisp.h" 23#include "lisp.h"
25#include "cm.h" 24#include "cm.h"
25#include "sysstdio.h"
26#include "termchar.h" 26#include "termchar.h"
27#include "tparam.h" 27#include "tparam.h"
28 28
@@ -45,8 +45,8 @@ int
45cmputc (int c) 45cmputc (int c)
46{ 46{
47 if (current_tty->termscript) 47 if (current_tty->termscript)
48 putc (c & 0177, current_tty->termscript); 48 putc_unlocked (c & 0177, current_tty->termscript);
49 putc (c & 0177, current_tty->output); 49 putc_unlocked (c & 0177, current_tty->output);
50 return c; 50 return c;
51} 51}
52 52
@@ -117,11 +117,11 @@ cmcheckmagic (struct tty_display_info *tty)
117 if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1) 117 if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1)
118 emacs_abort (); 118 emacs_abort ();
119 if (tty->termscript) 119 if (tty->termscript)
120 putc ('\r', tty->termscript); 120 putc_unlocked ('\r', tty->termscript);
121 putc ('\r', tty->output); 121 putc_unlocked ('\r', tty->output);
122 if (tty->termscript) 122 if (tty->termscript)
123 putc ('\n', tty->termscript); 123 putc_unlocked ('\n', tty->termscript);
124 putc ('\n', tty->output); 124 putc_unlocked ('\n', tty->output);
125 curX (tty) = 0; 125 curX (tty) = 0;
126 curY (tty)++; 126 curY (tty)++;
127 } 127 }
diff --git a/src/dispnew.c b/src/dispnew.c
index 27c69bde831..925e44d9804 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3126,9 +3126,9 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
3126 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) 3126 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
3127 { 3127 {
3128 if (FRAME_TTY (f)->termscript) 3128 if (FRAME_TTY (f)->termscript)
3129 fflush (FRAME_TTY (f)->termscript); 3129 fflush_unlocked (FRAME_TTY (f)->termscript);
3130 if (FRAME_TERMCAP_P (f)) 3130 if (FRAME_TERMCAP_P (f))
3131 fflush (FRAME_TTY (f)->output); 3131 fflush_unlocked (FRAME_TTY (f)->output);
3132 } 3132 }
3133 3133
3134 /* Check window matrices for lost pointers. */ 3134 /* Check window matrices for lost pointers. */
@@ -3181,8 +3181,8 @@ update_frame_with_menu (struct frame *f, int row, int col)
3181 update_end (f); 3181 update_end (f);
3182 3182
3183 if (FRAME_TTY (f)->termscript) 3183 if (FRAME_TTY (f)->termscript)
3184 fflush (FRAME_TTY (f)->termscript); 3184 fflush_unlocked (FRAME_TTY (f)->termscript);
3185 fflush (FRAME_TTY (f)->output); 3185 fflush_unlocked (FRAME_TTY (f)->output);
3186 /* Check window matrices for lost pointers. */ 3186 /* Check window matrices for lost pointers. */
3187#if GLYPH_DEBUG 3187#if GLYPH_DEBUG
3188#if 0 3188#if 0
@@ -4531,7 +4531,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4531 ptrdiff_t outq = __fpending (display_output); 4531 ptrdiff_t outq = __fpending (display_output);
4532 if (outq > 900 4532 if (outq > 900
4533 || (outq > 20 && ((i - 1) % preempt_count == 0))) 4533 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4534 fflush (display_output); 4534 fflush_unlocked (display_output);
4535 } 4535 }
4536 } 4536 }
4537 4537
@@ -5615,13 +5615,13 @@ when TERMINAL is nil. */)
5615 5615
5616 if (tty->termscript) 5616 if (tty->termscript)
5617 { 5617 {
5618 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript); 5618 fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->termscript);
5619 fflush (tty->termscript); 5619 fflush_unlocked (tty->termscript);
5620 } 5620 }
5621 out = tty->output; 5621 out = tty->output;
5622 } 5622 }
5623 fwrite (SDATA (string), 1, SBYTES (string), out); 5623 fwrite_unlocked (SDATA (string), 1, SBYTES (string), out);
5624 fflush (out); 5624 fflush_unlocked (out);
5625 unblock_input (); 5625 unblock_input ();
5626 return Qnil; 5626 return Qnil;
5627} 5627}
@@ -5636,7 +5636,7 @@ terminate any keyboard macro currently executing. */)
5636 if (!NILP (arg)) 5636 if (!NILP (arg))
5637 { 5637 {
5638 if (noninteractive) 5638 if (noninteractive)
5639 putchar (07); 5639 putchar_unlocked (07);
5640 else 5640 else
5641 ring_bell (XFRAME (selected_frame)); 5641 ring_bell (XFRAME (selected_frame));
5642 } 5642 }
@@ -5650,7 +5650,7 @@ void
5650bitch_at_user (void) 5650bitch_at_user (void)
5651{ 5651{
5652 if (noninteractive) 5652 if (noninteractive)
5653 putchar (07); 5653 putchar_unlocked (07);
5654 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */ 5654 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
5655 { 5655 {
5656 const char *msg 5656 const char *msg
diff --git a/src/emacs.c b/src/emacs.c
index da8df1bf1c7..0fec7167588 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 23
24#include <errno.h> 24#include <errno.h>
25#include <fcntl.h> 25#include <fcntl.h>
26#include <stdio.h>
27#include <stdlib.h> 26#include <stdlib.h>
28 27
29#include <sys/file.h> 28#include <sys/file.h>
@@ -33,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
33 32
34#define MAIN_PROGRAM 33#define MAIN_PROGRAM
35#include "lisp.h" 34#include "lisp.h"
35#include "sysstdio.h"
36 36
37#ifdef WINDOWSNT 37#ifdef WINDOWSNT
38#include <fcntl.h> 38#include <fcntl.h>
@@ -885,7 +885,7 @@ main (int argc, char **argv)
885 } 885 }
886#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */ 886#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
887 887
888 clearerr (stdin); 888 clearerr_unlocked (stdin);
889 889
890 emacs_backtrace (-1); 890 emacs_backtrace (-1);
891 891
@@ -983,7 +983,7 @@ main (int argc, char **argv)
983 int i; 983 int i;
984 printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]); 984 printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
985 for (i = 0; i < ARRAYELTS (usage_message); i++) 985 for (i = 0; i < ARRAYELTS (usage_message); i++)
986 fputs (usage_message[i], stdout); 986 fputs_unlocked (usage_message[i], stdout);
987 exit (0); 987 exit (0);
988 } 988 }
989 989
@@ -2197,7 +2197,7 @@ You must run Emacs in batch mode in order to dump it. */)
2197 } 2197 }
2198#endif 2198#endif
2199 2199
2200 fflush (stdout); 2200 fflush_unlocked (stdout);
2201 /* Tell malloc where start of impure now is. */ 2201 /* Tell malloc where start of impure now is. */
2202 /* Also arrange for warnings when nearly out of space. */ 2202 /* Also arrange for warnings when nearly out of space. */
2203#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC 2203#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
diff --git a/src/fileio.c b/src/fileio.c
index cb070029a9b..a57d50b24e0 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5643,14 +5643,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5643 { 5643 {
5644 block_input (); 5644 block_input ();
5645 if (!NILP (BVAR (b, filename))) 5645 if (!NILP (BVAR (b, filename)))
5646 { 5646 fwrite_unlocked (SDATA (BVAR (b, filename)), 1,
5647 fwrite (SDATA (BVAR (b, filename)), 1, 5647 SBYTES (BVAR (b, filename)), stream);
5648 SBYTES (BVAR (b, filename)), stream); 5648 putc_unlocked ('\n', stream);
5649 } 5649 fwrite_unlocked (SDATA (BVAR (b, auto_save_file_name)), 1,
5650 putc ('\n', stream); 5650 SBYTES (BVAR (b, auto_save_file_name)), stream);
5651 fwrite (SDATA (BVAR (b, auto_save_file_name)), 1, 5651 putc_unlocked ('\n', stream);
5652 SBYTES (BVAR (b, auto_save_file_name)), stream);
5653 putc ('\n', stream);
5654 unblock_input (); 5652 unblock_input ();
5655 } 5653 }
5656 5654
@@ -5841,7 +5839,7 @@ effect except for flushing STREAM's data. */)
5841 5839
5842 binmode = NILP (mode) ? O_TEXT : O_BINARY; 5840 binmode = NILP (mode) ? O_TEXT : O_BINARY;
5843 if (fp != stdin) 5841 if (fp != stdin)
5844 fflush (fp); 5842 fflush_unlocked (fp);
5845 5843
5846 return (set_binary_mode (fileno (fp), binmode) == O_BINARY) ? Qt : Qnil; 5844 return (set_binary_mode (fileno (fp), binmode) == O_BINARY) ? Qt : Qnil;
5847} 5845}
diff --git a/src/image.c b/src/image.c
index aedec7954ee..07c4769e9e3 100644
--- a/src/image.c
+++ b/src/image.c
@@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20#include <config.h> 20#include <config.h>
21 21
22#include <fcntl.h> 22#include <fcntl.h>
23#include <stdio.h>
24#include <unistd.h> 23#include <unistd.h>
25 24
26/* Include this before including <setjmp.h> to work around bugs with 25/* 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/>. */
41#include "buffer.h" 40#include "buffer.h"
42#include "dispextern.h" 41#include "dispextern.h"
43#include "blockinput.h" 42#include "blockinput.h"
43#include "sysstdio.h"
44#include "systime.h" 44#include "systime.h"
45#include <epaths.h> 45#include <epaths.h>
46#include "coding.h" 46#include "coding.h"
@@ -2361,7 +2361,7 @@ slurp_file (int fd, ptrdiff_t *size)
2361 This can happen if the file grows as we read it. */ 2361 This can happen if the file grows as we read it. */
2362 ptrdiff_t buflen = st.st_size; 2362 ptrdiff_t buflen = st.st_size;
2363 buf = xmalloc (buflen + 1); 2363 buf = xmalloc (buflen + 1);
2364 if (fread (buf, 1, buflen + 1, fp) == buflen) 2364 if (fread_unlocked (buf, 1, buflen + 1, fp) == buflen)
2365 *size = buflen; 2365 *size = buflen;
2366 else 2366 else
2367 { 2367 {
@@ -5890,7 +5890,7 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
5890{ 5890{
5891 FILE *fp = png_get_io_ptr (png_ptr); 5891 FILE *fp = png_get_io_ptr (png_ptr);
5892 5892
5893 if (fread (data, 1, length, fp) < length) 5893 if (fread_unlocked (data, 1, length, fp) < length)
5894 png_error (png_ptr, "Read error"); 5894 png_error (png_ptr, "Read error");
5895} 5895}
5896 5896
@@ -5959,7 +5959,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5959 } 5959 }
5960 5960
5961 /* Check PNG signature. */ 5961 /* Check PNG signature. */
5962 if (fread (sig, 1, sizeof sig, fp) != sizeof sig 5962 if (fread_unlocked (sig, 1, sizeof sig, fp) != sizeof sig
5963 || png_sig_cmp (sig, 0, sizeof sig)) 5963 || png_sig_cmp (sig, 0, sizeof sig))
5964 { 5964 {
5965 fclose (fp); 5965 fclose (fp);
@@ -6598,7 +6598,8 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
6598 { 6598 {
6599 ptrdiff_t bytes; 6599 ptrdiff_t bytes;
6600 6600
6601 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file); 6601 bytes = fread_unlocked (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE,
6602 src->file);
6602 if (bytes > 0) 6603 if (bytes > 0)
6603 src->mgr.bytes_in_buffer = bytes; 6604 src->mgr.bytes_in_buffer = bytes;
6604 else 6605 else
diff --git a/src/keyboard.c b/src/keyboard.c
index 55486c6d9ab..3442b18409a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
39#include "intervals.h" 39#include "intervals.h"
40#include "keymap.h" 40#include "keymap.h"
41#include "blockinput.h" 41#include "blockinput.h"
42#include "sysstdio.h"
42#include "systime.h" 43#include "systime.h"
43#include "atimer.h" 44#include "atimer.h"
44#include "process.h" 45#include "process.h"
@@ -3290,7 +3291,7 @@ record_char (Lisp_Object c)
3290 if (INTEGERP (c)) 3291 if (INTEGERP (c))
3291 { 3292 {
3292 if (XUINT (c) < 0x100) 3293 if (XUINT (c) < 0x100)
3293 putc (XUINT (c), dribble); 3294 putc_unlocked (XUINT (c), dribble);
3294 else 3295 else
3295 fprintf (dribble, " 0x%"pI"x", XUINT (c)); 3296 fprintf (dribble, " 0x%"pI"x", XUINT (c));
3296 } 3297 }
@@ -3303,15 +3304,15 @@ record_char (Lisp_Object c)
3303 3304
3304 if (SYMBOLP (dribblee)) 3305 if (SYMBOLP (dribblee))
3305 { 3306 {
3306 putc ('<', dribble); 3307 putc_unlocked ('<', dribble);
3307 fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char), 3308 fwrite_unlocked (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3308 SBYTES (SYMBOL_NAME (dribblee)), 3309 SBYTES (SYMBOL_NAME (dribblee)),
3309 dribble); 3310 dribble);
3310 putc ('>', dribble); 3311 putc_unlocked ('>', dribble);
3311 } 3312 }
3312 } 3313 }
3313 3314
3314 fflush (dribble); 3315 fflush_unlocked (dribble);
3315 unblock_input (); 3316 unblock_input ();
3316 } 3317 }
3317} 3318}
@@ -3769,7 +3770,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3769 detaching from the terminal. */ 3770 detaching from the terminal. */
3770 || (IS_DAEMON && DAEMON_RUNNING)) 3771 || (IS_DAEMON && DAEMON_RUNNING))
3771 { 3772 {
3772 int c = getchar (); 3773 int c = getchar_unlocked ();
3773 XSETINT (obj, c); 3774 XSETINT (obj, c);
3774 *kbp = current_kboard; 3775 *kbp = current_kboard;
3775 return obj; 3776 return obj;
@@ -10377,7 +10378,7 @@ handle_interrupt (bool in_signal_handler)
10377 sigemptyset (&blocked); 10378 sigemptyset (&blocked);
10378 sigaddset (&blocked, SIGINT); 10379 sigaddset (&blocked, SIGINT);
10379 pthread_sigmask (SIG_BLOCK, &blocked, 0); 10380 pthread_sigmask (SIG_BLOCK, &blocked, 0);
10380 fflush (stdout); 10381 fflush_unlocked (stdout);
10381 } 10382 }
10382 10383
10383 reset_all_sys_modes (); 10384 reset_all_sys_modes ();
diff --git a/src/lread.c b/src/lread.c
index 8716b86e9bf..182f96223a5 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -72,10 +72,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
72#define file_tell ftell 72#define file_tell ftell
73#endif 73#endif
74 74
75#ifndef HAVE_GETC_UNLOCKED
76#define getc_unlocked getc
77#endif
78
79/* The objects or placeholders read with the #n=object form. 75/* The objects or placeholders read with the #n=object form.
80 76
81 A hash table maps a number to either a placeholder (while the 77 A hash table maps a number to either a placeholder (while the
@@ -474,16 +470,15 @@ readbyte_from_file (int c, Lisp_Object readcharfun)
474 } 470 }
475 471
476 block_input (); 472 block_input ();
477 c = getc_unlocked (instream);
478 473
479 /* Interrupted reads have been observed while reading over the network. */ 474 /* Interrupted reads have been observed while reading over the network. */
480 while (c == EOF && ferror (instream) && errno == EINTR) 475 while ((c = getc_unlocked (instream)) == EOF && errno == EINTR
476 && ferror_unlocked (instream))
481 { 477 {
482 unblock_input (); 478 unblock_input ();
483 maybe_quit (); 479 maybe_quit ();
484 block_input (); 480 block_input ();
485 clearerr (instream); 481 clearerr_unlocked (instream);
486 c = getc_unlocked (instream);
487 } 482 }
488 483
489 unblock_input (); 484 unblock_input ();
diff --git a/src/minibuf.c b/src/minibuf.c
index 1bbe276776e..835992fa79d 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22#include <errno.h> 22#include <errno.h>
23#include <stdio.h>
24 23
25#include <binary-io.h> 24#include <binary-io.h>
26 25
@@ -31,6 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31#include "frame.h" 30#include "frame.h"
32#include "window.h" 31#include "window.h"
33#include "keymap.h" 32#include "keymap.h"
33#include "sysstdio.h"
34#include "systty.h" 34#include "systty.h"
35 35
36/* List of buffers for use as minibuffers. 36/* List of buffers for use as minibuffers.
@@ -209,15 +209,15 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial,
209 suppress_echo_on_tty (STDIN_FILENO); 209 suppress_echo_on_tty (STDIN_FILENO);
210 } 210 }
211 211
212 fwrite (SDATA (prompt), 1, SBYTES (prompt), stdout); 212 fwrite_unlocked (SDATA (prompt), 1, SBYTES (prompt), stdout);
213 fflush (stdout); 213 fflush_unlocked (stdout);
214 214
215 val = Qnil; 215 val = Qnil;
216 size = 100; 216 size = 100;
217 len = 0; 217 len = 0;
218 line = xmalloc (size); 218 line = xmalloc (size);
219 219
220 while ((c = getchar ()) != '\n' && c != '\r') 220 while ((c = getchar_unlocked ()) != '\n' && c != '\r')
221 { 221 {
222 if (c == EOF) 222 if (c == EOF)
223 { 223 {
diff --git a/src/print.c b/src/print.c
index aaec5b04956..6bf8af9ef93 100644
--- a/src/print.c
+++ b/src/print.c
@@ -228,7 +228,7 @@ printchar_to_stream (unsigned int ch, FILE *stream)
228 { 228 {
229 if (ASCII_CHAR_P (ch)) 229 if (ASCII_CHAR_P (ch))
230 { 230 {
231 putc (ch, stream); 231 putc_unlocked (ch, stream);
232#ifdef WINDOWSNT 232#ifdef WINDOWSNT
233 /* Send the output to a debugger (nothing happens if there 233 /* Send the output to a debugger (nothing happens if there
234 isn't one). */ 234 isn't one). */
@@ -246,7 +246,7 @@ printchar_to_stream (unsigned int ch, FILE *stream)
246 if (encode_p) 246 if (encode_p)
247 encoded_ch = code_convert_string_norecord (encoded_ch, 247 encoded_ch = code_convert_string_norecord (encoded_ch,
248 coding_system, true); 248 coding_system, true);
249 fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream); 249 fwrite_unlocked (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream);
250#ifdef WINDOWSNT 250#ifdef WINDOWSNT
251 if (print_output_debug_flag && stream == stderr) 251 if (print_output_debug_flag && stream == stderr)
252 OutputDebugString (SSDATA (encoded_ch)); 252 OutputDebugString (SSDATA (encoded_ch));
@@ -298,7 +298,7 @@ printchar (unsigned int ch, Lisp_Object fun)
298 if (DISP_TABLE_P (Vstandard_display_table)) 298 if (DISP_TABLE_P (Vstandard_display_table))
299 printchar_to_stream (ch, stdout); 299 printchar_to_stream (ch, stdout);
300 else 300 else
301 fwrite (str, 1, len, stdout); 301 fwrite_unlocked (str, 1, len, stdout);
302 noninteractive_need_newline = 1; 302 noninteractive_need_newline = 1;
303 } 303 }
304 else 304 else
@@ -350,7 +350,7 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
350 } 350 }
351 } 351 }
352 else 352 else
353 fwrite (ptr, 1, size_byte, stdout); 353 fwrite_unlocked (ptr, 1, size_byte, stdout);
354 354
355 noninteractive_need_newline = 1; 355 noninteractive_need_newline = 1;
356 } 356 }
@@ -801,7 +801,7 @@ append to existing target file. */)
801 report_file_error ("Cannot open debugging output stream", file); 801 report_file_error ("Cannot open debugging output stream", file);
802 } 802 }
803 803
804 fflush (stderr); 804 fflush_unlocked (stderr);
805 if (dup2 (fd, STDERR_FILENO) < 0) 805 if (dup2 (fd, STDERR_FILENO) < 0)
806 report_file_error ("dup2", file); 806 report_file_error ("dup2", file);
807 if (fd != stderr_dup) 807 if (fd != stderr_dup)
diff --git a/src/sysdep.c b/src/sysdep.c
index 70f4a9dd7ea..b52236769e0 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1408,7 +1408,7 @@ reset_sys_modes (struct tty_display_info *tty_out)
1408{ 1408{
1409 if (noninteractive) 1409 if (noninteractive)
1410 { 1410 {
1411 fflush (stdout); 1411 fflush_unlocked (stdout);
1412 return; 1412 return;
1413 } 1413 }
1414 if (!tty_out->term_initted) 1414 if (!tty_out->term_initted)
@@ -1428,17 +1428,14 @@ reset_sys_modes (struct tty_display_info *tty_out)
1428 } 1428 }
1429 else 1429 else
1430 { /* have to do it the hard way */ 1430 { /* have to do it the hard way */
1431 int i;
1432 tty_turn_off_insert (tty_out); 1431 tty_turn_off_insert (tty_out);
1433 1432
1434 for (i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++) 1433 for (int i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++)
1435 { 1434 fputc_unlocked (' ', tty_out->output);
1436 fputc (' ', tty_out->output);
1437 }
1438 } 1435 }
1439 1436
1440 cmgoto (tty_out, FrameRows (tty_out) - 1, 0); 1437 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1441 fflush (tty_out->output); 1438 fflush_unlocked (tty_out->output);
1442 1439
1443 if (tty_out->terminal->reset_terminal_modes_hook) 1440 if (tty_out->terminal->reset_terminal_modes_hook)
1444 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal); 1441 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
@@ -3079,7 +3076,7 @@ procfs_ttyname (int rdev)
3079 char minor[25]; /* 2 32-bit numbers + dash */ 3076 char minor[25]; /* 2 32-bit numbers + dash */
3080 char *endp; 3077 char *endp;
3081 3078
3082 for (; !feof (fdev) && !ferror (fdev); name[0] = 0) 3079 for (; !feof_unlocked (fdev) && !ferror_unlocked (fdev); name[0] = 0)
3083 { 3080 {
3084 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 3081 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
3085 && major == MAJOR (rdev)) 3082 && major == MAJOR (rdev))
@@ -3129,7 +3126,7 @@ procfs_get_total_memory (void)
3129 break; 3126 break;
3130 3127
3131 case 0: 3128 case 0:
3132 while ((c = getc (fmem)) != EOF && c != '\n') 3129 while ((c = getc_unlocked (fmem)) != EOF && c != '\n')
3133 continue; 3130 continue;
3134 done = c == EOF; 3131 done = c == EOF;
3135 break; 3132 break;
diff --git a/src/sysstdio.h b/src/sysstdio.h
index 45ee33f5580..7fbcefcdad9 100644
--- a/src/sysstdio.h
+++ b/src/sysstdio.h
@@ -33,4 +33,45 @@ extern FILE *emacs_fopen (char const *, char const *);
33# define FOPEN_TEXT "" 33# define FOPEN_TEXT ""
34#endif 34#endif
35 35
36/* These are compatible with unlocked-io.h, if both files are included. */
37#if !HAVE_DECL_CLEARERR_UNLOCKED
38# define clearerr_unlocked(x) clearerr (x)
39#endif
40#if !HAVE_DECL_FEOF_UNLOCKED
41# define feof_unlocked(x) feof (x)
42#endif
43#if !HAVE_DECL_FERROR_UNLOCKED
44# define ferror_unlocked(x) ferror (x)
45#endif
46#if !HAVE_DECL_FFLUSH_UNLOCKED
47# define fflush_unlocked(x) fflush (x)
48#endif
49#if !HAVE_DECL_FGETS_UNLOCKED
50# define fgets_unlocked(x,y,z) fgets (x,y,z)
51#endif
52#if !HAVE_DECL_FPUTC_UNLOCKED
53# define fputc_unlocked(x,y) fputc (x,y)
54#endif
55#if !HAVE_DECL_FPUTS_UNLOCKED
56# define fputs_unlocked(x,y) fputs (x,y)
57#endif
58#if !HAVE_DECL_FREAD_UNLOCKED
59# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
60#endif
61#if !HAVE_DECL_FWRITE_UNLOCKED
62# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
63#endif
64#if !HAVE_DECL_GETC_UNLOCKED
65# define getc_unlocked(x) getc (x)
66#endif
67#if !HAVE_DECL_GETCHAR_UNLOCKED
68# define getchar_unlocked() getchar ()
69#endif
70#if !HAVE_DECL_PUTC_UNLOCKED
71# define putc_unlocked(x,y) putc (x,y)
72#endif
73#if !HAVE_DECL_PUTCHAR_UNLOCKED
74# define putchar_unlocked(x) putchar (x)
75#endif
76
36#endif /* EMACS_SYSSTDIO_H */ 77#endif /* EMACS_SYSSTDIO_H */
diff --git a/src/term.c b/src/term.c
index 8770aff8a92..3d7f4ada0b9 100644
--- a/src/term.c
+++ b/src/term.c
@@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <config.h> 22#include <config.h>
23#include <errno.h> 23#include <errno.h>
24#include <fcntl.h> 24#include <fcntl.h>
25#include <stdio.h>
26#include <stdlib.h> 25#include <stdlib.h>
27#include <sys/file.h> 26#include <sys/file.h>
28#include <sys/time.h> 27#include <sys/time.h>
@@ -45,6 +44,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45#include "keymap.h" 44#include "keymap.h"
46#include "blockinput.h" 45#include "blockinput.h"
47#include "syssignal.h" 46#include "syssignal.h"
47#include "sysstdio.h"
48#ifdef MSDOS 48#ifdef MSDOS
49#include "msdos.h" 49#include "msdos.h"
50static int been_here = -1; 50static int been_here = -1;
@@ -146,7 +146,7 @@ tty_ring_bell (struct frame *f)
146 OUTPUT (tty, (tty->TS_visible_bell && visible_bell 146 OUTPUT (tty, (tty->TS_visible_bell && visible_bell
147 ? tty->TS_visible_bell 147 ? tty->TS_visible_bell
148 : tty->TS_bell)); 148 : tty->TS_bell));
149 fflush (tty->output); 149 fflush_unlocked (tty->output);
150 } 150 }
151} 151}
152 152
@@ -167,9 +167,10 @@ tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
167 Lisp_Object string = XCAR (extra_codes); 167 Lisp_Object string = XCAR (extra_codes);
168 if (STRINGP (string)) 168 if (STRINGP (string))
169 { 169 {
170 fwrite (SDATA (string), 1, SBYTES (string), tty->output); 170 fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->output);
171 if (tty->termscript) 171 if (tty->termscript)
172 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript); 172 fwrite_unlocked (SDATA (string), 1, SBYTES (string),
173 tty->termscript);
173 } 174 }
174 } 175 }
175} 176}
@@ -197,7 +198,7 @@ tty_set_terminal_modes (struct terminal *terminal)
197 OUTPUT_IF (tty, tty->TS_keypad_mode); 198 OUTPUT_IF (tty, tty->TS_keypad_mode);
198 losecursor (tty); 199 losecursor (tty);
199 tty_send_additional_strings (terminal, Qtty_mode_set_strings); 200 tty_send_additional_strings (terminal, Qtty_mode_set_strings);
200 fflush (tty->output); 201 fflush_unlocked (tty->output);
201 } 202 }
202} 203}
203 204
@@ -220,7 +221,7 @@ tty_reset_terminal_modes (struct terminal *terminal)
220 /* Output raw CR so kernel can track the cursor hpos. */ 221 /* Output raw CR so kernel can track the cursor hpos. */
221 current_tty = tty; 222 current_tty = tty;
222 cmputc ('\r'); 223 cmputc ('\r');
223 fflush (tty->output); 224 fflush_unlocked (tty->output);
224 } 225 }
225} 226}
226 227
@@ -235,7 +236,7 @@ tty_update_end (struct frame *f)
235 tty_show_cursor (tty); 236 tty_show_cursor (tty);
236 tty_turn_off_insert (tty); 237 tty_turn_off_insert (tty);
237 tty_background_highlight (tty); 238 tty_background_highlight (tty);
238 fflush (tty->output); 239 fflush_unlocked (tty->output);
239} 240}
240 241
241/* The implementation of set_terminal_window for termcap frames. */ 242/* 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)
497 for (i = curX (tty); i < first_unused_hpos; i++) 498 for (i = curX (tty); i < first_unused_hpos; i++)
498 { 499 {
499 if (tty->termscript) 500 if (tty->termscript)
500 fputc (' ', tty->termscript); 501 fputc_unlocked (' ', tty->termscript);
501 fputc (' ', tty->output); 502 fputc_unlocked (' ', tty->output);
502 } 503 }
503 cmplus (tty, first_unused_hpos - curX (tty)); 504 cmplus (tty, first_unused_hpos - curX (tty));
504 } 505 }
@@ -771,11 +772,11 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
771 if (coding->produced > 0) 772 if (coding->produced > 0)
772 { 773 {
773 block_input (); 774 block_input ();
774 fwrite (conversion_buffer, 1, coding->produced, tty->output); 775 fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
775 if (ferror (tty->output)) 776 clearerr_unlocked (tty->output);
776 clearerr (tty->output);
777 if (tty->termscript) 777 if (tty->termscript)
778 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 778 fwrite_unlocked (conversion_buffer, 1, coding->produced,
779 tty->termscript);
779 unblock_input (); 780 unblock_input ();
780 } 781 }
781 string += n; 782 string += n;
@@ -832,11 +833,11 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
832 if (coding->produced > 0) 833 if (coding->produced > 0)
833 { 834 {
834 block_input (); 835 block_input ();
835 fwrite (conversion_buffer, 1, coding->produced, tty->output); 836 fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
836 if (ferror (tty->output)) 837 clearerr_unlocked (tty->output);
837 clearerr (tty->output);
838 if (tty->termscript) 838 if (tty->termscript)
839 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 839 fwrite_unlocked (conversion_buffer, 1, coding->produced,
840 tty->termscript);
840 unblock_input (); 841 unblock_input ();
841 } 842 }
842 843
@@ -918,11 +919,11 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
918 if (coding->produced > 0) 919 if (coding->produced > 0)
919 { 920 {
920 block_input (); 921 block_input ();
921 fwrite (conversion_buffer, 1, coding->produced, tty->output); 922 fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output);
922 if (ferror (tty->output)) 923 clearerr_unlocked (tty->output);
923 clearerr (tty->output);
924 if (tty->termscript) 924 if (tty->termscript)
925 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 925 fwrite_unlocked (conversion_buffer, 1, coding->produced,
926 tty->termscript);
926 unblock_input (); 927 unblock_input ();
927 } 928 }
928 929
@@ -3327,7 +3328,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3327 which calls tty_show_cursor. Re-hide it, so it doesn't show 3328 which calls tty_show_cursor. Re-hide it, so it doesn't show
3328 through the menus. */ 3329 through the menus. */
3329 tty_hide_cursor (tty); 3330 tty_hide_cursor (tty);
3330 fflush (tty->output); 3331 fflush_unlocked (tty->output);
3331 } 3332 }
3332 3333
3333 sf->mouse_moved = 0; 3334 sf->mouse_moved = 0;
@@ -3335,7 +3336,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3335 while (statecount--) 3336 while (statecount--)
3336 free_saved_screen (state[statecount].screen_behind); 3337 free_saved_screen (state[statecount].screen_behind);
3337 tty_show_cursor (tty); /* Turn cursor back on. */ 3338 tty_show_cursor (tty); /* Turn cursor back on. */
3338 fflush (tty->output); 3339 fflush_unlocked (tty->output);
3339 3340
3340/* Clean up any mouse events that are waiting inside Emacs event queue. 3341/* Clean up any mouse events that are waiting inside Emacs event queue.
3341 These events are likely to be generated before the menu was even 3342 These events are likely to be generated before the menu was even
diff --git a/src/xfaces.c b/src/xfaces.c
index 4714b7b3cb8..86bb9b0b496 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6232,7 +6232,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6232 int red, green, blue; 6232 int red, green, blue;
6233 int num; 6233 int num;
6234 6234
6235 while (fgets (buf, sizeof (buf), fp) != NULL) { 6235 while (fgets_unlocked (buf, sizeof (buf), fp) != NULL) {
6236 if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3) 6236 if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3)
6237 { 6237 {
6238#ifdef HAVE_NTGUI 6238#ifdef HAVE_NTGUI