aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorPaul Eggert2025-07-13 12:52:43 -0700
committerPaul Eggert2025-07-13 21:09:40 -0700
commitc3f96d20eecdf0aa93f294a4f3fb96e16eec6a68 (patch)
tree73e54e7956a4d86bdb9418a5cad34562f61597cb /src/fileio.c
parent55f41ca3aa8fe487d10730708a7396137a2c9d18 (diff)
downloademacs-c3f96d20eecdf0aa93f294a4f3fb96e16eec6a68.tar.gz
emacs-c3f96d20eecdf0aa93f294a4f3fb96e16eec6a68.zip
Avoid some tiny /proc file reads
* src/fileio.c (union read_non_regular): New members buf and bufsize replace inserted and trytry. (read_non_regular): Adjust to this new, simpler interface. (Finsert_file_contents): If the gap is smaller than read_buf and we want to read more than the gap, read into read_buf first, to avoid lots of tiny reads from /proc files.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 2a53dbbdd07..075b9c590c8 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3906,7 +3906,8 @@ union read_non_regular
3906 struct 3906 struct
3907 { 3907 {
3908 emacs_fd fd; 3908 emacs_fd fd;
3909 ptrdiff_t inserted, trytry; 3909 char *buf;
3910 ptrdiff_t bufsize;
3910 } s; 3911 } s;
3911 GCALIGNED_UNION_MEMBER 3912 GCALIGNED_UNION_MEMBER
3912}; 3913};
@@ -3916,11 +3917,7 @@ static Lisp_Object
3916read_non_regular (Lisp_Object state) 3917read_non_regular (Lisp_Object state)
3917{ 3918{
3918 union read_non_regular *data = XFIXNUMPTR (state); 3919 union read_non_regular *data = XFIXNUMPTR (state);
3919 intmax_t nbytes 3920 intmax_t nbytes = emacs_fd_read (data->s.fd, data->s.buf, data->s.bufsize);
3920 = emacs_fd_read (data->s.fd,
3921 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
3922 + data->s.inserted),
3923 data->s.trytry);
3924 return make_int (nbytes < 0 ? -errno : nbytes); 3921 return make_int (nbytes < 0 ? -errno : nbytes);
3925} 3922}
3926 3923
@@ -4854,18 +4851,18 @@ by calling `format-decode', which see. */)
4854 4851
4855 while (inserted < total) 4852 while (inserted < total)
4856 { 4853 {
4857 ptrdiff_t this; 4854 char *buf;
4858 4855 ptrdiff_t bufsize, this;
4859 if (gap_size == 0) 4856 if (gap_size < total - inserted && gap_size < sizeof read_buf)
4860 { 4857 {
4861 /* The size estimate was wrong. Make the gap 50% larger. */ 4858 buf = read_buf;
4862 make_gap (GAP_SIZE >> 1); 4859 bufsize = sizeof read_buf;
4863 gap_size = GAP_SIZE - inserted; 4860 }
4861 else
4862 {
4863 buf = (char *) BEG_ADDR + PT_BYTE - BEG_BYTE + inserted;
4864 bufsize = min (min (gap_size, total - inserted), READ_BUF_SIZE);
4864 } 4865 }
4865
4866 /* 'try' is reserved in some compilers (Microsoft C). */
4867 ptrdiff_t trytry = min (gap_size,
4868 min (total - inserted, READ_BUF_SIZE));
4869 4866
4870 if (!seekable && end_offset == TYPE_MAXIMUM (off_t)) 4867 if (!seekable && end_offset == TYPE_MAXIMUM (off_t))
4871 { 4868 {
@@ -4875,7 +4872,7 @@ by calling `format-decode', which see. */)
4875 /* Read from the file, capturing `quit'. When an 4872 /* Read from the file, capturing `quit'. When an
4876 error occurs, end the loop, and arrange for a quit 4873 error occurs, end the loop, and arrange for a quit
4877 to be signaled after decoding the text we read. */ 4874 to be signaled after decoding the text we read. */
4878 union read_non_regular data = {{fd, inserted, trytry}}; 4875 union read_non_regular data = {{fd, buf, bufsize}};
4879 nbytes = internal_condition_case_1 4876 nbytes = internal_condition_case_1
4880 (read_non_regular, make_pointer_integer (&data), 4877 (read_non_regular, make_pointer_integer (&data),
4881 Qerror, read_non_regular_quit); 4878 Qerror, read_non_regular_quit);
@@ -4894,11 +4891,7 @@ by calling `format-decode', which see. */)
4894 part of the buffer until all the reading is done, so a 4891 part of the buffer until all the reading is done, so a
4895 C-g here doesn't do any harm. */ 4892 C-g here doesn't do any harm. */
4896 { 4893 {
4897 this = emacs_fd_read (fd, 4894 this = emacs_fd_read (fd, buf, bufsize); if (this < 0)
4898 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
4899 + inserted),
4900 trytry);
4901 if (this < 0)
4902 this = -errno; 4895 this = -errno;
4903 } 4896 }
4904 4897
@@ -4908,6 +4901,20 @@ by calling `format-decode', which see. */)
4908 break; 4901 break;
4909 } 4902 }
4910 4903
4904 if (buf == read_buf)
4905 {
4906 if (gap_size < this)
4907 {
4908 /* Size estimate was low. Make the gap at least 50% larger,
4909 and big enough so that the next loop iteration will
4910 use the gap directly instead of copying via read_buf. */
4911 make_gap (max (GAP_SIZE >> 1,
4912 this - gap_size + sizeof read_buf));
4913 gap_size = GAP_SIZE - inserted;
4914 }
4915 memcpy (BEG_ADDR + PT_BYTE - BEG_BYTE + inserted,
4916 read_buf, this);
4917 }
4911 gap_size -= this; 4918 gap_size -= this;
4912 inserted += this; 4919 inserted += this;
4913 } 4920 }