Subject: bug#70216: 30.0.50; self-insert-command doesn't respect create-lockfiles

From: Theodor Thornhill <[email-masked]>
Date: Fri, 05 Apr 2024 12:52:39 +0200

Hi all!

I'm digging more and more into the internals of Emacs these days, and
while tracing input lag performance i noticed that we don't respect the
create-lockfiles option, at least not fully.

The documentation states:
```
If the option `create-lockfiles' is nil, this does nothing.
```
However, the nothing is postponed until later, inside the lock_file
function. This means we won't cretae the lockfile, but we will get the
truename-buffer, verify visited file, etc, on my system amounting to
some time spent which I thought I opted out of.

Along with a patch that fixes this behavior I've added 4 screenshots of
graphs taken through intel_pt tracing on trigger of self-insert inside a
c file.

to reproduce what I do, from inside my emacs source code folder:

```
;; normal emacs built from source a couple of days ago
emacs -Q +644 src/filelock.c
emacs -Q -eval "(setq create-lockfiles nil)" +644 src/filelock.c

;; emacs with the provided patch
./src/emacs -Q +644 src/filelock.c
./src/emacs -Q -eval "(setq create-lockfiles nil)" +644 src/filelock.c
```

The first two screenshots show the current behavior without this patch,
where you can see that we still do some lock-file related computing even
though the setting is off. The last two show that we don't do it at all,
while preserving the vanilla operation when create-lockfiles = t.

The lock file related code can take up to a millisecond on my system,
but is usually in the range of 200-300 microseconds.

It seems there was some cleanup/changes around this behavior which i
believe caused this as a regression, from around 3 years ago. I _think_
this commit: 9ce6541ac9710933beca7f9944087fe4849d5ae9

Theo

>From c491a7533198ba875f8cc7dc26322744964b6000 Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <[email-masked]>
Date: Fri, 5 Apr 2024 12:34:13 +0200
Subject: [PATCH] Actually do nothing when create-lockfiles is nil

* src/filelock.c(lock-file, lock-buffer): Wrap the logic of the code in
a check for create-lockfiles.
---
 src/filelock.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/src/filelock.c b/src/filelock.c
index 8c27b226900..aad4f5abab1 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -642,18 +642,22 @@ DEFUN ("lock-file", Flock_file, Slock_file, 1, 1, 0,
 If the option `create-lockfiles' is nil, this does nothing.  */)
   (Lisp_Object file)
 {
+  if (create_lockfiles)
+    {
 #ifndef MSDOS
-  CHECK_STRING (file);
 
-  /* If the file name has special constructs in it,
-     call the corresponding file name handler.  */
-  Lisp_Object handler;
-  handler = Ffind_file_name_handler (file, Qlock_file);
-  if (!NILP (handler))
-    return call2 (handler, Qlock_file, file);
+      CHECK_STRING (file);
+
+      /* If the file name has special constructs in it,
+	 call the corresponding file name handler.  */
+      Lisp_Object handler;
+      handler = Ffind_file_name_handler (file, Qlock_file);
+      if (!NILP (handler))
+	return call2 (handler, Qlock_file, file);
 
-  lock_file (file);
+      lock_file (file);
 #endif	/* MSDOS */
+    }
   return Qnil;
 }
 
@@ -691,13 +695,16 @@ DEFUN ("lock-buffer", Flock_buffer, Slock_buffer,
 If the option `create-lockfiles' is nil, this does nothing.  */)
   (Lisp_Object file)
 {
-  if (NILP (file))
-    file = BVAR (current_buffer, file_truename);
-  else
-    CHECK_STRING (file);
-  if (SAVE_MODIFF < MODIFF
-      && !NILP (file))
-    Flock_file (file);
+  if (create_lockfiles)
+    {
+      if (NILP (file))
+	file = BVAR (current_buffer, file_truename);
+      else
+	CHECK_STRING (file);
+      if (SAVE_MODIFF < MODIFF
+	  && !NILP (file))
+	Flock_file (file);
+    }
   return Qnil;
 }
 
-- 
2.40.1