* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
@ 2021-03-02 20:33 Pip Cet
2021-03-02 20:45 ` Pip Cet
` (2 more replies)
0 siblings, 3 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-02 20:33 UTC (permalink / raw)
To: 46881
Playing around with the WebAssembly port, I noticed that pdumper, in
creating the dump file, makes way too many syscalls: it uses
emacs_write(), not fwrite(), so these calls translate to actual
syscalls and context switches. On immature systems (or in special
circumstances like a device mounted synchronously), they might
actually cause a hardware write for each syscall, which would wear out
flash quickly and be generally wasteful.
I've looked into the problem, and it seems easy to solve and worth it
in terms of debuggability and performance.
Patch will be attached once this has a bug number.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-02 20:33 bug#46881: 28.0.50; pdumper dumping causes way too many syscalls Pip Cet
@ 2021-03-02 20:45 ` Pip Cet
2021-03-02 21:07 ` Alan Third
2021-03-03 5:51 ` Eli Zaretskii
2021-06-15 9:25 ` Mattias Engdegård
2021-06-16 14:13 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2 siblings, 2 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-02 20:45 UTC (permalink / raw)
To: 46881
[-- Attachment #1: Type: text/plain, Size: 757 bytes --]
On Tue, Mar 2, 2021 at 8:35 PM Pip Cet <pipcet@gmail.com> wrote:
> I've looked into the problem, and it seems easy to solve and worth it
> in terms of debuggability and performance.
Very rough benchmarks, but this seems to be clearly worth it:
Performance:
With patch:
real 0m3.861s
user 0m3.776s
sys 0m0.085s
Without patch:
real 0m7.001s
user 0m4.476s
sys 0m2.511s
Number of syscalls:
With patch: 415442
Without patch: 2028307
> Patch will be attached once this has a bug number.
And here's the patch. Testing would be very appreciated.
I'm unsure about the precise usage of dump_off vs ptrdiff_t here; I
don't think it matters, but suggestions, nitpicks, and comments, on
this or any other aspect, would be very appreciated.
Pip
[-- Attachment #2: 0001-Prepare-pdumper-dump-file-in-memory-write-it-in-one-.patch --]
[-- Type: text/x-patch, Size: 2733 bytes --]
From 92ee138852b34ede2f43dd7f93f310fc746bb3bf Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Tue, 2 Mar 2021 20:38:23 +0000
Subject: [PATCH] Prepare pdumper dump file in memory, write it in one go
(Bug#46881)
* src/pdumper.c (struct dump_context): Add buf, buf_size, max_offset fields.
(grow_buffer): New function.
(dump_write): Use memcpy, not an actual emacs_write.
(dump_seek): Keep track of maximum seen offset.
(Fdump_emacs_portable): Write out the file contents when done.
---
src/pdumper.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/pdumper.c b/src/pdumper.c
index 337742fda4ade..62ddad8ee5e34 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -473,6 +473,10 @@ dump_fingerprint (char const *label,
{
/* Header we'll write to the dump file when done. */
struct dump_header header;
+ /* Data that will be written to the dump file. */
+ void *buf;
+ ptrdiff_t buf_size;
+ ptrdiff_t max_offset;
Lisp_Object old_purify_flag;
Lisp_Object old_post_gc_hook;
@@ -581,6 +585,13 @@ dump_fingerprint (char const *label,
\f
/* Dump file creation */
+static void dump_grow_buffer (struct dump_context *ctx)
+{
+ ctx->buf = xrealloc (ctx->buf, ctx->buf_size = (ctx->buf_size ?
+ (ctx->buf_size * 2)
+ : 1024 * 1024));
+}
+
static dump_off dump_object (struct dump_context *ctx, Lisp_Object object);
static dump_off dump_object_for_offset (struct dump_context *ctx,
Lisp_Object object);
@@ -747,8 +758,9 @@ dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte)
eassert (nbyte == 0 || buf != NULL);
eassert (ctx->obj_offset == 0);
eassert (ctx->flags.dump_object_contents);
- if (emacs_write (ctx->fd, buf, nbyte) < nbyte)
- report_file_error ("Could not write to dump file", ctx->dump_filename);
+ while (ctx->offset + nbyte > ctx->buf_size)
+ dump_grow_buffer (ctx);
+ memcpy ((char *)ctx->buf + ctx->offset, buf, nbyte);
ctx->offset += nbyte;
}
@@ -828,6 +840,8 @@ dump_tailq_pop (struct dump_tailq *tailq)
static void
dump_seek (struct dump_context *ctx, dump_off offset)
{
+ if (ctx->max_offset < ctx->offset)
+ ctx->max_offset = ctx->offset;
eassert (ctx->obj_offset == 0);
if (lseek (ctx->fd, offset, SEEK_SET) < 0)
report_file_error ("Setting file position",
@@ -4159,6 +4173,8 @@ DEFUN ("dump-emacs-portable",
ctx->header.magic[0] = dump_magic[0];
dump_seek (ctx, 0);
dump_write (ctx, &ctx->header, sizeof (ctx->header));
+ if (emacs_write (ctx->fd, ctx->buf, ctx->max_offset) < ctx->max_offset)
+ report_file_error ("Could not write to dump file", ctx->dump_filename);
dump_off
header_bytes = header_end - header_start,
--
2.30.1
^ permalink raw reply related [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-02 20:45 ` Pip Cet
@ 2021-03-02 21:07 ` Alan Third
2021-03-03 7:10 ` Pip Cet
2021-03-03 5:51 ` Eli Zaretskii
1 sibling, 1 reply; 39+ messages in thread
From: Alan Third @ 2021-03-02 21:07 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881
On Tue, Mar 02, 2021 at 08:45:04PM +0000, Pip Cet wrote:
> On Tue, Mar 2, 2021 at 8:35 PM Pip Cet <pipcet@gmail.com> wrote:
> > I've looked into the problem, and it seems easy to solve and worth it
> > in terms of debuggability and performance.
>
> Very rough benchmarks, but this seems to be clearly worth it:
>
> Performance:
> With patch:
> real 0m3.861s
> user 0m3.776s
> sys 0m0.085s
>
> Without patch:
> real 0m7.001s
> user 0m4.476s
> sys 0m2.511s
>
> Number of syscalls:
> With patch: 415442
> Without patch: 2028307
My quick test on macOS by doing:
rm src/*.pdmp
time make
sees it going from ~26s without patch to ~10s with patch, so a
considerable improvement.
> > Patch will be attached once this has a bug number.
>
> And here's the patch. Testing would be very appreciated.
It appears to work fine here, but I don't know if there's anything
specific to test other than just running Emacs.
--
Alan Third
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-02 20:45 ` Pip Cet
2021-03-02 21:07 ` Alan Third
@ 2021-03-03 5:51 ` Eli Zaretskii
2021-03-03 7:35 ` Pip Cet
2021-03-04 22:26 ` Daniel Colascione
1 sibling, 2 replies; 39+ messages in thread
From: Eli Zaretskii @ 2021-03-03 5:51 UTC (permalink / raw)
To: Pip Cet, Daniel Colascione, Paul Eggert; +Cc: 46881
> From: Pip Cet <pipcet@gmail.com>
> Date: Tue, 2 Mar 2021 20:45:04 +0000
>
> On Tue, Mar 2, 2021 at 8:35 PM Pip Cet <pipcet@gmail.com> wrote:
> > I've looked into the problem, and it seems easy to solve and worth it
> > in terms of debuggability and performance.
>
> Very rough benchmarks, but this seems to be clearly worth it:
>
> Performance:
> With patch:
> real 0m3.861s
> user 0m3.776s
> sys 0m0.085s
>
> Without patch:
> real 0m7.001s
> user 0m4.476s
> sys 0m2.511s
>
> Number of syscalls:
> With patch: 415442
> Without patch: 2028307
>
> > Patch will be attached once this has a bug number.
>
> And here's the patch. Testing would be very appreciated.
>
> I'm unsure about the precise usage of dump_off vs ptrdiff_t here; I
> don't think it matters, but suggestions, nitpicks, and comments, on
> this or any other aspect, would be very appreciated.
> From 92ee138852b34ede2f43dd7f93f310fc746bb3bf Mon Sep 17 00:00:00 2001
> From: Pip Cet <pipcet@gmail.com>
> Date: Tue, 2 Mar 2021 20:38:23 +0000
> Subject: [PATCH] Prepare pdumper dump file in memory, write it in one go
> (Bug#46881)
>
> * src/pdumper.c (struct dump_context): Add buf, buf_size, max_offset fields.
> (grow_buffer): New function.
> (dump_write): Use memcpy, not an actual emacs_write.
> (dump_seek): Keep track of maximum seen offset.
> (Fdump_emacs_portable): Write out the file contents when done.
> ---
> src/pdumper.c | 20 ++++++++++++++++++--
> 1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/src/pdumper.c b/src/pdumper.c
> index 337742fda4ade..62ddad8ee5e34 100644
> --- a/src/pdumper.c
> +++ b/src/pdumper.c
> @@ -473,6 +473,10 @@ dump_fingerprint (char const *label,
> {
> /* Header we'll write to the dump file when done. */
> struct dump_header header;
> + /* Data that will be written to the dump file. */
> + void *buf;
> + ptrdiff_t buf_size;
> + ptrdiff_t max_offset;
>
> Lisp_Object old_purify_flag;
> Lisp_Object old_post_gc_hook;
> @@ -581,6 +585,13 @@ dump_fingerprint (char const *label,
> \f
> /* Dump file creation */
>
> +static void dump_grow_buffer (struct dump_context *ctx)
> +{
> + ctx->buf = xrealloc (ctx->buf, ctx->buf_size = (ctx->buf_size ?
> + (ctx->buf_size * 2)
> + : 1024 * 1024));
> +}
> +
> static dump_off dump_object (struct dump_context *ctx, Lisp_Object object);
> static dump_off dump_object_for_offset (struct dump_context *ctx,
> Lisp_Object object);
> @@ -747,8 +758,9 @@ dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte)
> eassert (nbyte == 0 || buf != NULL);
> eassert (ctx->obj_offset == 0);
> eassert (ctx->flags.dump_object_contents);
> - if (emacs_write (ctx->fd, buf, nbyte) < nbyte)
> - report_file_error ("Could not write to dump file", ctx->dump_filename);
> + while (ctx->offset + nbyte > ctx->buf_size)
> + dump_grow_buffer (ctx);
> + memcpy ((char *)ctx->buf + ctx->offset, buf, nbyte);
> ctx->offset += nbyte;
> }
>
> @@ -828,6 +840,8 @@ dump_tailq_pop (struct dump_tailq *tailq)
> static void
> dump_seek (struct dump_context *ctx, dump_off offset)
> {
> + if (ctx->max_offset < ctx->offset)
> + ctx->max_offset = ctx->offset;
> eassert (ctx->obj_offset == 0);
> if (lseek (ctx->fd, offset, SEEK_SET) < 0)
> report_file_error ("Setting file position",
> @@ -4159,6 +4173,8 @@ DEFUN ("dump-emacs-portable",
> ctx->header.magic[0] = dump_magic[0];
> dump_seek (ctx, 0);
> dump_write (ctx, &ctx->header, sizeof (ctx->header));
> + if (emacs_write (ctx->fd, ctx->buf, ctx->max_offset) < ctx->max_offset)
> + report_file_error ("Could not write to dump file", ctx->dump_filename);
>
> dump_off
> header_bytes = header_end - header_start,
> --
> 2.30.1
Thanks.
Daniel, Paul: any comments? In particular, is it safe to allocate
large amounts of memory off the heap while dumping? A couple of
places in pdumper.c says some parts of code should call malloc.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-02 21:07 ` Alan Third
@ 2021-03-03 7:10 ` Pip Cet
2021-03-03 19:57 ` Alan Third
0 siblings, 1 reply; 39+ messages in thread
From: Pip Cet @ 2021-03-03 7:10 UTC (permalink / raw)
To: Alan Third, Pip Cet; +Cc: 46881
> My quick test on macOS by doing:
>
> rm src/*.pdmp
> time make
>
> sees it going from ~26s without patch to ~10s with patch, so a
> considerable improvement.
Thanks for testing!
> > > Patch will be attached once this has a bug number.
> >
> > And here's the patch. Testing would be very appreciated.
>
> It appears to work fine here, but I don't know if there's anything
> specific to test other than just running Emacs.
I suspect there may be problems on systems with very little memory. Do
you have an easy way to determine maximum resident size (on Debian
GNU/Linux, /bin/time works)? It would be interesting to see if that's
actually different.
Thanks again!
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-03 5:51 ` Eli Zaretskii
@ 2021-03-03 7:35 ` Pip Cet
2021-03-03 15:09 ` Lars Ingebrigtsen
2021-03-03 19:35 ` Paul Eggert
2021-03-04 22:26 ` Daniel Colascione
1 sibling, 2 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-03 7:35 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, Paul Eggert
[-- Attachment #1: Type: text/plain, Size: 1208 bytes --]
On Wed, Mar 3, 2021 at 5:51 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Tue, 2 Mar 2021 20:45:04 +0000
> >
> > On Tue, Mar 2, 2021 at 8:35 PM Pip Cet <pipcet@gmail.com> wrote:
> > > I've looked into the problem, and it seems easy to solve and worth it
> > > in terms of debuggability and performance.
Since debuggability is such a concern, we probably shouldn't leak the
buffer memory. Revised patch attached. (This patch also removes the
lseek() syscalls; while not quite as numerous as the read() ones,
those did clutter up straces here).
> In particular, is it safe to allocate
> large amounts of memory off the heap while dumping?
Even if it isn't, we'd still be faster re-running the dump after
growing the dumper image than the current approach is.
>A couple of
> places in pdumper.c says some parts of code should call malloc.
IIUC, the prohibition on calling malloc, if it is still a concern,
applies only when loading the dump, not while writing it.
My main concern is the possibility of a partly-written dump file,
since we no longer turn "!UMPEDGNUEMACS" into "DUMPEDGNUEMACS" after
the dump. Maybe it would make sense to restore that feature?
Pip
[-- Attachment #2: 0001-Prepare-pdumper-dump-file-in-memory-write-it-in-one-.patch --]
[-- Type: text/x-patch, Size: 2932 bytes --]
From fae67c02955a5bbea16d554b8e735dc8bef6a9e2 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Tue, 2 Mar 2021 20:38:23 +0000
Subject: [PATCH] Prepare pdumper dump file in memory, write it in one go
(Bug#46881)
* src/pdumper.c (struct dump_context): Add buf, buf_size, max_offset fields.
(dump_grow_buffer): New function.
(dump_write): Use memcpy, not an actual emacs_write.
(dump_seek): Keep track of maximum seen offset. Don't actually seek.
(Fdump_emacs_portable): Write out the file contents when done.
---
src/pdumper.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/pdumper.c b/src/pdumper.c
index 337742fda4ade..29d1cb862e07f 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -473,6 +473,10 @@ dump_fingerprint (char const *label,
{
/* Header we'll write to the dump file when done. */
struct dump_header header;
+ /* Data that will be written to the dump file. */
+ void *buf;
+ dump_off buf_size;
+ dump_off max_offset;
Lisp_Object old_purify_flag;
Lisp_Object old_post_gc_hook;
@@ -581,6 +585,13 @@ dump_fingerprint (char const *label,
\f
/* Dump file creation */
+static void dump_grow_buffer (struct dump_context *ctx)
+{
+ ctx->buf = xrealloc (ctx->buf, ctx->buf_size = (ctx->buf_size ?
+ (ctx->buf_size * 2)
+ : 8 * 1024 * 1024));
+}
+
static dump_off dump_object (struct dump_context *ctx, Lisp_Object object);
static dump_off dump_object_for_offset (struct dump_context *ctx,
Lisp_Object object);
@@ -747,8 +758,9 @@ dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte)
eassert (nbyte == 0 || buf != NULL);
eassert (ctx->obj_offset == 0);
eassert (ctx->flags.dump_object_contents);
- if (emacs_write (ctx->fd, buf, nbyte) < nbyte)
- report_file_error ("Could not write to dump file", ctx->dump_filename);
+ while (ctx->offset + nbyte > ctx->buf_size)
+ dump_grow_buffer (ctx);
+ memcpy ((char *)ctx->buf + ctx->offset, buf, nbyte);
ctx->offset += nbyte;
}
@@ -828,10 +840,9 @@ dump_tailq_pop (struct dump_tailq *tailq)
static void
dump_seek (struct dump_context *ctx, dump_off offset)
{
+ if (ctx->max_offset < ctx->offset)
+ ctx->max_offset = ctx->offset;
eassert (ctx->obj_offset == 0);
- if (lseek (ctx->fd, offset, SEEK_SET) < 0)
- report_file_error ("Setting file position",
- ctx->dump_filename);
ctx->offset = offset;
}
@@ -4159,6 +4170,12 @@ DEFUN ("dump-emacs-portable",
ctx->header.magic[0] = dump_magic[0];
dump_seek (ctx, 0);
dump_write (ctx, &ctx->header, sizeof (ctx->header));
+ if (emacs_write (ctx->fd, ctx->buf, ctx->max_offset) < ctx->max_offset)
+ report_file_error ("Could not write to dump file", ctx->dump_filename);
+ xfree (ctx->buf);
+ ctx->buf = NULL;
+ ctx->buf_size = 0;
+ ctx->max_offset = 0;
dump_off
header_bytes = header_end - header_start,
--
2.30.1
^ permalink raw reply related [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-03 7:35 ` Pip Cet
@ 2021-03-03 15:09 ` Lars Ingebrigtsen
2021-03-03 19:35 ` Paul Eggert
1 sibling, 0 replies; 39+ messages in thread
From: Lars Ingebrigtsen @ 2021-03-03 15:09 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, Paul Eggert
Pip Cet <pipcet@gmail.com> writes:
> Since debuggability is such a concern, we probably shouldn't leak the
> buffer memory. Revised patch attached. (This patch also removes the
> lseek() syscalls; while not quite as numerous as the read() ones,
> those did clutter up straces here).
I've tried the patch on a couple of systems here, and the resulting
Emacs works fine (as expected), and the pdumping is significantly faster
here, too.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-03 7:35 ` Pip Cet
2021-03-03 15:09 ` Lars Ingebrigtsen
@ 2021-03-03 19:35 ` Paul Eggert
1 sibling, 0 replies; 39+ messages in thread
From: Paul Eggert @ 2021-03-03 19:35 UTC (permalink / raw)
To: Pip Cet, Eli Zaretskii; +Cc: 46881
On 3/2/21 11:35 PM, Pip Cet wrote:
> IIUC, the prohibition on calling malloc, if it is still a concern,
> applies only when loading the dump, not while writing it.
That's my understanding as well.
> My main concern is the possibility of a partly-written dump file,
> since we no longer turn "!UMPEDGNUEMACS" into "DUMPEDGNUEMACS" after
> the dump. Maybe it would make sense to restore that feature?
Wouldn't hurt, though I'd make it low priority.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-03 7:10 ` Pip Cet
@ 2021-03-03 19:57 ` Alan Third
2021-03-04 7:25 ` Pip Cet
0 siblings, 1 reply; 39+ messages in thread
From: Alan Third @ 2021-03-03 19:57 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881
On Wed, Mar 03, 2021 at 07:10:28AM +0000, Pip Cet wrote:
> > My quick test on macOS by doing:
> >
> > rm src/*.pdmp
> > time make
> >
> > sees it going from ~26s without patch to ~10s with patch, so a
> > considerable improvement.
>
> Thanks for testing!
>
> > > > Patch will be attached once this has a bug number.
> > >
> > > And here's the patch. Testing would be very appreciated.
> >
> > It appears to work fine here, but I don't know if there's anything
> > specific to test other than just running Emacs.
>
> I suspect there may be problems on systems with very little memory. Do
> you have an easy way to determine maximum resident size (on Debian
> GNU/Linux, /bin/time works)? It would be interesting to see if that's
> actually different.
I tried using time -l the same as above and both came out with
roughly the same values, but I suspect that's probably just me getting
the values for running make.
Is there a better way of testing dumping?
--
Alan Third
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-03 19:57 ` Alan Third
@ 2021-03-04 7:25 ` Pip Cet
0 siblings, 0 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-04 7:25 UTC (permalink / raw)
To: Alan Third, Pip Cet, 46881
On Wed, Mar 3, 2021 at 7:58 PM Alan Third <alan@idiocy.org> wrote:
> On Wed, Mar 03, 2021 at 07:10:28AM +0000, Pip Cet wrote:
> > > My quick test on macOS by doing:
> > >
> > > rm src/*.pdmp
> > > time make
> > >
> > > sees it going from ~26s without patch to ~10s with patch, so a
> > > considerable improvement.
> >
> > Thanks for testing!
> >
> > > > > Patch will be attached once this has a bug number.
> > > >
> > > > And here's the patch. Testing would be very appreciated.
> > >
> > > It appears to work fine here, but I don't know if there's anything
> > > specific to test other than just running Emacs.
> >
> > I suspect there may be problems on systems with very little memory. Do
> > you have an easy way to determine maximum resident size (on Debian
> > GNU/Linux, /bin/time works)? It would be interesting to see if that's
> > actually different.
>
> I tried using time -l the same as above and both came out with
> roughly the same values, but I suspect that's probably just me getting
> the values for running make.
Thanks.
> Is there a better way of testing dumping?
I guess you could run "time ./temacs --batch -l loadup
--temacs=pbootstrap" directly (in src/)...
I realize that's not an answer to your question, but IME, dumping bugs
will often lead to immediate failures to bootstrap, whereas GC bugs
are tricky and don't. Since this bug doesn't affect GC in any way, I
think we've done enough initial testing.
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-03 5:51 ` Eli Zaretskii
2021-03-03 7:35 ` Pip Cet
@ 2021-03-04 22:26 ` Daniel Colascione
2021-03-05 2:30 ` Pip Cet
1 sibling, 1 reply; 39+ messages in thread
From: Daniel Colascione @ 2021-03-04 22:26 UTC (permalink / raw)
To: Eli Zaretskii, Pip Cet, Paul Eggert; +Cc: 46881
On 3/3/21 12:51 AM, Eli Zaretskii wrote:
>> From: Pip Cet <pipcet@gmail.com>
>> Date: Tue, 2 Mar 2021 20:45:04 +0000
>>
>> On Tue, Mar 2, 2021 at 8:35 PM Pip Cet <pipcet@gmail.com> wrote:
>>> I've looked into the problem, and it seems easy to solve and worth it
>>> in terms of debuggability and performance.
>> Very rough benchmarks, but this seems to be clearly worth it:
>>
>> Performance:
>> With patch:
>> real 0m3.861s
>> user 0m3.776s
>> sys 0m0.085s
>>
>> Without patch:
>> real 0m7.001s
>> user 0m4.476s
>> sys 0m2.511s
>>
>> Number of syscalls:
>> With patch: 415442
>> Without patch: 2028307
>>
>>> Patch will be attached once this has a bug number.
>> And here's the patch. Testing would be very appreciated.
>>
>> I'm unsure about the precise usage of dump_off vs ptrdiff_t here; I
>> don't think it matters, but suggestions, nitpicks, and comments, on
>> this or any other aspect, would be very appreciated.
>> From 92ee138852b34ede2f43dd7f93f310fc746bb3bf Mon Sep 17 00:00:00 2001
>> From: Pip Cet <pipcet@gmail.com>
>> Date: Tue, 2 Mar 2021 20:38:23 +0000
>> Subject: [PATCH] Prepare pdumper dump file in memory, write it in one go
>> (Bug#46881)
>>
>> * src/pdumper.c (struct dump_context): Add buf, buf_size, max_offset fields.
>> (grow_buffer): New function.
>> (dump_write): Use memcpy, not an actual emacs_write.
>> (dump_seek): Keep track of maximum seen offset.
>> (Fdump_emacs_portable): Write out the file contents when done.
>> ---
>> src/pdumper.c | 20 ++++++++++++++++++--
>> 1 file changed, 18 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/pdumper.c b/src/pdumper.c
>> index 337742fda4ade..62ddad8ee5e34 100644
>> --- a/src/pdumper.c
>> +++ b/src/pdumper.c
>> @@ -473,6 +473,10 @@ dump_fingerprint (char const *label,
>> {
>> /* Header we'll write to the dump file when done. */
>> struct dump_header header;
>> + /* Data that will be written to the dump file. */
>> + void *buf;
>> + ptrdiff_t buf_size;
>> + ptrdiff_t max_offset;
>>
>> Lisp_Object old_purify_flag;
>> Lisp_Object old_post_gc_hook;
>> @@ -581,6 +585,13 @@ dump_fingerprint (char const *label,
>> \f
>> /* Dump file creation */
>>
>> +static void dump_grow_buffer (struct dump_context *ctx)
>> +{
>> + ctx->buf = xrealloc (ctx->buf, ctx->buf_size = (ctx->buf_size ?
>> + (ctx->buf_size * 2)
>> + : 1024 * 1024));
>> +}
>> +
>> static dump_off dump_object (struct dump_context *ctx, Lisp_Object object);
>> static dump_off dump_object_for_offset (struct dump_context *ctx,
>> Lisp_Object object);
>> @@ -747,8 +758,9 @@ dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte)
>> eassert (nbyte == 0 || buf != NULL);
>> eassert (ctx->obj_offset == 0);
>> eassert (ctx->flags.dump_object_contents);
>> - if (emacs_write (ctx->fd, buf, nbyte) < nbyte)
>> - report_file_error ("Could not write to dump file", ctx->dump_filename);
>> + while (ctx->offset + nbyte > ctx->buf_size)
>> + dump_grow_buffer (ctx);
>> + memcpy ((char *)ctx->buf + ctx->offset, buf, nbyte);
>> ctx->offset += nbyte;
>> }
>>
>> @@ -828,6 +840,8 @@ dump_tailq_pop (struct dump_tailq *tailq)
>> static void
>> dump_seek (struct dump_context *ctx, dump_off offset)
>> {
>> + if (ctx->max_offset < ctx->offset)
>> + ctx->max_offset = ctx->offset;
>> eassert (ctx->obj_offset == 0);
>> if (lseek (ctx->fd, offset, SEEK_SET) < 0)
>> report_file_error ("Setting file position",
>> @@ -4159,6 +4173,8 @@ DEFUN ("dump-emacs-portable",
>> ctx->header.magic[0] = dump_magic[0];
>> dump_seek (ctx, 0);
>> dump_write (ctx, &ctx->header, sizeof (ctx->header));
>> + if (emacs_write (ctx->fd, ctx->buf, ctx->max_offset) < ctx->max_offset)
>> + report_file_error ("Could not write to dump file", ctx->dump_filename);
>>
>> dump_off
>> header_bytes = header_end - header_start,
>> --
>> 2.30.1
> Thanks.
>
> Daniel, Paul: any comments? In particular, is it safe to allocate
> large amounts of memory off the heap while dumping? A couple of
> places in pdumper.c says some parts of code should call malloc.
It looks fine, but wouldn't dumping to a FILE* (with internal buffering)
do the same basic thing in a simpler way? There aren't any particular
constraints on the environment _during_ the dump: we even make new lisp
objects. It's when loading the dump, early in initialization, that you
have to be careful.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-04 22:26 ` Daniel Colascione
@ 2021-03-05 2:30 ` Pip Cet
2021-03-05 7:19 ` Eli Zaretskii
0 siblings, 1 reply; 39+ messages in thread
From: Pip Cet @ 2021-03-05 2:30 UTC (permalink / raw)
To: Daniel Colascione; +Cc: 46881, Paul Eggert
On Thu, Mar 4, 2021 at 10:26 PM Daniel Colascione <dancol@dancol.org> wrote:
> On 3/3/21 12:51 AM, Eli Zaretskii wrote:
> > Daniel, Paul: any comments? In particular, is it safe to allocate
> > large amounts of memory off the heap while dumping? A couple of
> > places in pdumper.c says some parts of code should call malloc.
>
> It looks fine, but wouldn't dumping to a FILE* (with internal buffering)
> do the same basic thing in a simpler way?
I initially set out to do that, but decided against it. We don't just
write sequentially (when FILE I/O helps, a little), we also have the
seek-and-fixup phase, and it didn't seem any simpler at that point..
> There aren't any particular
> constraints on the environment _during_ the dump: we even make new lisp
> objects. It's when loading the dump, early in initialization, that you
> have to be careful.
Thanks!
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 2:30 ` Pip Cet
@ 2021-03-05 7:19 ` Eli Zaretskii
2021-03-05 7:38 ` Pip Cet
0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2021-03-05 7:19 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, eggert
> From: Pip Cet <pipcet@gmail.com>
> Date: Fri, 5 Mar 2021 02:30:13 +0000
> Cc: Eli Zaretskii <eliz@gnu.org>, Paul Eggert <eggert@cs.ucla.edu>, 46881@debbugs.gnu.org
>
> > It looks fine, but wouldn't dumping to a FILE* (with internal buffering)
> > do the same basic thing in a simpler way?
>
> I initially set out to do that, but decided against it. We don't just
> write sequentially (when FILE I/O helps, a little), we also have the
> seek-and-fixup phase, and it didn't seem any simpler at that point..
I'm not sure I understand: what's wrong with fseek?
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 7:19 ` Eli Zaretskii
@ 2021-03-05 7:38 ` Pip Cet
2021-03-05 7:54 ` Eli Zaretskii
2021-03-05 9:35 ` Andreas Schwab
0 siblings, 2 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-05 7:38 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, eggert
On Fri, Mar 5, 2021 at 7:19 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Fri, 5 Mar 2021 02:30:13 +0000
> > Cc: Eli Zaretskii <eliz@gnu.org>, Paul Eggert <eggert@cs.ucla.edu>, 46881@debbugs.gnu.org
> >
> > > It looks fine, but wouldn't dumping to a FILE* (with internal buffering)
> > > do the same basic thing in a simpler way?
> >
> > I initially set out to do that, but decided against it. We don't just
> > write sequentially (when FILE I/O helps, a little), we also have the
> > seek-and-fixup phase, and it didn't seem any simpler at that point..
>
> I'm not sure I understand: what's wrong with fseek?
Nothing, assuming you're fine with the current performance. Many libcs
aren't going to be smart enough to avoid I/O when you fseek through a
"large" file and write a word here and there, and my suspicion is that
would include glibc.
Also, we're not currently using fseek-and-write anywhere in Emacs.
We're talking about a file which Emacs is going to have to keep in
memory anyway, when reading the dump. The only case in which there
might be a problem is if the build machine has significantly less
available memory than the machine we intend to run on, and I just
don't think that's going to happen.
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 7:38 ` Pip Cet
@ 2021-03-05 7:54 ` Eli Zaretskii
2021-03-05 9:54 ` Pip Cet
2021-03-05 9:35 ` Andreas Schwab
1 sibling, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2021-03-05 7:54 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, eggert
> From: Pip Cet <pipcet@gmail.com>
> Date: Fri, 5 Mar 2021 07:38:27 +0000
> Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, 46881@debbugs.gnu.org
>
> > I'm not sure I understand: what's wrong with fseek?
>
> Nothing, assuming you're fine with the current performance. Many libcs
> aren't going to be smart enough to avoid I/O when you fseek through a
> "large" file and write a word here and there, and my suspicion is that
> would include glibc.
Could we benchmark the two implementations instead of acting on
suspicions?
In general, I'd prefer not to reinvent the wheel, and trust modern
libc's that they are efficient enough in handling buffered streams,
unless we have hard evidence to the contrary. If nothing else, it
would prevent people asking, like Daniel did, why didn't we use stdio
in the first place.
> Also, we're not currently using fseek-and-write anywhere in Emacs.
I don't see why this would be important. Since we open the file in
binary mode, fseek should work correctly even on non-Posix systems.
Am I missing something?
> We're talking about a file which Emacs is going to have to keep in
> memory anyway, when reading the dump. The only case in which there
> might be a problem is if the build machine has significantly less
> available memory than the machine we intend to run on, and I just
> don't think that's going to happen.
You are thinking about memory consumption, while I am thinking how to
avoid implementing our own private buffered streams.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 7:38 ` Pip Cet
2021-03-05 7:54 ` Eli Zaretskii
@ 2021-03-05 9:35 ` Andreas Schwab
2021-03-05 9:41 ` Pip Cet
1 sibling, 1 reply; 39+ messages in thread
From: Andreas Schwab @ 2021-03-05 9:35 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, eggert
On Mär 05 2021, Pip Cet wrote:
> We're talking about a file which Emacs is going to have to keep in
> memory anyway, when reading the dump.
While reading the dump, you only have the data once, and you don't have
to realloc the whole data.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 9:35 ` Andreas Schwab
@ 2021-03-05 9:41 ` Pip Cet
0 siblings, 0 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-05 9:41 UTC (permalink / raw)
To: Andreas Schwab; +Cc: 46881, eggert
On Fri, Mar 5, 2021 at 9:35 AM Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Mär 05 2021, Pip Cet wrote:
>
> > We're talking about a file which Emacs is going to have to keep in
> > memory anyway, when reading the dump.
>
> While reading the dump, you only have the data once, and you don't have
> to realloc the whole data.
Correct. I think a build memory usage of 28 MB for a 10 MB dump file
is something we can live with...
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 7:54 ` Eli Zaretskii
@ 2021-03-05 9:54 ` Pip Cet
2021-03-05 10:23 ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-03-05 12:06 ` Eli Zaretskii
0 siblings, 2 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-05 9:54 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, eggert
On Fri, Mar 5, 2021 at 7:55 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Fri, 5 Mar 2021 07:38:27 +0000
> > Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, 46881@debbugs.gnu.org
> >
> > > I'm not sure I understand: what's wrong with fseek?
> >
> > Nothing, assuming you're fine with the current performance. Many libcs
> > aren't going to be smart enough to avoid I/O when you fseek through a
> > "large" file and write a word here and there, and my suspicion is that
> > would include glibc.
>
> Could we benchmark the two implementations instead of acting on
> suspicions?
Sure.
My patch:
real 0m1.988s
user 0m1.916s
sys 0m0.073s
fwrite-based patch:
real 0m3.576s
user 0m2.571s
sys 0m1.006s
This is as I expected: glibc just isn't doing a very good job for this
buffered stream.
> In general, I'd prefer not to reinvent the wheel, and trust modern
> libc's that they are efficient enough in handling buffered streams,
> unless we have hard evidence to the contrary.
We do, now.
> If nothing else, it
> would prevent people asking, like Daniel did, why didn't we use stdio
> in the first place.
I think it's a very good question (in fact, the brach I'm working on
is called pdumper-fwrite because I decided only after creating it that
all the seeking would hurt performance too much). I'll try including a
comment explaining why.
> > Also, we're not currently using fseek-and-write anywhere in Emacs.
>
> I don't see why this would be important.
Because the stream returned by emacs_fopen might not be generally seekable?
> Since we open the file in
> binary mode, fseek should work correctly even on non-Posix systems.
I guess I should have used emacs_fopen :-)
> > We're talking about a file which Emacs is going to have to keep in
> > memory anyway, when reading the dump. The only case in which there
> > might be a problem is if the build machine has significantly less
> > available memory than the machine we intend to run on, and I just
> > don't think that's going to happen.
>
> You are thinking about memory consumption, while I am thinking how to
> avoid implementing our own private buffered streams.
By preparing the data in memory and writing it in one go, which
doesn't require any of the major complications of implementing
buffered streams.
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 9:54 ` Pip Cet
@ 2021-03-05 10:23 ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-03-05 12:06 ` Eli Zaretskii
1 sibling, 0 replies; 39+ messages in thread
From: Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-03-05 10:23 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, Eli Zaretskii, eggert
Pip Cet <pipcet@gmail.com> writes:
[...]
> By preparing the data in memory and writing it in one go, which
> doesn't require any of the major complications of implementing
> buffered streams.
Preparing data in memory might also be seen as a small step in the
direction of having pdumper as a generic de/serializer. IMO would be
helpful for a number of tasks (native compiler included).
Andrea
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 9:54 ` Pip Cet
2021-03-05 10:23 ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2021-03-05 12:06 ` Eli Zaretskii
2021-03-05 12:49 ` Lars Ingebrigtsen
2021-03-05 13:16 ` Pip Cet
1 sibling, 2 replies; 39+ messages in thread
From: Eli Zaretskii @ 2021-03-05 12:06 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, eggert
> From: Pip Cet <pipcet@gmail.com>
> Date: Fri, 5 Mar 2021 09:54:32 +0000
> Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, 46881@debbugs.gnu.org
>
> My patch:
>
> real 0m1.988s
> user 0m1.916s
> sys 0m0.073s
>
> fwrite-based patch:
>
> real 0m3.576s
> user 0m2.571s
> sys 0m1.006s
30% slowdown and 1.5 sec absolute time difference doesn't sound bad
enough to me to justify a homemade solution. I say let's go with
stdio.
> > > Also, we're not currently using fseek-and-write anywhere in Emacs.
> >
> > I don't see why this would be important.
>
> Because the stream returned by emacs_fopen might not be generally seekable?
I don't see how that could happen.
> > Since we open the file in
> > binary mode, fseek should work correctly even on non-Posix systems.
>
> I guess I should have used emacs_fopen :-)
Yes, of course. Especially as with fopen there are problems with
non-ASCII file names on MS-Windows.
> By preparing the data in memory and writing it in one go, which
> doesn't require any of the major complications of implementing
> buffered streams.
There are no complications I can see, not in our sources. (And you
don't actually write it in one go anyway, see emacs_full_write.)
So let's go with the stdio solution, please.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 12:06 ` Eli Zaretskii
@ 2021-03-05 12:49 ` Lars Ingebrigtsen
2021-03-05 13:23 ` Eli Zaretskii
2021-03-05 13:16 ` Pip Cet
1 sibling, 1 reply; 39+ messages in thread
From: Lars Ingebrigtsen @ 2021-03-05 12:49 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, eggert, Pip Cet
Eli Zaretskii <eliz@gnu.org> writes:
> 30% slowdown and 1.5 sec absolute time difference doesn't sound bad
> enough to me to justify a homemade solution. I say let's go with
> stdio.
Seems significant to me -- we're building Emacs a lot, and this bit
can't be parallelised. And the savings in electricity alone should make
us go for the most efficient solution.
There doesn't seem to be any significant drawbacks to doing it the
efficient way, either.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 12:06 ` Eli Zaretskii
2021-03-05 12:49 ` Lars Ingebrigtsen
@ 2021-03-05 13:16 ` Pip Cet
2021-03-05 14:02 ` Pip Cet
1 sibling, 1 reply; 39+ messages in thread
From: Pip Cet @ 2021-03-05 13:16 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, eggert
On Fri, Mar 5, 2021 at 12:07 PM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Fri, 5 Mar 2021 09:54:32 +0000
> > Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, 46881@debbugs.gnu.org
> >
> > My patch:
> >
> > real 0m1.988s
> > user 0m1.916s
> > sys 0m0.073s
> >
> > fwrite-based patch:
> >
> > real 0m3.576s
> > user 0m2.571s
> > sys 0m1.006s
>
> 30% slowdown and 1.5 sec absolute time difference doesn't sound bad
> enough to me to
It's a 30% slowdown of the entire dump process, including the
CPU-intensive part which loads Emacs. I think you get a better idea of
the performance difference from the "sys" numbers above.
And the absolute time difference is more than that, because Emacs is
dumped twice during each build; the first dump file is about 2.5 times
the size of the ultimate dump file, so my guess (as I said before,
unfortunately Intel decided to make this system not have a predictable
CPU clock, so I can't really run good benchmarks) is we're talking
about 4.5 seconds here.
> justify a homemade solution.
"Create a buffer in memory and do all the IO at once" is such an old
solution that even the GNU Coding Standards explicitly recommend it
(albeit for input files):
You could keep the entire input file in memory and scan it there
instead of using stdio
>I say let's go with stdio.
Maybe setbuffer(3) could help us here? I could run some benchmarks for
that if the idea isn't out of the question.
> > > > Also, we're not currently using fseek-and-write anywhere in Emacs.
> > >
> > > I don't see why this would be important.
> >
> > Because the stream returned by emacs_fopen might not be generally seekable?
>
> I don't see how that could happen.
It has, to me, but I'm willing to accept I did some inadvisable things first.
> > By preparing the data in memory and writing it in one go, which
> > doesn't require any of the major complications of implementing
> > buffered streams.
>
> There are no complications I can see, not in our sources. (And you
> don't actually write it in one go anyway, see emacs_full_write.)
Er, precisely. I was the one saying there are no complications, so we
shouldn't let the idea of "implementing our own buffered streams"
scare us, because that is a complicated project but it's also not what
we are doing.
> So let's go with the stdio solution, please.
Should I add a sync after every seek to make absolutely certain,
rather than merely likely, this will destroy someone's flash chip one
day?
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 12:49 ` Lars Ingebrigtsen
@ 2021-03-05 13:23 ` Eli Zaretskii
0 siblings, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2021-03-05 13:23 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 46881, eggert, pipcet
> From: Lars Ingebrigtsen <larsi@gnus.org>
> Cc: Pip Cet <pipcet@gmail.com>, 46881@debbugs.gnu.org, eggert@cs.ucla.edu
> Date: Fri, 05 Mar 2021 13:49:42 +0100
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > 30% slowdown and 1.5 sec absolute time difference doesn't sound bad
> > enough to me to justify a homemade solution. I say let's go with
> > stdio.
>
> Seems significant to me -- we're building Emacs a lot, and this bit
> can't be parallelised. And the savings in electricity alone should make
> us go for the most efficient solution.
>
> There doesn't seem to be any significant drawbacks to doing it the
> efficient way, either.
<Shrug> Fine, let's do it that way, then.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 13:16 ` Pip Cet
@ 2021-03-05 14:02 ` Pip Cet
2021-03-05 14:13 ` Daniel Colascione
2021-03-05 14:55 ` Eli Zaretskii
0 siblings, 2 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-05 14:02 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, eggert
On Fri, Mar 5, 2021 at 1:16 PM Pip Cet <pipcet@gmail.com> wrote:
> >I say let's go with stdio.
>
> Maybe setbuffer(3) could help us here? I could run some benchmarks for
> that if the idea isn't out of the question.
Actually, calling setbuffer() with a large buffer will make glibc
reread the entire file on every fseek(), rendering the dump so slow I
gave up and interrupted it.
However, there's open_memstream: that would have the added advantage
of actually making glibc write out the entire file in one go, so it
seems to shave a few extra milliseconds off the build.
(However however, glibc's memstreams are somewhat broken. I'll file a
bug report if there isn't one already...)
Still, that way we could use stdio today, leave the buffering to
glibc, and hopefully be able to switch trivially to a "open this file
but keep it in memory" combined memstream/FILE* one day.
Pip
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 14:02 ` Pip Cet
@ 2021-03-05 14:13 ` Daniel Colascione
2021-03-05 14:55 ` Eli Zaretskii
1 sibling, 0 replies; 39+ messages in thread
From: Daniel Colascione @ 2021-03-05 14:13 UTC (permalink / raw)
To: Pip Cet, Eli Zaretskii; +Cc: 46881, eggert
On 3/5/21 9:02 AM, Pip Cet wrote:
> On Fri, Mar 5, 2021 at 1:16 PM Pip Cet <pipcet@gmail.com> wrote:
>>> I say let's go with stdio.
>> Maybe setbuffer(3) could help us here? I could run some benchmarks for
>> that if the idea isn't out of the question.
> Actually, calling setbuffer() with a large buffer will make glibc
> reread the entire file on every fseek(), rendering the dump so slow I
> gave up and interrupted it.
>
> However, there's open_memstream: that would have the added advantage
> of actually making glibc write out the entire file in one go, so it
> seems to shave a few extra milliseconds off the build.
>
> (However however, glibc's memstreams are somewhat broken. I'll file a
> bug report if there isn't one already...)
>
> Still, that way we could use stdio today, leave the buffering to
> glibc, and hopefully be able to switch trivially to a "open this file
> but keep it in memory" combined memstream/FILE* one day.
You could also use fopencookie to make your own stdio stream that does
the right thing while still using the stdio abstraction in the part of
the code actually doing the writing.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 14:02 ` Pip Cet
2021-03-05 14:13 ` Daniel Colascione
@ 2021-03-05 14:55 ` Eli Zaretskii
2021-03-05 15:12 ` Pip Cet
1 sibling, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2021-03-05 14:55 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881, eggert
> From: Pip Cet <pipcet@gmail.com>
> Date: Fri, 5 Mar 2021 14:02:33 +0000
> Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, 46881@debbugs.gnu.org
>
> However, there's open_memstream
That's glibc-only, AFAIK. Not portable enough for us.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-05 14:55 ` Eli Zaretskii
@ 2021-03-05 15:12 ` Pip Cet
0 siblings, 0 replies; 39+ messages in thread
From: Pip Cet @ 2021-03-05 15:12 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, eggert
[-- Attachment #1: Type: text/plain, Size: 424 bytes --]
On Fri, Mar 5, 2021 at 2:56 PM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Pip Cet <pipcet@gmail.com>
> > Date: Fri, 5 Mar 2021 14:02:33 +0000
> > Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, 46881@debbugs.gnu.org
> >
> > However, there's open_memstream
>
> That's glibc-only, AFAIK. Not portable enough for us.
POSIX.1-2008. Not portable enough to require, certainly, but portable
enough to use?
Pip
[-- Attachment #2: 0001-Use-stdio-memstreams-if-available-for-pdumper-Bug-46.patch --]
[-- Type: text/x-patch, Size: 4798 bytes --]
From b600c444e046d3888f56839dbe70d6d209a6ba29 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Tue, 2 Mar 2021 20:38:23 +0000
Subject: [PATCH] Use stdio, memstreams if available for pdumper (Bug#46881)
* configure.ac: Check for open_memstream.
* src/pdumper.c (dump_unwind_cleanup): Handle memstreams.
(dump_seek): Record maximum offset for memstreams. Use stdio.
(struct dump_context): Add buffer information for memstreams.
(Fdump_emacs_portable): Use memstreams if available.
(dump_write): Use stdio.
(Fdump_emacs_portable): Use memstreams if available.
---
configure.ac | 1 +
src/pdumper.c | 64 ++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/configure.ac b/configure.ac
index 11a06a39bee3f..4225aea9635ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4554,6 +4554,7 @@ AC_DEFUN
dnl AC_CHECK_FUNCS_ONCE wouldn’t be right for snprintf, which needs
dnl the current CFLAGS etc.
AC_CHECK_FUNCS(snprintf)
+AC_CHECK_FUNCS(open_memstream)
dnl Check for glib. This differs from other library checks in that
dnl Emacs need not link to glib unless some other library is already
diff --git a/src/pdumper.c b/src/pdumper.c
index 337742fda4ade..a524f87300b51 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -482,8 +482,14 @@ dump_fingerprint (char const *label,
bool blocked_ralloc;
#endif
- /* File descriptor for dumpfile; < 0 if closed. */
- int fd;
+ /* File handle for dumpfile; NULL if closed. */
+ FILE *file;
+#ifdef HAVE_OPEN_MEMSTREAM
+ /* buf is non-NULL if file referred to a memstream and has been closed. */
+ char *buf;
+ size_t buf_size;
+ size_t max_offset;
+#endif
/* Name of dump file --- used for error reporting. */
Lisp_Object dump_filename;
/* Current offset in dump file. */
@@ -747,9 +753,16 @@ dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte)
eassert (nbyte == 0 || buf != NULL);
eassert (ctx->obj_offset == 0);
eassert (ctx->flags.dump_object_contents);
- if (emacs_write (ctx->fd, buf, nbyte) < nbyte)
- report_file_error ("Could not write to dump file", ctx->dump_filename);
- ctx->offset += nbyte;
+ while (nbyte)
+ {
+ size_t res = fwrite (buf, 1, nbyte, ctx->file);
+ if (res == 0)
+ report_file_error ("Could not write to dump file",
+ ctx->dump_filename);
+ buf = (char *)buf + res;
+ ctx->offset += res;
+ nbyte -= res;
+ }
}
static Lisp_Object
@@ -828,10 +841,13 @@ dump_tailq_pop (struct dump_tailq *tailq)
static void
dump_seek (struct dump_context *ctx, dump_off offset)
{
+#ifdef HAVE_OPEN_MEMSTREAM
+ if (ctx->offset > ctx->max_offset)
+ ctx->max_offset = ctx->offset;
+#endif
eassert (ctx->obj_offset == 0);
- if (lseek (ctx->fd, offset, SEEK_SET) < 0)
- report_file_error ("Setting file position",
- ctx->dump_filename);
+ if (fseek (ctx->file, offset, SEEK_SET) != 0)
+ report_file_error ("Setting file position", ctx->dump_filename);
ctx->offset = offset;
}
@@ -3513,8 +3529,25 @@ dump_drain_user_remembered_data_cold (struct dump_context *ctx)
dump_unwind_cleanup (void *data)
{
struct dump_context *ctx = data;
- if (ctx->fd >= 0)
- emacs_close (ctx->fd);
+#ifdef HAVE_OPEN_MEMSTREAM
+ if (ctx->file)
+ {
+ fseek (ctx->file, ctx->max_offset, SEEK_SET);
+ fclose (ctx->file);
+ }
+ if (ctx->buf)
+ {
+ eassert (ctx->max_offset <= ctx->buf_size);
+ ctx->file = emacs_fopen (SSDATA (ctx->dump_filename), "w");
+ if (ctx->file == NULL)
+ report_file_error ("Could not open dump file",
+ ctx->dump_filename);
+ ctx->offset = 0;
+ dump_write (ctx, ctx->buf, ctx->max_offset);
+ }
+#endif
+ if (ctx->file)
+ fclose (ctx->file);
#ifdef REL_ALLOC
if (ctx->blocked_ralloc)
r_alloc_inhibit_buffer_relocation (0);
@@ -3952,7 +3985,7 @@ DEFUN ("dump-emacs-portable",
struct dump_context ctx_buf = {0};
struct dump_context *ctx = &ctx_buf;
- ctx->fd = -1;
+ ctx->file = NULL;
ctx->objects_dumped = make_eq_hash_table ();
dump_queue_init (&ctx->dump_queue);
@@ -4012,9 +4045,12 @@ DEFUN ("dump-emacs-portable",
ctx->old_process_environment = Vprocess_environment;
Vprocess_environment = Qnil;
- ctx->fd = emacs_open (SSDATA (filename),
- O_RDWR | O_TRUNC | O_CREAT, 0666);
- if (ctx->fd < 0)
+#ifdef HAVE_OPEN_MEMSTREAM
+ ctx->file = open_memstream (&ctx->buf, &ctx->buf_size);
+#endif
+ if (ctx->file == NULL)
+ ctx->file = emacs_fopen (SSDATA (filename), "w+");
+ if (ctx->file == NULL)
report_file_error ("Opening dump output", filename);
verify (sizeof (ctx->header.magic) == sizeof (dump_magic));
memcpy (&ctx->header.magic, dump_magic, sizeof (dump_magic));
--
2.30.1
^ permalink raw reply related [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-02 20:33 bug#46881: 28.0.50; pdumper dumping causes way too many syscalls Pip Cet
2021-03-02 20:45 ` Pip Cet
@ 2021-06-15 9:25 ` Mattias Engdegård
2021-06-15 12:58 ` Daniel Colascione
2021-06-16 14:13 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2 siblings, 1 reply; 39+ messages in thread
From: Mattias Engdegård @ 2021-06-15 9:25 UTC (permalink / raw)
To: Pip Cet, Eli Zaretskii, 46881, Daniel Colascione, Paul Eggert
Any reason not to apply the patch from https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46881#20 right away? I've been using it locally for quite some time with very good results.
There seems to be a consensus for it, and while there may be even better solutions, having this in place now won't hurt.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 9:25 ` Mattias Engdegård
@ 2021-06-15 12:58 ` Daniel Colascione
2021-06-15 13:06 ` Eli Zaretskii
0 siblings, 1 reply; 39+ messages in thread
From: Daniel Colascione @ 2021-06-15 12:58 UTC (permalink / raw)
To: Mattias Engdegård, Pip Cet, Eli Zaretskii, 46881,
Paul Eggert
On 6/15/21 2:25 AM, Mattias Engdegård wrote:
> Any reason not to apply the patch from https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46881#20 right away? I've been using it locally for quite some time with very good results.
>
> There seems to be a consensus for it, and while there may be even better solutions, having this in place now won't hurt.
I thought we had consensus for an fwrite based approach?
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 12:58 ` Daniel Colascione
@ 2021-06-15 13:06 ` Eli Zaretskii
2021-06-15 13:17 ` Lars Ingebrigtsen
0 siblings, 1 reply; 39+ messages in thread
From: Eli Zaretskii @ 2021-06-15 13:06 UTC (permalink / raw)
To: Daniel Colascione, Lars Ingebrigtsen; +Cc: 46881, mattiase, eggert, pipcet
> From: Daniel Colascione <dancol@dancol.org>
> Date: Tue, 15 Jun 2021 05:58:26 -0700
>
> On 6/15/21 2:25 AM, Mattias Engdegård wrote:
>
> > Any reason not to apply the patch from https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46881#20 right away? I've been using it locally for quite some time with very good results.
> >
> > There seems to be a consensus for it, and while there may be even better solutions, having this in place now won't hurt.
> I thought we had consensus for an fwrite based approach?
That's what I preferred (still do), but Lars thought that the slightly
faster version without stdio was preferable.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 13:06 ` Eli Zaretskii
@ 2021-06-15 13:17 ` Lars Ingebrigtsen
2021-06-15 13:25 ` Daniel Colascione
2021-06-15 15:32 ` Mattias Engdegård
0 siblings, 2 replies; 39+ messages in thread
From: Lars Ingebrigtsen @ 2021-06-15 13:17 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 46881, mattiase, pipcet, eggert
Eli Zaretskii <eliz@gnu.org> writes:
> That's what I preferred (still do), but Lars thought that the slightly
> faster version without stdio was preferable.
Well, it's 30% faster in a single-threaded phase of the compilation, so
it seems like a significant improvement to me.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 13:17 ` Lars Ingebrigtsen
@ 2021-06-15 13:25 ` Daniel Colascione
2021-06-15 13:30 ` Eli Zaretskii
2021-06-15 15:32 ` Mattias Engdegård
1 sibling, 1 reply; 39+ messages in thread
From: Daniel Colascione @ 2021-06-15 13:25 UTC (permalink / raw)
To: Lars Ingebrigtsen, Eli Zaretskii; +Cc: 46881, mattiase, eggert, pipcet
On June 15, 2021 6:18:11 AM Lars Ingebrigtsen <larsi@gnus.org> wrote:
> Eli Zaretskii <eliz@gnu.org> writes:
>
>> That's what I preferred (still do), but Lars thought that the slightly
>> faster version without stdio was preferable.
>
> Well, it's 30% faster in a single-threaded phase of the compilation, so
> it seems like a significant improvement to me.
>
> --
> (domestic pets only, the antidote for overdose, milk.)
> bloggy blog: http://lars.ingebrigtsen.n
The in-memory version is 30% faster than the FILE* version or 30% faster
than the current write () version?
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 13:25 ` Daniel Colascione
@ 2021-06-15 13:30 ` Eli Zaretskii
0 siblings, 0 replies; 39+ messages in thread
From: Eli Zaretskii @ 2021-06-15 13:30 UTC (permalink / raw)
To: Daniel Colascione; +Cc: 46881, mattiase, larsi, eggert, pipcet
> From: Daniel Colascione <dancol@dancol.org>
> CC: <mattiase@acm.org>, <pipcet@gmail.com>, <46881@debbugs.gnu.org>, <eggert@cs.ucla.edu>
> Date: Tue, 15 Jun 2021 06:25:50 -0700
>
> >> That's what I preferred (still do), but Lars thought that the slightly
> >> faster version without stdio was preferable.
> >
> > Well, it's 30% faster in a single-threaded phase of the compilation, so
> > it seems like a significant improvement to me.
> >
> > --
> > (domestic pets only, the antidote for overdose, milk.)
> > bloggy blog: http://lars.ingebrigtsen.n
>
> The in-memory version is 30% faster than the FILE* version or 30% faster
> than the current write () version?
The former, see
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46881#56
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 13:17 ` Lars Ingebrigtsen
2021-06-15 13:25 ` Daniel Colascione
@ 2021-06-15 15:32 ` Mattias Engdegård
2021-06-15 22:44 ` Daniel Colascione
1 sibling, 1 reply; 39+ messages in thread
From: Mattias Engdegård @ 2021-06-15 15:32 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 46881, pipcet, eggert
15 juni 2021 kl. 15.17 skrev Lars Ingebrigtsen <larsi@gnus.org>:
> Well, it's 30% faster in a single-threaded phase of the compilation, so
> it seems like a significant improvement to me.
The patch seems to be good in all respects -- simple, low risk, better performance, no compatibility trouble. And nothing prevents us from replacing it with something better later on, should the need arise.
All set then?
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 15:32 ` Mattias Engdegård
@ 2021-06-15 22:44 ` Daniel Colascione
2021-06-16 8:00 ` Mattias Engdegård
0 siblings, 1 reply; 39+ messages in thread
From: Daniel Colascione @ 2021-06-15 22:44 UTC (permalink / raw)
To: Mattias Engdegård, Lars Ingebrigtsen; +Cc: 46881, eggert, pipcet
On 6/15/21 8:32 AM, Mattias Engdegård wrote:
> 15 juni 2021 kl. 15.17 skrev Lars Ingebrigtsen <larsi@gnus.org>:
>> Well, it's 30% faster in a single-threaded phase of the compilation, so
>> it seems like a significant improvement to me.
> The patch seems to be good in all respects -- simple, low risk, better performance, no compatibility trouble. And nothing prevents us from replacing it with something better later on, should the need arise.
>
> All set then?
>
Okay. I'm convinced.
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-15 22:44 ` Daniel Colascione
@ 2021-06-16 8:00 ` Mattias Engdegård
2021-06-16 8:14 ` Lars Ingebrigtsen
2021-06-16 8:16 ` Pip Cet
0 siblings, 2 replies; 39+ messages in thread
From: Mattias Engdegård @ 2021-06-16 8:00 UTC (permalink / raw)
To: Daniel Colascione; +Cc: 46881-done, Lars Ingebrigtsen, Paul Eggert, Pip Cet
16 juni 2021 kl. 00.44 skrev Daniel Colascione <dancol@dancol.org>:
> Okay. I'm convinced.
All right, pushed, and closing this bug.
Thanks, Pip!
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-16 8:00 ` Mattias Engdegård
@ 2021-06-16 8:14 ` Lars Ingebrigtsen
2021-06-16 8:16 ` Pip Cet
1 sibling, 0 replies; 39+ messages in thread
From: Lars Ingebrigtsen @ 2021-06-16 8:14 UTC (permalink / raw)
To: Mattias Engdegård; +Cc: 46881-done, Pip Cet, Paul Eggert
Mattias Engdegård <mattiase@acm.org> writes:
> All right, pushed, and closing this bug.
> Thanks, Pip!
Great; thanks.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-06-16 8:00 ` Mattias Engdegård
2021-06-16 8:14 ` Lars Ingebrigtsen
@ 2021-06-16 8:16 ` Pip Cet
1 sibling, 0 replies; 39+ messages in thread
From: Pip Cet @ 2021-06-16 8:16 UTC (permalink / raw)
To: Mattias Engdegård; +Cc: 46881-done, Lars Ingebrigtsen, Paul Eggert
On Wed, Jun 16, 2021 at 8:00 AM Mattias Engdegård <mattiase@acm.org> wrote:
>
> 16 juni 2021 kl. 00.44 skrev Daniel Colascione <dancol@dancol.org>:
>
> > Okay. I'm convinced.
>
> All right, pushed, and closing this bug.
> Thanks, Pip!
Thank you for following up on this! Sorry Emacs kind of lost priority
for me right now, but I'll get back to it...
^ permalink raw reply [flat|nested] 39+ messages in thread
* bug#46881: 28.0.50; pdumper dumping causes way too many syscalls
2021-03-02 20:33 bug#46881: 28.0.50; pdumper dumping causes way too many syscalls Pip Cet
2021-03-02 20:45 ` Pip Cet
2021-06-15 9:25 ` Mattias Engdegård
@ 2021-06-16 14:13 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2 siblings, 0 replies; 39+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-06-16 14:13 UTC (permalink / raw)
To: Pip Cet; +Cc: 46881
Pip Cet [2021-03-02 20:33:42] wrote:
> Playing around with the WebAssembly port, I noticed that pdumper, in
> creating the dump file, makes way too many syscalls: it uses
> emacs_write(), not fwrite(), so these calls translate to actual
> syscalls and context switches. On immature systems (or in special
> circumstances like a device mounted synchronously),
Thanks for this patch. For the little story, this inefficiency showed
up on one of my Thinkpads running GNU/Linux with a plain
old ext4 partition mounted in the most standard way (no synchronous
mount or other funny business):
https://serverfault.com/questions/996495/writes-throttled-to-500kb-s
The way this manifested itself is that after some uptime individual
writes to the SSD became very slow. For most operations, this was
completely invisible, but it was quite noticeable during Emacs's dump
which sometimes took several minutes (while all the rest of the
compilation (including the "load" part of the dump)) progressed at
(apparently) usual speeds.
Stefan
^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2021-06-16 14:13 UTC | newest]
Thread overview: 39+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-02 20:33 bug#46881: 28.0.50; pdumper dumping causes way too many syscalls Pip Cet
2021-03-02 20:45 ` Pip Cet
2021-03-02 21:07 ` Alan Third
2021-03-03 7:10 ` Pip Cet
2021-03-03 19:57 ` Alan Third
2021-03-04 7:25 ` Pip Cet
2021-03-03 5:51 ` Eli Zaretskii
2021-03-03 7:35 ` Pip Cet
2021-03-03 15:09 ` Lars Ingebrigtsen
2021-03-03 19:35 ` Paul Eggert
2021-03-04 22:26 ` Daniel Colascione
2021-03-05 2:30 ` Pip Cet
2021-03-05 7:19 ` Eli Zaretskii
2021-03-05 7:38 ` Pip Cet
2021-03-05 7:54 ` Eli Zaretskii
2021-03-05 9:54 ` Pip Cet
2021-03-05 10:23 ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-03-05 12:06 ` Eli Zaretskii
2021-03-05 12:49 ` Lars Ingebrigtsen
2021-03-05 13:23 ` Eli Zaretskii
2021-03-05 13:16 ` Pip Cet
2021-03-05 14:02 ` Pip Cet
2021-03-05 14:13 ` Daniel Colascione
2021-03-05 14:55 ` Eli Zaretskii
2021-03-05 15:12 ` Pip Cet
2021-03-05 9:35 ` Andreas Schwab
2021-03-05 9:41 ` Pip Cet
2021-06-15 9:25 ` Mattias Engdegård
2021-06-15 12:58 ` Daniel Colascione
2021-06-15 13:06 ` Eli Zaretskii
2021-06-15 13:17 ` Lars Ingebrigtsen
2021-06-15 13:25 ` Daniel Colascione
2021-06-15 13:30 ` Eli Zaretskii
2021-06-15 15:32 ` Mattias Engdegård
2021-06-15 22:44 ` Daniel Colascione
2021-06-16 8:00 ` Mattias Engdegård
2021-06-16 8:14 ` Lars Ingebrigtsen
2021-06-16 8:16 ` Pip Cet
2021-06-16 14:13 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).