unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Patch for fields of `struct buffer'
@ 2011-01-27 20:18 Tom Tromey
  2011-01-28  7:37 ` Eli Zaretskii
                   ` (3 more replies)
  0 siblings, 4 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-27 20:18 UTC (permalink / raw)
  To: Emacs discussions

[-- Attachment #1: Type: text/plain, Size: 2039 bytes --]

Here is the promised change to buffer fields.

I need volunteers to complete this patch; or at least the ok on
proceeding to temporarily break the build.  See below for details.


In order to implement thread-specific let-binding of buffer-local
variables, we must introduce an indirection into the C code, so that
lookups of these variables see the thread-specific value, if any.

This patch enables this by adding an accessor macro for each field of
struct buffer.  For a field named `name', the corresponding accessor
is `BUF_NAME'.  All code outside of the GC must then use these
accessor macros.

On the trunk this results in the same code.  On the concurrency
branch, we will redefine these macros to do the needed thread
indirection.


This patch was automatically generated using the attached script.  The
basic idea is simple: rename all the fields in struct buffer, run
`make', and then use the locations in the error messages to decide
where to rewrite.  If you want to reproduce this, you will need a
modified GCC; I can tell you how to get the patches if you want.

Because this script runs the compiler, it only edits locations which
were included in my build.  So, it is probable that some needed
changes were not done.  Fixing any given build failure is simple, but
requires someone to actually see it.

This is where volunteers come in.  We could either proceed by
committing the patch and fixing the problems piecemeal, or by having a
couple people with other systems apply the patch, do a build, and send
me the logs (or patches relative to mine), then repeat.  You would not
need a modified GCC to do this step; I don't expect enough problems to
warrant more automation.


This same technique could be used to extend HIDE_LISP_IMPLEMENTATION
to all lisp types.  Is that worth doing?


The next patch will be applying the same treatment to struct kboard.
Again, it may be a while before I can get to that.


Let me know what you think.  I am not sure what I will do in the absence
of comments.  Maybe check it in!

Tom


[-- Attachment #2: hack buffer locals --]
[-- Type: text/plain, Size: 10721 bytes --]

;; Rewrite all references to buffer-objfwd fields in struct buffer
;; to use accessor macros.
;; This works in a tricky way: it renames all such fields, then
;; recompiles Emacs.  Then it visits each error location and
;; rewrites the expressions.
;; This has a few requirements in order to work.
;; First, Emacs must compile before the script is run.
;; It does not handle errors arising for other reasons.
;; Second, you need a GCC which has been hacked to emit proper
;; column location even when the -> expression in question has
;; been wrapped in a macro call.  I am using Dodji Seketeli's
;; patch series that adds location tracking through macros;
;; it has been submitted to gcc-patches but not yet applied.
;; After running this script, a few changes need to be made by hand.
;; These occur mostly in macros in headers, but also in
;; reset_buffer and reset_buffer_local_variables.  Finally,
;; DEFVAR_PER_BUFFER and the GC should not use these accessors.

(setq add-log-keep-changes-together t)

(defvar gcc-prefix "/home/tromey/gcc/install/")
(defvar gcc-bin-dir (concat gcc-prefix "bin/"))

(defvar emacs-base "/home/tromey/Emacs/emacs-mt/")
(defvar emacs-src (concat emacs-base "trunk/src/"))
(defvar emacs-build (concat emacs-base "build/src/"))

(defun file-error (text)
  (error "%s:%d:%d: error: expected %s"
	 buffer-file-name (line-number-at-pos (point))
	 (current-column)
	 text))

(defun assert-looking-at (exp)
  (unless (looking-at exp)
    (file-error exp)))

(defvar last-file-name nil)
(defvar last-function-name nil)

(defun edit-add-cl-entry ()
  (unless (equal buffer-file-name last-file-name)
    (setq last-file-name buffer-file-name)
    (setq last-function-name nil))

  (let ((function (add-log-current-defun)))
    (unless (equal function last-function-name)
      (setq last-function-name function)
      (save-current-buffer
	(add-change-log-entry))
      t)))

(defun insert-cl-entry (text)
  (save-current-buffer
    (find-file "ChangeLog")
    (insert text)
    (fill-paragraph)))

(defvar field-names nil)

(defvar field-regexp nil)

(defun modify-buffer.h ()
  (message "Modifying fields in struct buffer")
  (find-file (expand-file-name "buffer.h" emacs-src))
  (goto-char (point-min))

  (let ((add-log-current-defun-function
	 #'(lambda () "struct buffer")))
    (edit-add-cl-entry)
    (insert-cl-entry "Rename all Lisp_Object fields."))

  (re-search-forward "^struct buffer$")
  (forward-line)
  (assert-looking-at "^{")
  (let ((starting-point (point))
	(closing-brace (save-excursion
			 (forward-sexp)
			 (point-marker))))
    ;; Find each field.
    (while (re-search-forward "^\\s *Lisp_Object\\s +"
			      closing-brace 'move)
      (goto-char (match-end 0))
      (while (not (looking-at ";"))
	(assert-looking-at "\\([A-Za-z0-9_]+\\)\\(;\\|,\\s *\\)")
	;; Remember the name so we can generate accessors.
	(push (match-string-no-properties 1) field-names)
	;; Rename it.
	(goto-char (match-beginning 2))
	(insert "_")
	;; On to the next one, if any.
	(if (looking-at ",\\s *")
	    (goto-char (match-end 0)))))
    ;; Generate accessors.
    (goto-char starting-point)
    (forward-sexp)
    (forward-line)
    (insert "\n")
    (dolist (name field-names)
      (let* ((m-name (concat "BUF_" (upcase name)))
	     (add-log-current-defun-function
	      #'(lambda () m-name)))
	(insert "#define " m-name "(BUF) \\\n    ((BUF)->"
		;; "*find_variable_location (&((BUF)->"
		name ;;"_))\n"
		"_)\n")
	(edit-add-cl-entry)))
    (insert "\n")
    (insert-cl-entry "New macro."))
  (setq field-regexp (concat "\\(->\\|\\.\\)"
			     (regexp-opt field-names t)
			     "\\_>"))

  (goto-char (point-min))
  (search-forward "#define PER_BUFFER_VAR_OFFSET")
  (forward-line)
  (search-forward "VAR")
  (assert-looking-at ")")
  (insert " ## _")

  (save-buffer))

(defun modify-buffer.c ()
  (message "Updating swapfield in buffer.c")
  (find-file (expand-file-name "buffer.c" emacs-src))
  (goto-char (point-min))
  (search-forward "#define swapfield")
  (forward-paragraph)

  (let ((add-log-current-defun-function #'(lambda () "swapfield_")))
    (save-current-buffer
      (edit-add-cl-entry)
      (insert-cl-entry "New macro.")
      (fill-paragraph)))

  (insert "#define swapfield_(field, type) \\
  do {							\\
    type tmp##field = other_buffer->field ## _;		\\
    other_buffer->field ## _ = current_buffer->field ## _;	\\
    current_buffer->field ## _ = tmp##field;			\\
  } while (0)\n")
  (while (search-forward "swapfield" nil 'move)
    (if
	(save-excursion
	  (assert-looking-at " (\\([a-z_]+\\),")
	  (member (match-string-no-properties 1) field-names))
	(insert "_")
      (edit-add-cl-entry)))

  (insert-cl-entry "Use swapfield_ where appropriate.")

  (save-buffer))

(defun modify-lisp.h ()
  (message "Updating lisp.h")
  (find-file (expand-file-name "lisp.h" emacs-src))
  (goto-char (point-min))
  (search-forward "#define DEFVAR_BUFFER_DEFAULTS")
  (search-forward "buffer_defaults.vname")
  (assert-looking-at ");")
  (insert " ## _")

  (let ((add-log-current-defun-function
	 #'(lambda () "DEFVAR_BUFFER_DEFAULTS")))
    (edit-add-cl-entry)
    (insert-cl-entry "Update for change to field names."))

  (save-buffer))

(defun get-field-name ()
  (save-excursion
    (assert-looking-at "\\(\\.\\|->\\)\\([A-Za-z0-9_]+\\)\\_>")
    (prog1
	(match-string-no-properties 2)
      (delete-region (match-beginning 0) (match-end 0)))))

(defun maybe-skip-backward-lhs-again ()
  (let (st-point)
    (when
	(save-excursion
	  (skip-chars-backward " \t\n")
	  (prog1
	      (or (progn
		    (backward-char)
		    (equal (char-after) ?.))
		  (progn
		    (backward-char 1)
		    (looking-at "->")))
	    (setq st-point (point))))
      (goto-char st-point)
      (skip-backward-lhs))))

(defun skip-backward-lhs ()
  (skip-chars-backward " \t\n")
  (cond
   ((eq (char-before) ?\])
    (file-error "array ref!")
    ;; fixme
    )
   ((eq (char-before) ?\))
    ;; A paren expression is preceding.
    ;; See if this is just a paren expression or whether it is a
    ;; function call.
    ;; For now assume that there are no function-calls-via-expr.
    (backward-sexp)
    (skip-chars-backward " \t\n")
    (when (save-excursion
	    (backward-char)
	    (looking-at "[A-Za-z0-9_]"))
      (backward-sexp)
      (maybe-skip-backward-lhs-again)))
   ((save-excursion
      (backward-char)
      (looking-at "[A-Za-z0-9_]"))
    ;; An identifier.
    (backward-sexp)
    (maybe-skip-backward-lhs-again))
   (t
    (file-error "unhandled case!"))))

(defun do-fix-instance ()
  (cond
   ((looking-at "->")
    ;; The GC should not use the accessors.
    (if (string-match "/alloc[.]c$" buffer-file-name)
	(progn
	  (forward-sexp)
	  (insert "_"))
      (let ((field-name (get-field-name)))
	(insert ")")
	(backward-char)
	(skip-backward-lhs)
	(insert "BUF_" (upcase field-name) " ("))
      t))
   ((eq (char-after) ?.)
    (let ((field-name (get-field-name)))
      (insert ")")
      (backward-char)
      (backward-sexp)
      (assert-looking-at "\\(buffer_defaults\\|buffer_local_flags\\|buffer_local_symbols\\)")
      (if (equal field-name "vname")
	  ;; Undo our changes, this use is in DEFVAR_PER_BUFFER.
	  (progn
	    (forward-sexp)
	    (delete-char 1)		; the ")" we inserted.
	    (insert ".vname")
	    nil)
	(insert "BUF_" (upcase field-name) " (&")
	t)))
   (t
    (message "%s:%d:%d: warning: did not see -> or ., probably macro"
	     buffer-file-name (line-number-at-pos (point))
	     (current-column))
    nil)))

(defun update-header-files ()
  (dolist (file (directory-files emacs-src t "h$"))
    (let (any-changed)
      (message "Applying header changes to %s" file)
      (find-file file)
      (goto-char (point-min))
      (while (re-search-forward
	      "\\(current_buffer->\\|buffer_defaults\\.\\)"
	      nil 'move)
	(goto-char (match-end 0))
	(skip-chars-backward "->.")
	(when (looking-at field-regexp)
	  (when (do-fix-instance)
	    (edit-add-cl-entry)
	    (setq any-changed t)))
      (goto-char (point-min))
      (while (search-forward "XBUFFER (" nil 'move)
	(goto-char (- (match-end 0) 1))
	(forward-sexp)
	;; This works even for the new #define BUF_ macros
	;; because the field-regexp ends with \_>.
	(when (looking-at field-regexp)
	  (when (do-fix-instance)
	    (edit-add-cl-entry)
	    (setq any-changed t))))
      (save-buffer)
      (if any-changed
	  (insert-cl-entry "Update."))))))

(defun fix-one-instance (filename line column)
  (message "%s:%d:%d: info: fixing instance" filename line column)
  (find-file filename)
  (goto-char (point-min))
  (forward-line (- line 1))
  ;; (move-to-column (- column 1))
  (forward-char (- column 1))
  (when (do-fix-instance)
    (edit-add-cl-entry)
    t))

(defvar make-accumulation "")

(defvar last-error-line nil)
(defvar error-list nil)

(defun make-filter (process string)
  (setq make-accumulation (concat make-accumulation string))
  (while (string-match "^[^\n]*\n" make-accumulation)
    (let ((line (substring (match-string 0 make-accumulation) 0 -1)))
      (setq make-accumulation (substring make-accumulation
					 (match-end 0)))
      (message "%s" line)
      (if (string-match "^\\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)+: error:"
			line)
	  (save-excursion
	    (let ((file-name (match-string 1 line))
		  (line-no (string-to-number (match-string 2 line)))
		  (col-no (string-to-number (match-string 3 line))))
	      ;; Process all errors on a given line in reverse order.
	      (unless (eq line-no last-error-line)
		(let (any-edited)
		  (dolist (one-item error-list)
		    (if (apply #'fix-one-instance one-item)
			(setq any-edited t)))
		  ;; Just edit ChangeLog by hand, it is simpler.
		  ;; (if any-edited
		  ;;     (insert-cl-entry "Update."))
		  )
		(setq error-list nil)
		(setq last-error-line line-no))
	      (push (list file-name line-no col-no) error-list)))))))

(defvar make-done nil)

(defun make-sentinel (process string)
  (dolist (one-item error-list)
    (apply #'fix-one-instance one-item))
  (setq make-done t))

(defun recompile-emacs ()
  (let* ((default-directory emacs-build)
	 (output-buffer (get-buffer-create "*recompile*"))
	 (exec-path (cons gcc-bin-dir exec-path))
	 (make (start-process "make" output-buffer "make" "-k"
			      (concat "CC=" gcc-bin-dir 
				      "gcc -ftrack-macro-expansion=2"))))
    (set-process-filter make #'make-filter)
    (set-process-sentinel make #'make-sentinel)
    (while (not make-done)
      (accept-process-output))))

(modify-buffer.h)
(modify-buffer.c)
(modify-lisp.h)
(update-header-files)
(recompile-emacs)
(dolist (buf (buffer-list))
  (with-current-buffer buf
    (when buffer-file-name
      (message "Saving %s" buffer-file-name)
      (save-buffer))))

[-- Attachment #3: the patch --]
[-- Type: application/x-gzip, Size: 56413 bytes --]

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-27 20:18 Patch for fields of `struct buffer' Tom Tromey
@ 2011-01-28  7:37 ` Eli Zaretskii
  2011-01-28  8:58   ` Tom Tromey
  2011-01-28 14:55 ` Stefan Monnier
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 123+ messages in thread
From: Eli Zaretskii @ 2011-01-28  7:37 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> From: Tom Tromey <tromey@redhat.com>
> Date: Thu, 27 Jan 2011 13:18:37 -0700
> 
> This is where volunteers come in.  We could either proceed by
> committing the patch and fixing the problems piecemeal, or by having a
> couple people with other systems apply the patch, do a build, and send
> me the logs (or patches relative to mine), then repeat.  You would not
> need a modified GCC to do this step; I don't expect enough problems to
> warrant more automation.

Could this please be postponed until the Windows build is working
again?  I hope to make this done this weekend (unless I bump into some
unanticipated trouble).

TIA



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28  7:37 ` Eli Zaretskii
@ 2011-01-28  8:58   ` Tom Tromey
  2011-01-28  9:29     ` Eli Zaretskii
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-01-28  8:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:

Eli> Could this please be postponed until the Windows build is working
Eli> again?

Sure, I think that is a good idea.  Could you post a note when it works?
I am not likely to notice.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28  8:58   ` Tom Tromey
@ 2011-01-28  9:29     ` Eli Zaretskii
  2011-01-29 12:50       ` Eli Zaretskii
  0 siblings, 1 reply; 123+ messages in thread
From: Eli Zaretskii @ 2011-01-28  9:29 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> From: Tom Tromey <tromey@redhat.com>
> Cc: emacs-devel@gnu.org
> Date: Fri, 28 Jan 2011 01:58:19 -0700
> 
> >>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
> 
> Eli> Could this please be postponed until the Windows build is working
> Eli> again?
> 
> Sure, I think that is a good idea.  Could you post a note when it works?

Will do.  A lot of people are impatient ;-)



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-27 20:18 Patch for fields of `struct buffer' Tom Tromey
  2011-01-28  7:37 ` Eli Zaretskii
@ 2011-01-28 14:55 ` Stefan Monnier
  2011-01-28 17:38   ` Tom Tromey
  2011-01-28 17:23 ` Kim F. Storm
  2011-01-29 16:18 ` Richard Stallman
  3 siblings, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-28 14:55 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Emacs discussions

> Here is the promised change to buffer fields.

Please make the "#define BUF_FOO(BUF) ((BUF)->foo_)" to be
auto-generated (they could go into global.h).
Oh and the arg shojuld be `buf' rather than `BUF'.

I'd also be happier if the buffer.h code that defines the fields used
names without _ (so they'd have to be passed to a macro that adds the _).
Similarly the alloc.c code should ideally not hard-code the "add an _"
at every use but instead use some kind of macro call like
BUFFER_INTERNAL_FIELD(foo) that would return "foo_".


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-27 20:18 Patch for fields of `struct buffer' Tom Tromey
  2011-01-28  7:37 ` Eli Zaretskii
  2011-01-28 14:55 ` Stefan Monnier
@ 2011-01-28 17:23 ` Kim F. Storm
  2011-01-28 17:36   ` Tom Tromey
  2011-01-28 18:29   ` Stefan Monnier
  2011-01-29 16:18 ` Richard Stallman
  3 siblings, 2 replies; 123+ messages in thread
From: Kim F. Storm @ 2011-01-28 17:23 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Emacs discussions

Tom Tromey <tromey@redhat.com> writes:

> Here is the promised change to buffer fields.
>
> I need volunteers to complete this patch; or at least the ok on
> proceeding to temporarily break the build.  See below for details.
>

Just wondering how "unreadable" the resulting code becomes with
all those new macros ....

Rather than defining all the individual BUF_xxxx(buf) macros 
for each field buf->xxxx field, would it be possible to factor
this out in a single accessor macro like

      B_(buf, XXXX)

If necessary, behind the scenes (by help of the proprocessor),
this could further map into a BUF_xxxx(buf) macro, but I don't
know what kind of mapping the BUF_XXXX macros are supposed to
do, so I cannot say whether it is possible or not...

Kim




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 17:23 ` Kim F. Storm
@ 2011-01-28 17:36   ` Tom Tromey
  2011-01-28 18:29   ` Stefan Monnier
  1 sibling, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-28 17:36 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Emacs discussions

>>>>> "Kim" == Kim F Storm <no-spam@cua.dk> writes:

Kim> Just wondering how "unreadable" the resulting code becomes with
Kim> all those new macros ....

I find it pretty much in keeping with the already heavy macroization in
emacs, but YMMV.  Take a glance at the patch -- nearly any part will
do -- and let me know what you think.

Kim> Rather than defining all the individual BUF_xxxx(buf) macros 
Kim> for each field buf->xxxx field, would it be possible to factor
Kim> this out in a single accessor macro like
Kim>       B_(buf, XXXX)
Kim> If necessary, behind the scenes (by help of the proprocessor),
Kim> this could further map into a BUF_xxxx(buf) macro, but I don't
Kim> know what kind of mapping the BUF_XXXX macros are supposed to
Kim> do, so I cannot say whether it is possible or not...

Yes, this would work.  I will implement it if it is generally agreed
upon, or more specifically if Stefan wants it this way :-)

The key thing is to intercept all references to the field, either rvalue
or lvalue, to introduce an indirection.  On the concurrency branch, a
sample macro will look something like:

#define BUF_NAME(buf) *find_variable_location (&((buf)->name_))

find_variable_location looks to see if its argument has a
thread-local binding.  It may return its argument, a pointer to the
thread-local slot, or a pointer to the global slot, depending on what is
stored in the field.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 14:55 ` Stefan Monnier
@ 2011-01-28 17:38   ` Tom Tromey
  2011-01-28 18:27     ` Stefan Monnier
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-01-28 17:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs discussions

Stefan> Please make the "#define BUF_FOO(BUF) ((BUF)->foo_)" to be
Stefan> auto-generated (they could go into global.h).

Ok, I will look at this.
I think it will mean first making the current global.h be generated.
At least, that will make it simpler.

Stefan> Oh and the arg shojuld be `buf' rather than `BUF'.

Stefan> I'd also be happier if the buffer.h code that defines the fields
Stefan> used names without _ (so they'd have to be passed to a macro
Stefan> that adds the _).  Similarly the alloc.c code should ideally not
Stefan> hard-code the "add an _" at every use but instead use some kind
Stefan> of macro call like BUFFER_INTERNAL_FIELD(foo) that would return
Stefan> "foo_".

I implemented all these things.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 17:38   ` Tom Tromey
@ 2011-01-28 18:27     ` Stefan Monnier
  2011-01-28 18:42       ` Tom Tromey
  0 siblings, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-28 18:27 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Emacs discussions

Stefan> Please make the "#define BUF_FOO(BUF) ((BUF)->foo_)" to be
Stefan> auto-generated (they could go into global.h).

> Ok, I will look at this.
> I think it will mean first making the current global.h be generated.

Yes, indeed.  BTW, glancing at globals.h, why are <foo>_consed in
emacs_globals?

> I implemented all these things.

Good, thanks.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 17:23 ` Kim F. Storm
  2011-01-28 17:36   ` Tom Tromey
@ 2011-01-28 18:29   ` Stefan Monnier
  2011-01-29  2:34     ` Miles Bader
  1 sibling, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-28 18:29 UTC (permalink / raw)
  To: Kim F. Storm; +Cc: Tom Tromey, Emacs discussions

> Rather than defining all the individual BUF_xxxx(buf) macros 
> for each field buf->xxxx field, would it be possible to factor
> this out in a single accessor macro like

>       B_(buf, XXXX)

That sounds even better, yes.

> If necessary, behind the scenes (by help of the proprocessor),
> this could further map into a BUF_xxxx(buf) macro, but I don't

I don't think that would be necessary, because I think the treatment is
the same for all fields.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 18:27     ` Stefan Monnier
@ 2011-01-28 18:42       ` Tom Tromey
  2011-01-28 20:04         ` Stefan Monnier
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-01-28 18:42 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs discussions

Stefan> Yes, indeed.  BTW, glancing at globals.h, why are <foo>_consed in
Stefan> emacs_globals?

There are a bunch of DEFVAR_INTs in alloc.c that refer to them.

It is sort of a weird case since I think it doesn't really make sense to
let-bind these.  However, it is possible, and it was simpler to just let
the script update everything.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 18:42       ` Tom Tromey
@ 2011-01-28 20:04         ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-01-28 20:04 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Emacs discussions

Stefan> Yes, indeed.  BTW, glancing at globals.h, why are <foo>_consed in
Stefan> emacs_globals?

> There are a bunch of DEFVAR_INTs in alloc.c that refer to them.

Duh!  Sorry, I didn't know about those Lisp vars and it didn't even
occur to me that they could be exposed to Lisp.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28 18:29   ` Stefan Monnier
@ 2011-01-29  2:34     ` Miles Bader
  2011-01-29  3:58       ` Stefan Monnier
  0 siblings, 1 reply; 123+ messages in thread
From: Miles Bader @ 2011-01-29  2:34 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Tom Tromey, Emacs discussions, Kim F. Storm

Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>       B_(buf, XXXX)
>
> That sounds even better, yes.

If by "better" you mean "less readable and more confusing"...

The BUF_xxxx(b) syntax may be slightly more verbose, but it's very
familiar and idiomatic.

-Miles

-- 
Christian, n. One who follows the teachings of Christ so long as they are not
inconsistent with a life of sin.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-29  2:34     ` Miles Bader
@ 2011-01-29  3:58       ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-01-29  3:58 UTC (permalink / raw)
  To: Miles Bader; +Cc: Tom Tromey, Emacs discussions, Kim F. Storm

>>> B_(buf, XXXX)
>> That sounds even better, yes.
> If by "better" you mean "less readable and more confusing"...

Apparently it's a question of taste, but I feel it's good when the
symbol I see in the declaration of a field/variable is the same
(literally, and not uppercased or anything) as the one I see in the code
that accesses this field/variable.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-28  9:29     ` Eli Zaretskii
@ 2011-01-29 12:50       ` Eli Zaretskii
  2011-01-29 13:33         ` Juanma Barranquero
  0 siblings, 1 reply; 123+ messages in thread
From: Eli Zaretskii @ 2011-01-29 12:50 UTC (permalink / raw)
  To: tromey; +Cc: emacs-devel

> Date: Fri, 28 Jan 2011 11:29:56 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: emacs-devel@gnu.org
> 
> > From: Tom Tromey <tromey@redhat.com>
> > Cc: emacs-devel@gnu.org
> > Date: Fri, 28 Jan 2011 01:58:19 -0700
> > 
> > >>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
> > 
> > Eli> Could this please be postponed until the Windows build is working
> > Eli> again?
> > 
> > Sure, I think that is a good idea.  Could you post a note when it works?
> 
> Will do.  A lot of people are impatient ;-)

I have now committed to the trunk revision 103022 which should repair
the Emacs build on MS-Windows.  People who build Emacs on Windows
please try it and report any problems left.

Caveats:

  . Bootstrap wasn't tested.  If someone has time for that, please try
    and report any left-overs.

  . I don't have MSVC installed, so I only built using MinGW.

  . I needed to port revision 100423 from emacs-23 branch, which was
    not yet merged into trunk, to fix the bug introduced by the branch
    revision 100409 (which was already merged into trunk).  So when
    the next merge from the branch into trunk is done, this could
    cause extra conflicts; sorry about that.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-29 12:50       ` Eli Zaretskii
@ 2011-01-29 13:33         ` Juanma Barranquero
  2011-01-29 13:42           ` Eli Zaretskii
  0 siblings, 1 reply; 123+ messages in thread
From: Juanma Barranquero @ 2011-01-29 13:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tromey, emacs-devel

On Sat, Jan 29, 2011 at 13:50, Eli Zaretskii <eliz@gnu.org> wrote:

>  . Bootstrap wasn't tested.  If someone has time for that, please try
>    and report any left-overs.

windres -O coff --include-dir ../nt -o oo-spd/i386/emacs.res ../nt/emacs.rc
make[2]: Leaving directory `C:/emacs/src'
make[2]: *** No rule to make target `../lib/oo-spd/i386/libgnu.a',
needed by `oo-spd/i386/temacs.exe'.  Stop.
make[1]: *** [bootstrap-temacs] Error 2
make[1]: Leaving directory `C:/emacs/src'
make: *** [bootstrap-gmake] Error 2
src\oo-spd\i386\emacs.exe does not exit

    Juanma



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-29 13:33         ` Juanma Barranquero
@ 2011-01-29 13:42           ` Eli Zaretskii
  2011-02-02 18:17             ` Juanma Barranquero
  0 siblings, 1 reply; 123+ messages in thread
From: Eli Zaretskii @ 2011-01-29 13:42 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: tromey, emacs-devel

> From: Juanma Barranquero <lekktu@gmail.com>
> Date: Sat, 29 Jan 2011 14:33:02 +0100
> Cc: tromey@redhat.com, emacs-devel@gnu.org
> 
> windres -O coff --include-dir ../nt -o oo-spd/i386/emacs.res ../nt/emacs.rc
> make[2]: Leaving directory `C:/emacs/src'
> make[2]: *** No rule to make target `../lib/oo-spd/i386/libgnu.a',
> needed by `oo-spd/i386/temacs.exe'.  Stop.
> make[1]: *** [bootstrap-temacs] Error 2
> make[1]: Leaving directory `C:/emacs/src'
> make: *** [bootstrap-gmake] Error 2

Thanks.  Please try again.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-27 20:18 Patch for fields of `struct buffer' Tom Tromey
                   ` (2 preceding siblings ...)
  2011-01-28 17:23 ` Kim F. Storm
@ 2011-01-29 16:18 ` Richard Stallman
  2011-01-30 20:23   ` Tom Tromey
  3 siblings, 1 reply; 123+ messages in thread
From: Richard Stallman @ 2011-01-29 16:18 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

    In order to implement thread-specific let-binding of buffer-local
    variables, we must introduce an indirection into the C code, so that
    lookups of these variables see the thread-specific value, if any.

This makes thread-switching faster but makes access slower.  Moreover,
it is a big change.  Why not use a mechanism like that of buffer-local
variables?  It would be much easier and perhaps better.

I hope you are not trying to implement truly asynchronous thread
switching, because that is going to cause lots of timing errors
in C code that isn't ready for this.

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-29 16:18 ` Richard Stallman
@ 2011-01-30 20:23   ` Tom Tromey
  2011-01-31  4:04     ` Stefan Monnier
  2011-01-31 19:37     ` Richard Stallman
  0 siblings, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-30 20:23 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

Tom>     In order to implement thread-specific let-binding of buffer-local
Tom>     variables, we must introduce an indirection into the C code, so that
Tom>     lookups of these variables see the thread-specific value, if any.

RMS> This makes thread-switching faster but makes access slower.

Yes.  I think that is the right tradeoff given my long term goal, which
is preemptive multi-threading.

Also, the cost from this patch (and its successor) only applies to
DEFVAR_PER_BUFFER and DEFVAR_KBOARD variables.  That is because these
are the only variables which are referred to by C code and which also
already require a double indirection.  Ordinary DEFVARs will be handled
by a much more efficient approach, and ordinary Lisp variables are
already reasonably expensive.  See below for a full explanation.

RMS> Moreover, it is a big change.  Why not use a mechanism like that of
RMS> buffer-local variables?  It would be much easier and perhaps
RMS> better.

Thread-local bindings in most cases will involve a variable forwarding
object akin to Lisp_Buffer_Local_Value.  There are several cases to
consider.

* DEFVAR_LISP and other true globals.
  These will be handled efficiently by using pointer tricks.  Each
  global will have a corresponding pointer to it, and each thread will
  have its own copy of all of these.  A given pointer will either point
  to the main thread's slot, or the current thread's slot, depending on
  whether the variable in question is let-bound.
  That is:

     struct emacs_globals {
        Lisp_Var f_something;
        Lisp_Var *f_something_ptr;
     };
     #define something *(current_thread->f_something_ptr)

  I think the performance overhead of this is pretty minimal,
  particularly on systems with decent TLS support.  GNU/Linux has this.

  This has some space overhead.  Each new thread will need a few K of
  memory just to start up.

* DEFVAR_PER_BUFFER and DEFVAR_KBOARD.
  Currently in the C code these are referenced directly in struct buffer.
  For the threading code, when there is a let-binding, we will put a
  Lisp_ThreadLocal object into the slot instead.  A Lisp_ThreadLocal is
  a forwarding object somewhat like Lisp_Buffer_Local_Value; it has a
  slot for the variable's global value and then an alist mapping threads
  to values.

  The overhead here could perhaps be reduced by use of an inline
  function that checks for the common case of no thread-local binding,
  something like:

  inline Lisp_Object *find_slot (Lisp_Object *field) {
    if (likely (! THREADLOCALP (*field)))
      return field;
    return find_variable_location (field);
  }

  #define B_(buf, field)  *find_slot (&((buf)->field))

* Ordinary Lisp variables, not defined by C code.
  These will always involve an indirection through find_variable_location.
  However, ordinary Lisp variable access may already involve various
  indirections due to Lisp_Buffer_Local_Value, Lisp_Buffer_Objfwd, etc.
  I think another possible indirection is probably not too bad.  We
  could use the same inline function here to minimize the cost.

RMS> I hope you are not trying to implement truly asynchronous thread
RMS> switching, because that is going to cause lots of timing errors
RMS> in C code that isn't ready for this.

Yes, I realize this.  My initial goal is to implement cooperative
threading only (with I/O considered as a yield point as well).  In fact,
I think we will probably have to be even more restrictive than this, and
disallow background threads from redisplay and the debugger (though I am
not positive, there is a lot there that I do not know about).

However, in the long run I would like to see preemptive threading.  I
would rather make decisions now that support this goal, and I believe
that planning to do any work at all at thread-switch time is bad for
this.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-30 20:23   ` Tom Tromey
@ 2011-01-31  4:04     ` Stefan Monnier
  2011-01-31 14:29       ` Tom Tromey
  2011-01-31 19:37     ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31  4:04 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> Yes.  I think that is the right tradeoff given my long term goal, which
> is preemptive multi-threading.

Actually the long term goal is true concurrency, to make use of the
insane number of cores we'll have by them.

RMS> Moreover, it is a big change.  Why not use a mechanism like that of
RMS> buffer-local variables?  It would be much easier and perhaps
RMS> better.

I do not care too much about the mechanism itself.  What matters to me is:
- the semantics exposed to Elisp, whee the main qualities are
  cleanliness, compatibility with existing code, and compatibility with
  the future goal of concurrency.
- the changes to the code base.

To the extent that they're hidden behind macros, the current changes
seem fine (the move of vars to globals.h is not, tho, which is why
I want globals.h to be auto-generated).

> However, in the long run I would like to see preemptive threading.
> I would rather make decisions now that support this goal, and
> I believe that planning to do any work at all at thread-switch time is
> bad for this.

While I largely agree, I do not presume that the mechanism you use now
is necessarily going to stay.  So it's important that it stay
well encapsulated.


        Stefan


PS: BTW, the special Lisp_Object values like Lisp_Buffer_Local_Value have
disappeared on the trunk, replaced by extra bits in the Symbol objects.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31  4:04     ` Stefan Monnier
@ 2011-01-31 14:29       ` Tom Tromey
  2011-01-31 15:22         ` Stefan Monnier
                           ` (3 more replies)
  0 siblings, 4 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 14:29 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

Stefan> I do not care too much about the mechanism itself.  What matters
Stefan> to me is:

Stefan> - the semantics exposed to Elisp, whee the main qualities are
Stefan>   cleanliness, compatibility with existing code, and compatibility with
Stefan>   the future goal of concurrency.

I have a bunch of questions here that I'll bring up later, in a
different message.

One easy one is whether a new thread should inherit thread-local
bindings from its parent thread.  Our initial implementation did
inherit, but later I found out that this is not common in the Lisp
world.

I.E., what should this display?

(defvar var 0)
(let ((var 1))
  (run-in-thread (lambda () (message "%d" var))))

Stefan> To the extent that they're hidden behind macros, the current changes
Stefan> seem fine (the move of vars to globals.h is not, tho, which is why
Stefan> I want globals.h to be auto-generated).

I can do this after my current patch is done.

Stefan> PS: BTW, the special Lisp_Object values like
Stefan> Lisp_Buffer_Local_Value have disappeared on the trunk, replaced
Stefan> by extra bits in the Symbol objects.

Yeah, I was mostly looking at the concurrency branch when writing.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 14:29       ` Tom Tromey
@ 2011-01-31 15:22         ` Stefan Monnier
  2011-01-31 15:30           ` Tom Tromey
  2011-01-31 16:46         ` David De La Harpe Golden
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 15:22 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> One easy one is whether a new thread should inherit thread-local
> bindings from its parent thread.  Our initial implementation did
> inherit, but later I found out that this is not common in the Lisp
> world.

> I.E., what should this display?

> (defvar var 0)
> (let ((var 1))
>   (run-in-thread (lambda () (message "%d" var))))

I think any choice is acceptable, from a semantics point of view.
Maybe one of the two choices is "superior" in some sense, but it's not
clear which, and I doubt it matters much.  So I think the option that
leads to the cleaner code (ideally, both for the current code, and for
any foreseeable alternative implementation we decide to use in some
distant future) should be preferred.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 15:22         ` Stefan Monnier
@ 2011-01-31 15:30           ` Tom Tromey
  2011-01-31 17:02             ` Stefan Monnier
  2011-01-31 20:00             ` Stefan Monnier
  0 siblings, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 15:30 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

>>>>> "Stefan" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> (defvar var 0)
>> (let ((var 1))
>> (run-in-thread (lambda () (message "%d" var))))

Stefan> I think any choice is acceptable, from a semantics point of view.
Stefan> Maybe one of the two choices is "superior" in some sense, but it's not
Stefan> clear which, and I doubt it matters much.  So I think the option that
Stefan> leads to the cleaner code (ideally, both for the current code, and for
Stefan> any foreseeable alternative implementation we decide to use in some
Stefan> distant future) should be preferred.

Ok, thanks.

I will probably keep the current approach (the above shows "1"), since
the hair is all isolated in the thread-creation function, and since this
is how I expected it to work in the first place.


Another thing I realized I don't know is how thread-local let-bindings
ought to interact with lexbind.  That is, if you make a closure, and
then in the body of it you let-bind one of its captured variables, is
that let-binding thread-local?

Offhand I would say "yes", but presumably this implies a performance hit
where there was none before.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 14:29       ` Tom Tromey
  2011-01-31 15:22         ` Stefan Monnier
@ 2011-01-31 16:46         ` David De La Harpe Golden
  2011-01-31 19:04           ` Tom Tromey
  2011-01-31 19:38         ` Richard Stallman
  2011-02-01 18:26         ` Tom Tromey
  3 siblings, 1 reply; 123+ messages in thread
From: David De La Harpe Golden @ 2011-01-31 16:46 UTC (permalink / raw)
  To: emacs-devel

On 31/01/11 14:29, Tom Tromey wrote:

> One easy one is whether a new thread should inherit thread-local
> bindings from its parent thread.  Our initial implementation did
> inherit, but later I found out that this is not common in the Lisp
> world.

I'd suggest going with CL afaik-now-most-common-practice and not 
inherit. Isn't that easier implementation-wise anyway?

General api similarity to CL bordeaux-threads if doing conventional 
threads seems reasonable - I haven't thought especially deeply about it, 
but I doubt emacs lisp needs are particularly different to CL, and 
threading is no longer a new thing in CL land.

You can see the bordeaux threads api documentation without diving into 
any implementation source code (the reference implementation's license 
is open, but anyway):

http://trac.common-lisp.net/bordeaux-threads/wiki/ApiDocumentation

Because historically some CLs did one thing and others the other, you 
can see it recommends all bindings are redone anyway in portable code.

Also note how recent bordeaux-threads' make-thread takes an 
initial-bindings alist arg though, that defaults to the local value of 
*default-special-bindings*. So not "simply" inheriting local let 
bindings doesn't mean you can't provide a mechanism for establishing 
some thread-local initial bindings that don't correspond to the globals 
when you do want to do that - in fact you'll ultimately probably *want* to
have such a mechanism, some things are likely "naturally thread local".

The current version of that spec for the aforementioned 
initial-bindings/*default-special-bindings*  considers it an open 
question  whether the binding forms are evaluated in the original or new 
thread, but I expect new thread makes more sense, and is what recent 
clisp does:

http://clisp.sourceforge.net/impnotes/mt.html#make-thread

(clisp also has symbol-value-thread, for accessing thread-local
bindings).

OTOH, maybe someone who's been writing multithreaded lisp recently might 
want to chime in...





^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 15:30           ` Tom Tromey
@ 2011-01-31 17:02             ` Stefan Monnier
  2011-01-31 18:38               ` Tom Tromey
  2011-01-31 20:00             ` Stefan Monnier
  1 sibling, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 17:02 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> Another thing I realized I don't know is how thread-local let-bindings
> ought to interact with lexbind.

Good you mention, I was indeed just thinking that I had forgotten to
mention that the concurrency patch should be designed with the
assumption that all the code that natters can/will use lexical scoping
(i.e. dynamic let bindings of variables that are not buffer-local and
have no global value will be pretty much non-existent or not
performance-relevant).

> That is, if you make a closure, and then in the body of it you
> let-bind one of its captured variables, is that let-binding
> thread-local?

Variables that are captured by a closure are (by definition) lexically
scoped, so they should not be affected by
buffer/thread/keyboard-localness which only applies to
dynamically-scoped variables.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 17:02             ` Stefan Monnier
@ 2011-01-31 18:38               ` Tom Tromey
  2011-01-31 20:03                 ` Stefan Monnier
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 18:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

Tom> That is, if you make a closure, and then in the body of it you
Tom> let-bind one of its captured variables, is that let-binding
Tom> thread-local?

Stefan> Variables that are captured by a closure are (by definition) lexically
Stefan> scoped, so they should not be affected by
Stefan> buffer/thread/keyboard-localness which only applies to
Stefan> dynamically-scoped variables.

Ok, I think I see.  I was trying to construct a test case and, IIUC, an
inner `let' would make a new lexically-bound variable, not dynamically
bind the outer one.  Is that correct?

I would try it but last time I checked out lexbind, I couldn't get it to
build.  Is it working now?

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 16:46         ` David De La Harpe Golden
@ 2011-01-31 19:04           ` Tom Tromey
  2011-01-31 22:08             ` David De La Harpe Golden
                               ` (2 more replies)
  0 siblings, 3 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 19:04 UTC (permalink / raw)
  To: David De La Harpe Golden; +Cc: emacs-devel

>>>>> "David" == David De La Harpe Golden <david@harpegolden.net> writes:

Tom> One easy one is whether a new thread should inherit thread-local
Tom> bindings from its parent thread.  Our initial implementation did
Tom> inherit, but later I found out that this is not common in the Lisp
Tom> world.

David> I'd suggest going with CL afaik-now-most-common-practice and not
David> inherit. Isn't that easier implementation-wise anyway?

Not notably, especially since this code is already written.
(I did notice a bug on the branch ... but whatever, it is easy to fix.)

David> General api similarity to CL bordeaux-threads if doing conventional
David> threads seems reasonable - I haven't thought especially deeply about
David> it, but I doubt emacs lisp needs are particularly different to CL, and
David> threading is no longer a new thing in CL land.
...
David> http://trac.common-lisp.net/bordeaux-threads/wiki/ApiDocumentation

I am quite sympathetic to this idea, but at the same time, Emacs Lisp is
not CL, so I think the field is more open.  BTW, thanks for the pointer.

I've been kicking around different ideas for how everything should fit
together.  The API at that URL is basically the "simple reflection of
POSIX threads" model.

Other ideas I have been considering:

Instead of explicit locks, just let any symbol function as a lock, and
have the locks hidden in the C code.  (Or an extension of this idea, let
any Lisp object be a lock -- "Java style".)

Or, instead of the locks-and-condition-variables approach, go the CSP
route and have channels and channel-select.  This idea is making a
comeback, maybe it would fit well in Emacs Lisp.

I welcome input on this topic.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-30 20:23   ` Tom Tromey
  2011-01-31  4:04     ` Stefan Monnier
@ 2011-01-31 19:37     ` Richard Stallman
  2011-01-31 19:57       ` Tom Tromey
                         ` (2 more replies)
  1 sibling, 3 replies; 123+ messages in thread
From: Richard Stallman @ 2011-01-31 19:37 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

    Yes.  I think that is the right tradeoff given my long term goal, which
    is preemptive multi-threading.

I don't think preemptive thread switching is a sensible goal.  It is
so much trouble that it isn't worth doing even in the long term.
Thus, it is a mistake to do much work now, or complicate the code now,
or cause a slowdown now, for the sake of preemptive thread switching.

    Also, the cost from this patch (and its successor) only applies to
    DEFVAR_PER_BUFFER and DEFVAR_KBOARD variables.

That is more limited than I thought it was.  If it is needed for
non-preemptive thread switching, the benefit would justify the cost,
but I think it isn't needed for that.  If this is would only be needed
for preemptive thread switching, I think the loss of clarity and
naturalness of the code is enough reason not to do it.

Meanwhile, I am concerned about this:

    * DEFVAR_LISP and other true globals.
      These will be handled efficiently by using pointer tricks.  Each
      global will have a corresponding pointer to it, and each thread will
      have its own copy of all of these.

That is incorrect semantics.  Most ofthese values should be shared
between all the threads that don't bind them somehow, just as they
are shared between all the buffers that don't bind them.

    * Ordinary Lisp variables, not defined by C code.
      These will always involve an indirection through find_variable_location.
      However, ordinary Lisp variable access may already involve various
      indirections due to Lisp_Buffer_Local_Value, Lisp_Buffer_Objfwd, etc.

Are you saying you would like to change it so that every access to
a Lisp variable requires indirecting?

At present, every access to a Lisp variable requires a test for
possible indirections, but most variables don't have an indirection.

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 14:29       ` Tom Tromey
  2011-01-31 15:22         ` Stefan Monnier
  2011-01-31 16:46         ` David De La Harpe Golden
@ 2011-01-31 19:38         ` Richard Stallman
  2011-02-01 18:26         ` Tom Tromey
  3 siblings, 0 replies; 123+ messages in thread
From: Richard Stallman @ 2011-01-31 19:38 UTC (permalink / raw)
  To: Tom Tromey; +Cc: monnier, emacs-devel

    One easy one is whether a new thread should inherit thread-local
    bindings from its parent thread.  Our initial implementation did
    inherit, but later I found out that this is not common in the Lisp
    world.

    I.E., what should this display?

    (defvar var 0)
    (let ((var 1))
      (run-in-thread (lambda () (message "%d" var))))

You are talking about ordinary local bindings.  They would be
per-thread, but not specifically related to threading.

I would expect "thread-local bindings" to refer to a feature similar
to buffer-local bindings, and controlled through a similar set of
functions.  I think these should never be copied to a new thread,
just as buffer-local bindings are never copied to a new buffer.

As for local bindings in the thread, it might make sense to copy them
into the new thread when the function is a lambda, and not copy them
when the function is a symbol.  Or perhaps have two functions to start
a thread, `run-in-nested-thread' and `run-in-global-thread', to make
both options available.

Or maybe have a macro to start a new thread and copy the local bindings,

  (with-temp-thread body...)

while using a function to start a new thread with no local bindings.



-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:37     ` Richard Stallman
@ 2011-01-31 19:57       ` Tom Tromey
  2011-02-01  2:42         ` Tom Tromey
  2011-02-01 16:40         ` Richard Stallman
  2011-01-31 20:30       ` Stefan Monnier
  2011-02-01 10:26       ` Daniel Colascione
  2 siblings, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 19:57 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

RMS> I don't think preemptive thread switching is a sensible goal.  It
RMS> is so much trouble that it isn't worth doing even in the long term.

I don't think it is nearly that bad.

RMS> That is more limited than I thought it was.  If it is needed for
RMS> non-preemptive thread switching, the benefit would justify the cost,
RMS> but I think it isn't needed for that.  If this is would only be needed
RMS> for preemptive thread switching, I think the loss of clarity and
RMS> naturalness of the code is enough reason not to do it.

Ok.  I will stop work on this patch, then.  I am not sure if I am
interested in working on threads done the other way, I will have to
think about it.

You might want to consider backing out my earlier patch.  It won't be
needed either.

Tom>     * DEFVAR_LISP and other true globals.
Tom>       These will be handled efficiently by using pointer tricks.  Each
Tom>       global will have a corresponding pointer to it, and each thread will
Tom>       have its own copy of all of these.

RMS> That is incorrect semantics.  Most ofthese values should be shared
RMS> between all the threads that don't bind them somehow, just as they
RMS> are shared between all the buffers that don't bind them.

I wasn't clear enough.

For each global variable, the per-thread pointer will ordinarily point
to the main thread's slot.  When the variable is let-bound, thus
becoming thread-local, the pointer will be redirected to the slot in the
per-thread structure.  When the outermost let-binding is undone, the
pointer will be reset to the main thread's slot.

I think this implements the correct semantics: a global variable's value
is shared between all threads, and a let-bound variable is thread-local.

RMS> Are you saying you would like to change it so that every access to
RMS> a Lisp variable requires indirecting?

Only potentially -- like today.

RMS> At present, every access to a Lisp variable requires a test for
RMS> possible indirections, but most variables don't have an indirection.

That will continue to be the case.  We can add another value to enum
symbol_redirect to indicate variables which are potentially
thread-local.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 15:30           ` Tom Tromey
  2011-01-31 17:02             ` Stefan Monnier
@ 2011-01-31 20:00             ` Stefan Monnier
  2011-01-31 20:05               ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 20:00 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> I will probably keep the current approach (the above shows "1"), since
> the hair is all isolated in the thread-creation function, and since this
> is how I expected it to work in the first place.

BTW, I think the option 1 of sharing between threads might lead to
complications in some implementations, since we now have variables which
are neither global nor specific to a single thread but are shared by
some subset of all threads.

If those vars are never `setq'd, it's OK because this sharing can be
eliminated by copying their values, but since we don't have such
guarantees, it sounds like option 2 of "no sharing" is more future-proof.

We can provide ways to transfer the value (but just the value) of some
variables from a parent to his child.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 18:38               ` Tom Tromey
@ 2011-01-31 20:03                 ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 20:03 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

Stefan> Variables that are captured by a closure are (by definition) lexically
Stefan> scoped, so they should not be affected by
Stefan> buffer/thread/keyboard-localness which only applies to
Stefan> dynamically-scoped variables.

> Ok, I think I see.  I was trying to construct a test case and, IIUC, an
> inner `let' would make a new lexically-bound variable, not dynamically
> bind the outer one.  Is that correct?

Exactly.  Basically, lexically scoped vars don't use the symbol's
`value' cell at all, so their values only reside on the stack and other
such places and they should interact with concurrency without any extra
work, just like normal local C variables.

> I would try it but last time I checked out lexbind, I couldn't get it to
> build.  Is it working now?

I could build it last time I tried it, but I haven't tried recently, and
it's been even (much) longer since I last bootstrapped it.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 20:00             ` Stefan Monnier
@ 2011-01-31 20:05               ` Tom Tromey
  2011-01-31 20:40                 ` Stefan Monnier
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 20:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

>>>>> "Stefan" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

Tom> I will probably keep the current approach (the above shows "1"), since
Tom> the hair is all isolated in the thread-creation function, and since this
Tom> is how I expected it to work in the first place.

Stefan> BTW, I think the option 1 of sharing between threads might lead to
Stefan> complications in some implementations, since we now have variables which
Stefan> are neither global nor specific to a single thread but are shared by
Stefan> some subset of all threads.

Aha.  I was unclear here.

In my implementation, variables let-bound in the parent thread are just
re-let-bound in the new thread.  The bindings are not shared.

I hadn't even considered this idea.

Stefan> We can provide ways to transfer the value (but just the value) of some
Stefan> variables from a parent to his child.

Perhaps copying CL is the way to go, then.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:37     ` Richard Stallman
  2011-01-31 19:57       ` Tom Tromey
@ 2011-01-31 20:30       ` Stefan Monnier
  2011-01-31 20:49         ` Tom Tromey
  2011-02-01 12:09         ` Stephen J. Turnbull
  2011-02-01 10:26       ` Daniel Colascione
  2 siblings, 2 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 20:30 UTC (permalink / raw)
  To: rms; +Cc: Tom Tromey, emacs-devel

> I don't think preemptive thread switching is a sensible goal.  It is
> so much trouble that it isn't worth doing even in the long term.

I don't think we will get to choose.  The alternative will be to switch
to some other language that does provide threading.  But let's not get
into this discussion because I believe it is not relevant to the problem
at hand.

> Thus, it is a mistake to do much work now, or complicate the code now,
> or cause a slowdown now, for the sake of preemptive thread switching.

AFAICT, none of what he did is done because of preemptive threading.
IOW, I don't think you can do it much more simply, even if you assume
a cooperative threading model.

> That is more limited than I thought it was.  If it is needed for
> non-preemptive thread switching, the benefit would justify the cost,
> but I think it isn't needed for that.  If this is would only be needed
> for preemptive thread switching, I think the loss of clarity and
> naturalness of the code is enough reason not to do it.

I don't think this is "only needed for preemptive thread scheduling".


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 20:05               ` Tom Tromey
@ 2011-01-31 20:40                 ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 20:40 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> In my implementation, variables let-bound in the parent thread are just
> re-let-bound in the new thread.  The bindings are not shared.

Ah, I see.  That's much less problematic, thanks.

> Perhaps copying CL is the way to go, then.

If it's not more trouble, I think it makes sense, yes.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 20:30       ` Stefan Monnier
@ 2011-01-31 20:49         ` Tom Tromey
  2011-01-31 21:54           ` Stefan Monnier
  2011-02-01 16:39           ` Richard Stallman
  2011-02-01 12:09         ` Stephen J. Turnbull
  1 sibling, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-01-31 20:49 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

RMS> Thus, it is a mistake to do much work now, or complicate the code now,
RMS> or cause a slowdown now, for the sake of preemptive thread switching.

Stefan> AFAICT, none of what he did is done because of preemptive threading.
Stefan> IOW, I don't think you can do it much more simply, even if you assume
Stefan> a cooperative threading model.

Yeah, you could.  On a thread-switch, you could unwind all the old
thread's bindings, then restore the new thread's bindings.

This would let all the existing C code work without indirections or
macro trickery; the downsides are that you have to have user-space
control over thread switching, and thread switching becomes expensive.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 20:49         ` Tom Tromey
@ 2011-01-31 21:54           ` Stefan Monnier
  2011-02-13 19:01             ` Richard Stallman
  2011-02-01 16:39           ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-01-31 21:54 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> Yeah, you could.  On a thread-switch, you could unwind all the old
> thread's bindings, then restore the new thread's bindings.

> This would let all the existing C code work without indirections or
> macro trickery; the downsides are that you have to have user-space
> control over thread switching, and thread switching becomes expensive.

I also expect some really nasty cases showing up when you try to rewind
a thread's bindings.  E.g. if a let-binding that was originally applied
to a global variable has to be rewound (i.e. re-applied) to a variable
that has become buffer-local in the mean time.

I guess this brings up back into the core of the issue: the semantics of
thread-local dynamic scoping and its interaction with
buffer-local bindings.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:04           ` Tom Tromey
@ 2011-01-31 22:08             ` David De La Harpe Golden
  2011-02-01 10:54             ` Daniel Colascione
  2011-02-01 15:43             ` Patch for fields of `struct buffer' Stefan Monnier
  2 siblings, 0 replies; 123+ messages in thread
From: David De La Harpe Golden @ 2011-01-31 22:08 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

On 31/01/11 19:04, Tom Tromey wrote:
>>>>>> "David" == David De La Harpe Golden<david@harpegolden.net>  writes:
>
> Tom>  One easy one is whether a new thread should inherit thread-local
> Tom>  bindings from its parent thread.  Our initial implementation did
> Tom>  inherit, but later I found out that this is not common in the Lisp
> Tom>  world.
>
> David>  I'd suggest going with CL afaik-now-most-common-practice and not
> David>  inherit. Isn't that easier implementation-wise anyway?
>
> Not notably, especially since this code is already written.
> (I did notice a bug on the branch ... but whatever, it is easy to fix.)
>

FWIW - turns out the initial model in SBCL was inherit, but a transition 
to non-inherit was made in late 2005 at SBCL 0.9.6 [1][2].  ISTR more 
wide-ranging discussions of the issue elsewhere, but this seems to be 
the relevant sbcl-devel thread:

"[sbcl-devel] dynamic variables and threads" on 2005-10-12
http://sourceforge.net/mailarchive/forum.php?thread_name=200510121507.15694.mega%40hotpop.com&forum_name=sbcl-devel

> Or, instead of the locks-and-condition-variables approach, go the CSP
> route and have channels and channel-select.  This idea is making a
> comeback, maybe it would fit well in Emacs Lisp.

I do think that some message-passing type system is a nice high-level 
model, even in the multithreading case rather than multiprocessing.
But isn't that something one might then build on top given the lowlevel 
pthredy stuff?  I suppose you could not fully expose the lowlevel stuff 
to lisp.

[1] http://www.sbcl.org/manual/Special-Variables.html#Special-Variables
[2] http://www.sbcl.org/all-news.html#0.9.6



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:57       ` Tom Tromey
@ 2011-02-01  2:42         ` Tom Tromey
  2011-02-01  4:09           ` Eli Zaretskii
  2011-02-01 16:40         ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-01  2:42 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

RMS> That is more limited than I thought it was.  If it is needed for
RMS> non-preemptive thread switching, the benefit would justify the cost,
RMS> but I think it isn't needed for that.  If this is would only be needed
RMS> for preemptive thread switching, I think the loss of clarity and
RMS> naturalness of the code is enough reason not to do it.

Tom> Ok.  I will stop work on this patch, then.  I am not sure if I am
Tom> interested in working on threads done the other way, I will have to
Tom> think about it.

Tom> You might want to consider backing out my earlier patch.  It won't be
Tom> needed either.

Someone gently pointed out off-list that I am perhaps being too hasty in
abandoning this approach so soon.  To be honest, I don't really
understand how Emacs development works -- it seems to be an anarchic
free-for-all, but I have trouble accepting that this could possibly be
the case.

Anyway, the patch is as complete as I can make it.  It is no trouble to
regenerate it; I have done many updates and recreations in the past few
weeks.  All that remains is a "go" or "no-go" from the powers that be.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01  2:42         ` Tom Tromey
@ 2011-02-01  4:09           ` Eli Zaretskii
  0 siblings, 0 replies; 123+ messages in thread
From: Eli Zaretskii @ 2011-02-01  4:09 UTC (permalink / raw)
  To: Tom Tromey; +Cc: rms, emacs-devel

> From: Tom Tromey <tromey@redhat.com>
> Date: Mon, 31 Jan 2011 19:42:12 -0700
> Cc: emacs-devel@gnu.org
> 
> To be honest, I don't really understand how Emacs development works
> -- it seems to be an anarchic free-for-all, but I have trouble
> accepting that this could possibly be the case.

Accept that.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:37     ` Richard Stallman
  2011-01-31 19:57       ` Tom Tromey
  2011-01-31 20:30       ` Stefan Monnier
@ 2011-02-01 10:26       ` Daniel Colascione
  2011-02-01 12:10         ` Stephen J. Turnbull
  2011-02-01 16:41         ` Richard Stallman
  2 siblings, 2 replies; 123+ messages in thread
From: Daniel Colascione @ 2011-02-01 10:26 UTC (permalink / raw)
  To: rms; +Cc: Tom Tromey, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1075 bytes --]

On 1/31/11 11:37 AM, Richard Stallman wrote:
>     Yes.  I think that is the right tradeoff given my long term goal, which
>     is preemptive multi-threading.
> 
> I don't think preemptive thread switching is a sensible goal.  It is
> so much trouble that it isn't worth doing even in the long term.
> Thus, it is a mistake to do much work now, or complicate the code now,
> or cause a slowdown now, for the sake of preemptive thread switching.

The world is increasingly moving toward parallel processing, and we
haven't seen single-core performance improve for years now. Meanwhile,
Emacs has become more computationally demanding, not only through new
features like CEDET, but via improvements to old ones as well. I find
myself regularly bumping up against CPU limits in my Emacs hacking.
Processor trends won't change any time soon, and forfeiting the power of
multi-core machines by proscribing OS-level, preemptive multitasking is
a mistake that will be hard to correct if assumptions about cooperative
threads are baked into the system early on.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:04           ` Tom Tromey
  2011-01-31 22:08             ` David De La Harpe Golden
@ 2011-02-01 10:54             ` Daniel Colascione
  2011-02-07  2:34               ` Tom Tromey
  2011-02-01 15:43             ` Patch for fields of `struct buffer' Stefan Monnier
  2 siblings, 1 reply; 123+ messages in thread
From: Daniel Colascione @ 2011-02-01 10:54 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel, David De La Harpe Golden

[-- Attachment #1: Type: text/plain, Size: 1128 bytes --]

On 1/31/11 11:04 AM, Tom Tromey wrote:
> Other ideas I have been considering:
> 
> Instead of explicit locks, just let any symbol function as a lock, and
> have the locks hidden in the C code.

While elegant, I'm afraid using symbols as locks would lead to a
proliferation of locks of code, not data. Using a symbol as a big global
lock is easier than using gensym to get per-object locks.

> (Or an extension of this idea, let
> any Lisp object be a lock -- "Java style".)

This approach has potential. I believe JVMs get away with this trick at
a cost of a machine word per object --- that's a big addition to a
simple cons cell, of which Emacs has quite a few.

> Or, instead of the locks-and-condition-variables approach, go the CSP
> route and have channels and channel-select.  This idea is making a
> comeback, maybe it would fit well in Emacs Lisp.

Some sort of CSP facility would be interesting. I'd also love to see
Clojure-style STM, although I don't know how well something like an
agent would work in elisp's more imperative environment. Also, it'd
require lexbind to make sense at all.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 20:30       ` Stefan Monnier
  2011-01-31 20:49         ` Tom Tromey
@ 2011-02-01 12:09         ` Stephen J. Turnbull
  2011-02-02  2:41           ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Stephen J. Turnbull @ 2011-02-01 12:09 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Tom Tromey, rms, emacs-devel

Stefan Monnier writes:

 > > I don't think preemptive thread switching is a sensible goal.  It is
 > > so much trouble that it isn't worth doing even in the long term.
 > 
 > I don't think we will get to choose.

FWIW, Guido Van Rossum is about +0.5 in Richard's camp.

Simon Peyton-Jones seemed pretty optimistic about STM in his
"Beautiful Code" chapter, but the Haskell programmers I know say it
doesn't work nearly so well in their practical programs.

So, maybe we will lose all our non-genius programmers if we don't do
threads.  Then again, maybe not.<wink>




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 10:26       ` Daniel Colascione
@ 2011-02-01 12:10         ` Stephen J. Turnbull
  2011-02-01 14:23           ` Lennart Borgman
  2011-02-01 16:41         ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Stephen J. Turnbull @ 2011-02-01 12:10 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: Tom Tromey, rms, emacs-devel

Daniel Colascione writes:

 > The world is increasingly moving toward parallel processing,

Since when does parallel processing == threads?

Inquiring-minds-wanna-know-ly-y'rs,



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 12:10         ` Stephen J. Turnbull
@ 2011-02-01 14:23           ` Lennart Borgman
  2011-02-01 16:19             ` Stephen J. Turnbull
  0 siblings, 1 reply; 123+ messages in thread
From: Lennart Borgman @ 2011-02-01 14:23 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Tom Tromey, Daniel Colascione, rms, emacs-devel

On Tue, Feb 1, 2011 at 1:10 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote:
> Daniel Colascione writes:
>
>  > The world is increasingly moving toward parallel processing,
>
> Since when does parallel processing == threads?

I am a computer illiterate sometimes. Could you give us some hints
about the current status?



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:04           ` Tom Tromey
  2011-01-31 22:08             ` David De La Harpe Golden
  2011-02-01 10:54             ` Daniel Colascione
@ 2011-02-01 15:43             ` Stefan Monnier
  2011-02-01 16:28               ` Helmut Eller
  2011-02-07  2:44               ` Tom Tromey
  2 siblings, 2 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-01 15:43 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel, David De La Harpe Golden

> Other ideas I have been considering:

> Instead of explicit locks, just let any symbol function as a lock, and
> have the locks hidden in the C code.  (Or an extension of this idea, let
> any Lisp object be a lock -- "Java style".)

As we discussed in the past, the first step is of course cooperative
threading, via context switches at I/O points, which is a "minor" tweak
to the current semantics (where we already have such switches but the
threads are nested, i.e. the main thread can only re-start once
the sub-thread (a process filter or sentinel) finishes).

If/when we'll get to finer grained concurrency, I think it makes sense
to use something that's as clean and high-level as possible: Elisp is
already slow and interpreted, so we can afford something "slow".

> Or, instead of the locks-and-condition-variables approach, go the CSP
> route and have channels and channel-select.  This idea is making a
> comeback, maybe it would fit well in Emacs Lisp.

Erlang-style concurrency is nice and clean, but I'm not sure it'll
integrate well with existing code which stomps over a global state all
the time.  This doesn't mean it won't work.  If we can make it work
something like "one agent per buffer" and turn `set-buffer' into a kind
of message maybe we could get some good results, but it seems tricky.

Threads and locks don't look too good: too low-level.  If we go in that
direction, then STM seems a lot more appealing.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 14:23           ` Lennart Borgman
@ 2011-02-01 16:19             ` Stephen J. Turnbull
  2011-02-01 17:08               ` Lennart Borgman
  2011-02-01 19:57               ` Daniel Colascione
  0 siblings, 2 replies; 123+ messages in thread
From: Stephen J. Turnbull @ 2011-02-01 16:19 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Tom Tromey, Daniel Colascione, rms, emacs-devel

Lennart Borgman writes:
 > On Tue, Feb 1, 2011 at 1:10 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote:
 > > Daniel Colascione writes:
 > >
 > >  > The world is increasingly moving toward parallel processing,
 > >
 > > Since when does parallel processing == threads?
 > 
 > I am a computer illiterate sometimes. Could you give us some hints
 > about the current status?

Well, that's actually what I was asking Daniel.  I'm not sure how
illiterate you think you are, so please try not to be insulted if it's
all too basic.

By *definition*, both threads and processes are ways of multitasking
which allow various forms of "parallel processing", such as multi-CPU
processing and time-slicing.  There are other forms of parallel
processing, such as GPUs on the video card and DMA for I/O, but these
are rather specialized.

In *theory*, both threads and processes should be capable of being
distributed across processors, and AFAIK they both work pretty well in
practice each with its advantages and disadvantages.

The specific difference between threads and processes is that threads
share all resources of a single process *except* the instruction
counter, and thus can communicate with each other with maximum
efficiency.  Processes do not share resources with each other, and
thus it is impossible (absent an OS or hardware bug) for one process
to stomp on another's resources, thus providing maximum safety for
each task.  In fact there are intermediate possibilities, for example
shared memory allows two separate processes to access the same
memory.  Any variables stored in that area are efficiently
communicated between the processes.

Now, in practice threads require protection from each other, just as
processes do when accessing disk (thus the infamous "stale lock"
problem in CVS and Subversion, which many workflows for dVCSes can
reduce to almost zero).  If you allocate a resource on the heap (often
called "consing" in Lisp, and is commonly extended to resources other
than Lisp conses), then in theory only a thread hold a pointer to it
can access it, thus providing some protection.  However, a wild
pointer "for (p = memory; ; p++) { write(stuff,p); }" can trash
another thread's private resources, while this can't happen with
processes.

The problem with threads as I see it, and I believe this is why
Richard and Guido express pessimism too, is that Lisp objects tend to
get all linked together.  Tasks that follow the links and mutate the
objects are likely to interfere with each other, but that is a very
common pattern in dynamic languages.  In Python, this is handled with
the GIL, or global interpreter lock.[1]  In many circumstances, a thread
must grab that lock, excluding all other threads from running.  This
also is somewhat expensive in terms of CPU AIUI.  Many proposals have
been made to remove the GIL from Python, but (so far) they all fall
down because it turns out that keeping track of lots of "local" locks
is either very expensive, or deadlock-prone.  (The "STM" that I
mentioned in connection with Haskell and Simon Peyton-Jones is more or
less a technique for automatically managing "local" locks, and has
been applied successfully in some projects.)

Of course, processes also involve high costs, specifically the cost of
context switching when interrupting one process and starting another,
and the cost of copying shared data back and forth between the
cooperating processes.

But on balance my intuition (FWIW, probably not much in this case :-)
is that threads are fundamentally a low-level, performance-oriented
implementation of the high-level abstraction "concurrent task", and
that there's a severe impedence mismatch with Lisp, especially Emacs
Lisp.

Footnotes: 
[1]  I refer here to the mainline Python written in C.  Jython and
IronPython are based on different virtual machines which don't have
GILs.





^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 15:43             ` Patch for fields of `struct buffer' Stefan Monnier
@ 2011-02-01 16:28               ` Helmut Eller
  2011-02-07  2:47                 ` Tom Tromey
  2011-02-07  2:44               ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Helmut Eller @ 2011-02-01 16:28 UTC (permalink / raw)
  To: emacs-devel

* Stefan Monnier [2011-02-01 15:43] writes:

>> Or, instead of the locks-and-condition-variables approach, go the CSP
>> route and have channels and channel-select.  This idea is making a
>> comeback, maybe it would fit well in Emacs Lisp.
>
> Erlang-style concurrency is nice and clean, but I'm not sure it'll
> integrate well with existing code which stomps over a global state all
> the time. This doesn't mean it won't work.  If we can make it work
> something like "one agent per buffer" and turn `set-buffer' into a kind
> of message maybe we could get some good results, but it seems tricky.

Erlang-style concurrency would be awesome.  Where can I vote for it :-)

Is there a way to evaluate the different approaches against each other?
What are the uses cases where concurrency should be used in the future?

Helmut




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 20:49         ` Tom Tromey
  2011-01-31 21:54           ` Stefan Monnier
@ 2011-02-01 16:39           ` Richard Stallman
  1 sibling, 0 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-01 16:39 UTC (permalink / raw)
  To: Tom Tromey; +Cc: monnier, emacs-devel

    Stefan> AFAICT, none of what he did is done because of preemptive threading.
    Stefan> IOW, I don't think you can do it much more simply, even if you assume
    Stefan> a cooperative threading model.

    Yeah, you could.  On a thread-switch, you could unwind all the old
    thread's bindings, then restore the new thread's bindings.

    This would let all the existing C code work without indirections or
    macro trickery; the downsides are that you have to have user-space
    control over thread switching, and thread switching becomes expensive.

That's exactly the implementation I have in mind.  It means that
thread switching is slower, but the other approach slows down
execution within a thread.

With this approach, you pay for threads only when you use them.
With the other, you pay all the time.

If multi-core is used for the machines where each core is also as fast
as can be, pay-if-you-use-threads seems like the best choice.



-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 19:57       ` Tom Tromey
  2011-02-01  2:42         ` Tom Tromey
@ 2011-02-01 16:40         ` Richard Stallman
  2011-02-01 16:44           ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Richard Stallman @ 2011-02-01 16:40 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

    RMS> Are you saying you would like to change it so that every access to
    RMS> a Lisp variable requires indirecting?

    Only potentially -- like today.

That is not a problem, then.

    For each global variable, the per-thread pointer will ordinarily point
    to the main thread's slot.  When the variable is let-bound, thus
    becoming thread-local, the pointer will be redirected to the slot in the
    per-thread structure.  When the outermost let-binding is undone, the
    pointer will be reset to the main thread's slot.

This seems to give the right semantics, but having a pointer in each thread
for each DEFVAR_LISP variable makes threads rather heavy.  How many such
variables are there now?  I'd expect thousands.

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 10:26       ` Daniel Colascione
  2011-02-01 12:10         ` Stephen J. Turnbull
@ 2011-02-01 16:41         ` Richard Stallman
  2011-02-01 16:51           ` Tom Tromey
  2011-02-01 20:04           ` Patch for fields of `struct buffer' Daniel Colascione
  1 sibling, 2 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-01 16:41 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: tromey, emacs-devel

Your argument makes sense, for people using powerful machines.
I have a slow one, by today's standards, and I don't think it is
likely I will get a faster one (or multicore) for years if ever.
Many free software activists use the same machine for the same reason.

Meanwhile, the big problem of making Emacs work with true parallelism
is not in the general mechanisms.  It is in all the code that knows
it can only be interrupted due to an error or where it says QUIT.
If you want to test the feasibility of real parallelism, that's what
you need to work on.


-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:40         ` Richard Stallman
@ 2011-02-01 16:44           ` Tom Tromey
  2011-02-02  2:42             ` Richard Stallman
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-01 16:44 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

RMS> This seems to give the right semantics, but having a pointer in
RMS> each thread for each DEFVAR_LISP variable makes threads rather
RMS> heavy.  How many such variables are there now?  I'd expect
RMS> thousands.

562.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:41         ` Richard Stallman
@ 2011-02-01 16:51           ` Tom Tromey
  2011-02-02  2:42             ` Richard Stallman
  2011-02-01 20:04           ` Patch for fields of `struct buffer' Daniel Colascione
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-01 16:51 UTC (permalink / raw)
  To: rms; +Cc: Daniel Colascione, emacs-devel

RMS> Your argument makes sense, for people using powerful machines.
RMS> I have a slow one, by today's standards, and I don't think it is
RMS> likely I will get a faster one (or multicore) for years if ever.
RMS> Many free software activists use the same machine for the same reason.

It is an empirical question as to whether this change slows things down
too much.  I don't think it is the case that any slowdown is
unacceptable.

One thing worth noting is that if the concurrency branch is a huge
failure, it is simple to back out at least the buffer change.  It can be
done with a perl one liner.  And, since there is no performance penalty
possible until concurrency is actually merged, I think the risks
associated with moving forward are rather low.

RMS> Meanwhile, the big problem of making Emacs work with true parallelism
RMS> is not in the general mechanisms.  It is in all the code that knows
RMS> it can only be interrupted due to an error or where it says QUIT.
RMS> If you want to test the feasibility of real parallelism, that's what
RMS> you need to work on.

The point of this patch series is to make it simpler to work on the
other problems on a branch.  Without the infrastructure in place,
merging (in either direction) is simply too difficult.  That is, it is a
stepping stone to getting cooperative threading, which itself is a
stepping stone to real parallelism.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:19             ` Stephen J. Turnbull
@ 2011-02-01 17:08               ` Lennart Borgman
  2011-02-01 19:57               ` Daniel Colascione
  1 sibling, 0 replies; 123+ messages in thread
From: Lennart Borgman @ 2011-02-01 17:08 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Tom Tromey, Daniel Colascione, rms, emacs-devel

On Tue, Feb 1, 2011 at 5:19 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote:
>
> Well, that's actually what I was asking Daniel.  I'm not sure how
> illiterate you think you are, so please try not to be insulted if it's
> all too basic.

Oh, it has been a pleasure reading your answer.


> The problem with threads as I see it, and I believe this is why
> Richard and Guido express pessimism too, is that Lisp objects tend to
> get all linked together.  Tasks that follow the links and mutate the
> objects are likely to interfere with each other, but that is a very
> common pattern in dynamic languages.  In Python, this is handled with
> the GIL, or global interpreter lock.[1]  In many circumstances, a thread
> must grab that lock, excluding all other threads from running.  This
> also is somewhat expensive in terms of CPU AIUI.  Many proposals have
> been made to remove the GIL from Python, but (so far) they all fall
> down because it turns out that keeping track of lots of "local" locks
> is either very expensive, or deadlock-prone.  (The "STM" that I
> mentioned in connection with Haskell and Simon Peyton-Jones is more or
> less a technique for automatically managing "local" locks, and has
> been applied successfully in some projects.)

Thanks, I see. Isn't that problem there also with Tom's proposal of a
per thread-pointer for global vars?



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 14:29       ` Tom Tromey
                           ` (2 preceding siblings ...)
  2011-01-31 19:38         ` Richard Stallman
@ 2011-02-01 18:26         ` Tom Tromey
  2011-02-01 19:28           ` Paul Eggert
                             ` (3 more replies)
  3 siblings, 4 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-01 18:26 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Stefan> To the extent that they're hidden behind macros, the current changes
Stefan> seem fine (the move of vars to globals.h is not, tho, which is why
Stefan> I want globals.h to be auto-generated).

Tom> I can do this after my current patch is done.

I wrote an evil sed script to generate globals.h from the .c files.
I used sed and not anything nicer since that is what the GNU coding
standards specify.

It is rather slow.  On my laptop it takes 10 seconds to scan src/*.c.
This would have to be done with every change to a .c file.

I've appended the script in case you want to try it yourself.
This is just generating the body of the "emacs_globals" struct; some
minor tweaks remain to be done in the Makefile.

Maybe Andreas' idea of reusing the doc extractor would be better.
I have not looked at that.

Tom

s/^.*DEFVAR_INT *("[^"]*", *\([a-zA-Z0-9_]*\),.*$/\1/
t printint
/^.*DEFVAR_INT *("[^"]*",[ 	]*$/ {
  n
  s/^[ 	]*\([a-zA-Z0-9_]*\),.*$/\1/
  b printint
}
s/^.*DEFVAR_BOOL *("[^"]*", *\([a-zA-Z0-9_]*\),.*$/\1/
t printbool
/^.*DEFVAR_BOOL ("[^"]*",[ 	]*$/ {
  n
  s/^[ 	]*\([a-zA-Z0-9_]*\),.*$/\1/
  b printbool
}
s/^.*DEFVAR_LISP\(_NOPRO\)* *("[^"]*", *\([a-zA-Z0-9_]*\),.*$/\2/
t printlisp
/^.*DEFVAR_LISP\(_NOPRO\)* ("[^"]*",[ 	]*$/ {
  n
  s/^[ 	]*\([a-zA-Z0-9_]*\),.*$/\1/
  b printlisp
}

b done

: printint
h
s/^\(.*\)$/  EMACS_INT f_\1;/p
g
s/^\(.*\)$/#define \1 globals.f_\1/p
b done

: printbool
h
s/^\(.*\)$/  int f_\1;/p
g
s/^\(.*\)$/#define \1 globals.f_\1/p
b done

: printlisp
h
s/^\(.*\)$/  Lisp_Object f_\1;/p
g
s/^\(.*\)$/#define \1 globals.f_\1/p
b done

: done



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 18:26         ` Tom Tromey
@ 2011-02-01 19:28           ` Paul Eggert
  2011-02-01 19:42             ` Tom Tromey
  2011-02-01 20:34           ` Andreas Schwab
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 123+ messages in thread
From: Paul Eggert @ 2011-02-01 19:28 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

On 02/01/11 10:26, Tom Tromey wrote:
> It is rather slow.  On my laptop it takes 10 seconds to scan src/*.c.
> This would have to be done with every change to a .c file.

Prepending "/DEFVAR_/!d" to the script sped it up
by a factor of 8 on my server; it then ran in
0.142 seconds real-time.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 19:28           ` Paul Eggert
@ 2011-02-01 19:42             ` Tom Tromey
  2011-02-09 10:16               ` Jim Meyering
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-01 19:42 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

>>>>> "Paul" == Paul Eggert <eggert@cs.ucla.edu> writes:

Tom> It is rather slow.  On my laptop it takes 10 seconds to scan src/*.c.
Tom> This would have to be done with every change to a .c file.

Paul> Prepending "/DEFVAR_/!d" to the script sped it up
Paul> by a factor of 8 on my server; it then ran in
Paul> 0.142 seconds real-time.

Thanks.

Can I use 'sort -u' or 'uniq' in GNU Makefiles these days?
Testing my script revealed that some things are DEFVAR'd twice.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:19             ` Stephen J. Turnbull
  2011-02-01 17:08               ` Lennart Borgman
@ 2011-02-01 19:57               ` Daniel Colascione
  2011-02-01 20:06                 ` Daniel Colascione
  1 sibling, 1 reply; 123+ messages in thread
From: Daniel Colascione @ 2011-02-01 19:57 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Tom Tromey, Lennart Borgman, rms, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3781 bytes --]

On 2/1/11 8:19 AM, Stephen J. Turnbull wrote:
> Lennart Borgman writes:
>  > On Tue, Feb 1, 2011 at 1:10 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote:
>  > > Daniel Colascione writes:
>  > >
>  > >  > The world is increasingly moving toward parallel processing,
>  > >
>  > > Since when does parallel processing == threads?
>  > 
>  > I am a computer illiterate sometimes. Could you give us some hints
>  > about the current status?
> 
> Well, that's actually what I was asking Daniel.  I'm not sure how
> illiterate you think you are, so please try not to be insulted if it's
> all too basic.

That's an excellent overview of the topic. Thanks for writing it, Stephan.

You're absolutely correct in that multiprocessing can also take provide
concurrency the ability to exploit SMP machines. But we've had it for
decades, and it doesn't seem to be used very much to solve some
persistent issues. Sure, flymake, flyspell, slime, M-x compile,
find-grep, and friends allow a lot of work to happen asynchronously. But
it's harder to use multiple processes to parallelize code written in
elisp, especially code that interacts with the user.

I actually prefer the shared-nothing multiprocessing approach in
general, but it's hard to take advantage of that in Emacs today, at
least for elisp. The startup time for a sub-Emacs (at least one that has
also processed user startup code) is high, we have no fork exposed to
elisp for easy data sharing, and there's no simple way to shuffle Lisp
data structures between the Emacs processes, though at least with prin1
and read, the last easier than it'd be in some other systems. You could
argue that bulk processing helpers should be written in something other
than elisp --- and in practice, they are --- but it complicates both
development and distribution.

Have you seen the Python multiprocessing module? It provides a simple,
elegant facilities to coordinate multiple communicating processes ---
things like queues and pipes. A similar approach would work fine for
Emacs as long as we're talking about bulk processing, e.g., parsing lots
of RFC2822 messages, or indexing hairy C++.

But for intricately coordinated work, it'd be a lot harder to allow
these multiple processes to effectively manipulate the same buffer or
communicate with the user: you'd have to either copy the whole thing,
which could be expensive for large buffers and which would have child
operate on stale data; you could provide a protocol for parent and child
to talk about buffers over IPC, but that would introduces complexity,
latency and coordination issues as well as a potentially large number of
context switches; or you could put the buffer in shared memory and
reintroduce some of the problems solved by multiprocessing as well as
run into issues some platforms have with cross-process synchronization
primitives. (ISTR a discussion of these options some time ago.)

We could have two concurrency systems: a cooperative threads system for
tasks inside an Emacs process that work closely with the user and that
share the work of fontifying buffers, and another, high-level facility
for offloading work to another Emacs process. This approach would solve
some problems, but it'd be complex, and I suspect a lot of CPU-intensive
code will nevertheless be run in the main Emacs process because it'd
hard to logically separate buffer-dependent and buffer-independent work
here.

Or, instead of that complexity, we can use shared-everything threads ---
which are inherently preemptive if they take advantage of hardware
concurrency --- and deal with the fallout as best we can; other systems
seem to manage. We could use locks and condition variables, or CSP, or
(my favorite) STM.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:41         ` Richard Stallman
  2011-02-01 16:51           ` Tom Tromey
@ 2011-02-01 20:04           ` Daniel Colascione
  2011-02-02  2:43             ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Daniel Colascione @ 2011-02-01 20:04 UTC (permalink / raw)
  To: rms; +Cc: tromey, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1477 bytes --]

On 2/1/11 8:41 AM, Richard Stallman wrote:
> Your argument makes sense, for people using powerful machines.
> I have a slow one, by today's standards, and I don't think it is
> likely I will get a faster one (or multicore) for years if ever.
> Many free software activists use the same machine for the same reason.

If you link against GNU Pth, the threading primitives become practically
free aside from the few hundred pointers referring to global Lisp
variables. I doubt the aggregate impact of following those indirections
would have much of an impact over all the pointer-chasing Lisp code
already performs. (How many cons cell are used for the output of
parse-partial-sexp?)

> Meanwhile, the big problem of making Emacs work with true parallelism
> is not in the general mechanisms.  It is in all the code that knows
> it can only be interrupted due to an error or where it says QUIT.
> If you want to test the feasibility of real parallelism, that's what
> you need to work on.

One approach successfully applied to other systems that make assumptions
about a lack of preemptive concurrency is to put large locks around the
sensitive portions and gradually split these locks up over time as the
code is improved. Subrs not specially marked as concurrency-safe could
be made to automatically take such a lock on entry, and Feval would
release it until another such subr were entered. Over time, more subrs
could be inspected and marked safe.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 19:57               ` Daniel Colascione
@ 2011-02-01 20:06                 ` Daniel Colascione
  0 siblings, 0 replies; 123+ messages in thread
From: Daniel Colascione @ 2011-02-01 20:06 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Tom Tromey, Lennart Borgman, rms, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 156 bytes --]

On 2/1/11 11:57 AM, Daniel Colascione wrote:
> That's an excellent overview of the topic. Thanks for writing it, Stephan.

Stephen. Sorry about that.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 18:26         ` Tom Tromey
  2011-02-01 19:28           ` Paul Eggert
@ 2011-02-01 20:34           ` Andreas Schwab
  2011-02-01 21:56             ` Tom Tromey
  2011-02-01 21:59           ` Tom Tromey
  2011-02-01 22:21           ` Stefan Monnier
  3 siblings, 1 reply; 123+ messages in thread
From: Andreas Schwab @ 2011-02-01 20:34 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Stefan Monnier, emacs-devel

Tom Tromey <tromey@redhat.com> writes:

> I wrote an evil sed script to generate globals.h from the .c files.
> I used sed and not anything nicer since that is what the GNU coding
> standards specify.

We already have make-docfile, why not just extend it?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 20:34           ` Andreas Schwab
@ 2011-02-01 21:56             ` Tom Tromey
  0 siblings, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-01 21:56 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Stefan Monnier, emacs-devel

Tom> I wrote an evil sed script to generate globals.h from the .c files.
Tom> I used sed and not anything nicer since that is what the GNU coding
Tom> standards specify.

Andreas> We already have make-docfile, why not just extend it?

No good reason.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 18:26         ` Tom Tromey
  2011-02-01 19:28           ` Paul Eggert
  2011-02-01 20:34           ` Andreas Schwab
@ 2011-02-01 21:59           ` Tom Tromey
  2011-02-02  0:44             ` Paul Eggert
  2011-02-02  3:49             ` Stefan Monnier
  2011-02-01 22:21           ` Stefan Monnier
  3 siblings, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-01 21:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Tom> I wrote an evil sed script to generate globals.h from the .c files.

With Paul's suggestion, this script seems to do ok.
Here is a patch that ties it all together.

I think this will break the nextstep build, since there Vselection_alist
was erroneously moved to globals.h.  Only DEFVARs have to be in
globals.h, other globals do not.  I reverted a similar change to
xselect.c, because I was able to test that one.

Let me know what you think.  I'm not excessively happy about the
ALL_SOURCES bit in src/Makefile.in.

Tom

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2011-02-01 08:53:03 +0000
+++ src/ChangeLog	2011-02-01 22:03:56 +0000
@@ -1,3 +1,15 @@
+2011-02-01  Tom Tromey  <tromey@redhat.com>
+
+	* buffer.c: Don't use "no_cell" for name of kill-buffer-hook's
+	variable.
+	* xselect.c (Vselection_alist): Define.  Reverts change from
+	2011-01-19.
+	* Makefile.in (ALL_SOURCES): New variable.
+	(globals.h, gl-stamp, $(obj)): New targets.
+	* globals.h: Remove.
+	* globals-2.sed: New file.
+	* globals-1.sed: New file.
+
 2011-02-01  Jan Djärv  <jan.h.d@swipnet.se>
 
 	* xsmfns.c (ice_connection_closed): Call delete_read_fd.

=== modified file 'src/Makefile.in'
--- src/Makefile.in	2011-01-30 23:34:18 +0000
+++ src/Makefile.in	2011-02-01 21:32:14 +0000
@@ -645,6 +645,44 @@
 buildobj.h: Makefile
 	echo "#define BUILDOBJ \"$(obj) $(otherobj) " "\"" > buildobj.h
 
+ALL_SOURCES = alloc.c atimer.c bidi.c buffer.c bytecode.c callint.c \
+ callproc.c casefiddle.c casetab.c category.c ccl.c character.c	\
+ charset.c chartab.c cm.c cmds.c coding.c composite.c data.c \
+ dbusbind.c dired.c dispnew.c doc.c doprnt.c dosfns.c editfns.c	\
+ emacs.c eval.c fileio.c filelock.c filemode.c firstfile.c floatfns.c \
+ fns.c font.c fontset.c frame.c fringe.c ftfont.c ftxfont.c \
+ getloadavg.c gmalloc.c gnutls.c gtkutil.c image.c indent.c insdel.c \
+ intervals.c keyboard.c keymap.c lastfile.c lread.c macros.c marker.c \
+ md5.c menu.c minibuf.c msdos.c nsfns.m nsfont.m nsimage.m nsmenu.m \
+ nsselect.m nsterm.m pre-crt0.c print.c process.c ralloc.c regex.c \
+ region-cache.c scroll.c search.c sheap.c sound.c syntax.c sysdep.c \
+ term.c termcap.c terminal.c terminfo.c textprop.c tparam.c undo.c \
+ unexaix.c unexcoff.c unexcw.c unexelf.c unexhp9k800.c unexmacosx.c \
+ unexsol.c unexw32.c vm-limit.c w16select.c w32.c w32console.c \
+ w32fns.c w32font.c w32heap.c w32inevt.c w32menu.c w32proc.c w32reg.c \
+ w32select.c w32term.c w32uniscribe.c w32xfns.c widget.c window.c \
+ xdisp.c xfaces.c xfns.c xfont.c xftfont.c xgselect.c xmenu.c xml.c \
+ xrdb.c xselect.c xsettings.c xsmfns.c xterm.c
+
+globals.h: gl-stamp
+	cp gl-stamp globals.h
+
+gl-stamp: $(ALL_SOURCES)
+	@rm -f gl-tmp
+	echo "/* This file was auto-generated */" > gl-tmp
+	echo "/* DO NOT EDIT */" >> gl-tmp
+	echo "struct emacs_globals {" >> gl-tmp
+	here=`pwd`; \
+	cd $(srcdir) && \
+	sed -n -f globals-1.sed $(ALL_SOURCES) | \
+	LANG=C sort -u | \
+	sed -n -f globals-2.sed >> $$here/gl-tmp
+	echo "};" >> gl-tmp
+	echo "extern struct emacs_globals globals;" >> gl-tmp
+	@$(srcdir)/../move-if-change gl-tmp gl-stamp
+
+$(obj): globals.h
+
 $(lib)/libgnu.a: $(config_h)
 	cd $(lib) && $(MAKE) libgnu.a
 

=== modified file 'src/buffer.c'
--- src/buffer.c	2011-01-30 22:17:44 +0000
+++ src/buffer.c	2011-02-01 21:43:53 +0000
@@ -1320,7 +1320,7 @@
 }
 
 /*
-  DEFVAR_LISP ("kill-buffer-hook", no_cell, "\
+  DEFVAR_LISP ("kill-buffer-hook", ..., "\
 Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
 The buffer being killed will be current while the hook is running.\n\
 See `kill-buffer'."

=== added file 'src/globals-1.sed'
--- src/globals-1.sed	1970-01-01 00:00:00 +0000
+++ src/globals-1.sed	2011-02-01 21:35:14 +0000
@@ -0,0 +1,32 @@
+# Find all DEFVARs that correspond to globals and emit lines suitable
+# for further processing by globals-2.sed.  Globals are defined by
+# DEFVAR_LISP, DEFVAR_LISP_NOPRO, DEFVAR_INT, and DEFVAR_BOOL.  Some
+# hair is needed to ensure that the script works even when the DEFVAR
+# is split before the global variable's name.
+
+/DEFVAR_/!d
+
+s/^.*DEFVAR_INT *("[^"]*", *\([a-zA-Z0-9_]*\),.*$/EMACS_INT \1/
+t done
+/^.*DEFVAR_INT *("[^"]*",[ 	]*$/ {
+  n
+  s/^[ 	]*\([a-zA-Z0-9_]*\),.*$/EMACS_INT \1/
+  b done
+}
+s/^.*DEFVAR_BOOL *("[^"]*", *\([a-zA-Z0-9_]*\),.*$/int \1/
+t done
+/^.*DEFVAR_BOOL ("[^"]*",[ 	]*$/ {
+  n
+  s/^[ 	]*\([a-zA-Z0-9_]*\),.*$/int \1/
+  b done
+}
+s/^.*DEFVAR_LISP\(_NOPRO\)* *("[^"]*", *\([a-zA-Z0-9_]*\),.*$/Lisp_Object \2/
+t done
+/^.*DEFVAR_LISP\(_NOPRO\)* ("[^"]*",[ 	]*$/ {
+  n
+  s/^[ 	]*\([a-zA-Z0-9_]*\),.*$/Lisp_Object \1/
+  b done
+}
+d
+: done
+p

=== added file 'src/globals-2.sed'
--- src/globals-2.sed	1970-01-01 00:00:00 +0000
+++ src/globals-2.sed	2011-02-01 21:34:00 +0000
@@ -0,0 +1,7 @@
+# Turn a sequence of lines like
+# TYPE VAR
+# into definitions suitable for globals.h.
+h
+s/^\(.*\) \(.*\)$/  \1 f_\2;/p
+g
+s/^\(.*\) \(.*\)$/#define \2 globals.f_\2/p

=== removed file 'src/globals.h'
--- src/globals.h	2011-01-26 20:02:07 +0000
+++ src/globals.h	1970-01-01 00:00:00 +0000
@@ -1,2900 +0,0 @@
-/* Declare all global lisp variables.
-
-   Copyright (C) 2011  Free Software Foundation, Inc.
-
-   This file is part of GNU Emacs.
-
-   GNU Emacs is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   GNU Emacs is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
-
-struct emacs_globals
-{
-
-  /* Count the amount of consing of various sorts of space.  */
-  EMACS_INT f_cons_cells_consed;
-
-  EMACS_INT f_floats_consed;
-
-  EMACS_INT f_vector_cells_consed;
-
-  EMACS_INT f_symbols_consed;
-
-  EMACS_INT f_string_chars_consed;
-
-  EMACS_INT f_misc_objects_consed;
-
-  EMACS_INT f_intervals_consed;
-
-  EMACS_INT f_strings_consed;
-
-  /* Minimum number of bytes of consing since GC before next GC. */
-  EMACS_INT f_gc_cons_threshold;
-
-  Lisp_Object f_Vgc_cons_percentage;
-
-  /* Nonzero means display messages at beginning and end of GC.  */
-  int f_garbage_collection_messages;
-
-  /* Non-nil means defun should do purecopy on the function definition.  */
-  Lisp_Object f_Vpurify_flag;
-
-  /* Non-nil means we are handling a memory-full error.  */
-  Lisp_Object f_Vmemory_full;
-
-  /* Total number of bytes allocated in pure storage. */
-  EMACS_INT f_pure_bytes_used;
-
-  /* Pre-computed signal argument for use when memory is exhausted.  */
-  Lisp_Object f_Vmemory_signal_data;
-
-  Lisp_Object f_Vpost_gc_hook;
-
-  Lisp_Object f_Vgc_elapsed;
-
-  EMACS_INT f_gcs_done;
-
-  /* Functions to call before and after each text change. */
-  Lisp_Object f_Vbefore_change_functions;
-
-  Lisp_Object f_Vafter_change_functions;
-
-  Lisp_Object f_Vtransient_mark_mode;
-
-  /* t means ignore all read-only text properties.
-     A list means ignore such a property if its value is a member of the list.
-     Any non-nil value means ignore buffer-read-only.  */
-  Lisp_Object f_Vinhibit_read_only;
-
-  /* List of functions to call that can query about killing a buffer.
-     If any of these functions returns nil, we don't kill it.  */
-  Lisp_Object f_Vkill_buffer_query_functions;
-
-  Lisp_Object f_Vchange_major_mode_hook;
-
-  /* List of functions to call before changing an unmodified buffer.  */
-  Lisp_Object f_Vfirst_change_hook;
-
-  /* If nonzero, all modification hooks are suppressed.  */
-  int f_inhibit_modification_hooks;
-
-  Lisp_Object f_Vbyte_code_meter;
-
-  int f_byte_metering_on;
-
-  Lisp_Object f_Vcurrent_prefix_arg;
-
-  Lisp_Object f_Vcommand_history;
-
-  Lisp_Object f_Vcommand_debug_status;
-
-  /* Non-nil means treat the mark as active
-     even if mark_active is 0.  */
-  Lisp_Object f_Vmark_even_if_inactive;
-
-  Lisp_Object f_Vmouse_leave_buffer_hook;
-
-  Lisp_Object f_Vexec_path;
-  Lisp_Object f_Vexec_directory;
-  Lisp_Object f_Vexec_suffixes;
-
-  Lisp_Object f_Vdata_directory;
-  Lisp_Object f_Vdoc_directory;
-
-  Lisp_Object f_Vconfigure_info_directory;
-  Lisp_Object f_Vshared_game_score_directory;
-
-  Lisp_Object f_Vshell_file_name;
-
-  Lisp_Object f_Vprocess_environment;
-  Lisp_Object f_Vinitial_environment;
-
-  /* Variables to determine word boundary.  */
-  Lisp_Object f_Vword_combining_categories;
-  Lisp_Object f_Vword_separating_categories;
-
-  /* This contains all code conversion map available to CCL.  */
-  Lisp_Object f_Vcode_conversion_map_vector;
-
-  /* Alist of fontname patterns vs corresponding CCL program.  */
-  Lisp_Object f_Vfont_ccl_encoder_alist;
-
-  /* Vector of registered hash tables for translation.  */
-  Lisp_Object f_Vtranslation_hash_table_vector;
-
-  /* Vector of translation table ever defined.
-     ID of a translation table is used to index this vector.  */
-  Lisp_Object f_Vtranslation_table_vector;
-
-  /* A char-table for characters which may invoke auto-filling.  */
-  Lisp_Object f_Vauto_fill_chars;
-
-  /* A char-table.  An element is non-nil iff the corresponding
-     character has a printable glyph.  */
-  Lisp_Object f_Vprintable_chars;
-
-  /* A char-table.  An elemnent is a column-width of the corresponding
-     character.  */
-  Lisp_Object f_Vchar_width_table;
-
-  /* A char-table.  An element is a symbol indicating the direction
-     property of corresponding character.  */
-  Lisp_Object f_Vchar_direction_table;
-
-  /* Char table of scripts.  */
-  Lisp_Object f_Vchar_script_table;
-
-  /* Alist of scripts vs representative characters.  */
-  Lisp_Object f_Vscript_representative_chars;
-
-  Lisp_Object f_Vunicode_category_table;
-
-  /* List of all charsets.  This variable is used only from Emacs
-     Lisp.  */
-  Lisp_Object f_Vcharset_list;
-
-  Lisp_Object f_Vcharset_map_path;
-
-  /* If nonzero, don't load charset maps.  */
-  int f_inhibit_load_charset_map;
-
-  Lisp_Object f_Vcurrent_iso639_language;
-
-  Lisp_Object f_Vpost_self_insert_hook;
-
-  int f_coding_system_require_warning;
-
-  Lisp_Object f_Vselect_safe_coding_system_function;
-
-  /* Mnemonic string for each format of end-of-line.  */
-  Lisp_Object f_eol_mnemonic_unix;
-  Lisp_Object f_eol_mnemonic_dos;
-  Lisp_Object f_eol_mnemonic_mac;
-
-  /* Mnemonic string to indicate format of end-of-line is not yet
-     decided.  */
-  Lisp_Object f_eol_mnemonic_undecided;
-
-  Lisp_Object f_Vcoding_system_list;
-  Lisp_Object f_Vcoding_system_alist;
-
-  /* Coding-system for reading files and receiving data from process.  */
-  Lisp_Object f_Vcoding_system_for_read;
-
-  /* Coding-system for writing files and sending data to process.  */
-  Lisp_Object f_Vcoding_system_for_write;
-
-  /* Coding-system actually used in the latest I/O.  */
-  Lisp_Object f_Vlast_coding_system_used;
-
-  /* Set to non-nil when an error is detected while code conversion.  */
-  Lisp_Object f_Vlast_code_conversion_error;
-
-  /* A vector of length 256 which contains information about special
-     Latin codes (especially for dealing with Microsoft codes).  */
-  Lisp_Object f_Vlatin_extra_code_table;
-
-  /* Flag to inhibit code conversion of end-of-line format.  */
-  int f_inhibit_eol_conversion;
-
-  /* Flag to inhibit ISO2022 escape sequence detection.  */
-  int f_inhibit_iso_escape_detection;
-
-  /* Flag to inhibit detection of binary files through null bytes.  */
-  int f_inhibit_null_byte_detection;
-
-  /* Flag to make buffer-file-coding-system inherit from process-coding.  */
-  int f_inherit_process_coding_system;
-
-  Lisp_Object f_Vfile_coding_system_alist;
-
-  Lisp_Object f_Vprocess_coding_system_alist;
-
-  Lisp_Object f_Vnetwork_coding_system_alist;
-
-  Lisp_Object f_Vlocale_coding_system;
-
-  /* Flag to tell if we look up translation table on character code
-     conversion.  */
-  Lisp_Object f_Venable_character_translation;
-
-  /* Standard translation table to look up on decoding (reading).  */
-  Lisp_Object f_Vstandard_translation_table_for_decode;
-
-  /* Standard translation table to look up on encoding (writing).  */
-  Lisp_Object f_Vstandard_translation_table_for_encode;
-
-  /* Alist of charsets vs revision number.  */
-  Lisp_Object f_Vcharset_revision_table;
-
-  /* Default coding systems used for process I/O.  */
-  Lisp_Object f_Vdefault_process_coding_system;
-
-  /* Char table for translating Quail and self-inserting input.  */
-  Lisp_Object f_Vtranslation_table_for_input;
-
-  /* List of symbols `coding-category-xxx' ordered by priority.  This
-     variable is exposed to Emacs Lisp.  */
-  Lisp_Object f_Vcoding_category_list;
-
-  /* Function to call to adjust composition.  */
-  Lisp_Object f_Vcompose_chars_after_function;
-
-  Lisp_Object f_Vauto_composition_mode;
-
-  Lisp_Object f_Vauto_composition_function;
-
-  Lisp_Object f_Vcomposition_function_table;
-
-  Lisp_Object f_Vmost_positive_fixnum;
-  Lisp_Object f_Vmost_negative_fixnum;
-
-  /* Registered buses.  */
-  Lisp_Object f_Vdbus_registered_buses;
-
-  /* Hash table which keeps function definitions.  */
-  Lisp_Object f_Vdbus_registered_objects_table;
-
-  /* Whether to debug D-Bus.  */
-  Lisp_Object f_Vdbus_debug;
-
-  Lisp_Object f_Vcompletion_ignored_extensions;
-
-  /* Non-zero means don't pause redisplay for pending input.  (This is
-     for debugging and for a future implementation of EDT-like
-     scrolling.  */
-  int f_redisplay_dont_pause;
-
-  /* If a number (float), check for user input every N seconds.  */
-  Lisp_Object f_Vredisplay_preemption_period;
-
-  /* Lisp variable visible-bell; enables use of screen-flash instead of
-     audible bell.  */
-  int f_visible_bell;
-
-  /* Invert the color of the whole frame, at a low level.  */
-  int f_inverse_video;
-
-  /* Line speed of the terminal.  */
-  EMACS_INT f_baud_rate;
-
-  /* Either nil or a symbol naming the window system under which Emacs
-     creates the first frame.  */
-  Lisp_Object f_Vinitial_window_system;
-
-  /* Version number of X windows: 10, 11 or nil.  */
-  Lisp_Object f_Vwindow_system_version;
-
-  /* Vector of glyph definitions.  Indexed by glyph number, the contents
-     are a string which is how to output the glyph.
-
-     If Vglyph_table is nil, a glyph is output by using its low 8 bits
-     as a character code.
-
-     This is an obsolete feature that is no longer used.  The variable
-     is retained for compatibility.  */
-  Lisp_Object f_Vglyph_table;
-
-  /* Display table to use for vectors that don't specify their own.  */
-  Lisp_Object f_Vstandard_display_table;
-
-  /* Nonzero means reading single-character input with prompt so put
-     cursor on mini-buffer after the prompt.  Positive means at end of
-     text in echo area; negative means at beginning of line.  */
-  int f_cursor_in_echo_area;
-
-  Lisp_Object f_Vdoc_file_name;
-
-  /* A list of files used to build this Emacs binary.  */
-  Lisp_Object f_Vbuild_files;
-
-  /* country info */
-  EMACS_INT f_dos_country_code;
-
-  EMACS_INT f_dos_codepage;
-
-  EMACS_INT f_dos_timezone_offset;
-
-  EMACS_INT f_dos_decimal_point;
-
-  EMACS_INT f_dos_keyboard_layout;
-
-  EMACS_INT f_dos_hyper_key;
-
-  EMACS_INT f_dos_super_key;
-
-  EMACS_INT f_dos_keypad_mode;
-
-  Lisp_Object f_Vdos_version;
-
-  Lisp_Object f_Vdos_display_scancodes;
-
-  Lisp_Object f_Vdos_windows_version;
-
-  Lisp_Object f_Vbuffer_access_fontify_functions;
-
-  Lisp_Object f_Vbuffer_access_fontified_property;
-
-  /* Non-nil means don't stop at field boundary in text motion commands.  */
-  Lisp_Object f_Vinhibit_field_text_motion;
-
-  /* Some static data, and a function to initialize it for each run */
-  Lisp_Object f_Vsystem_name;
-
-  Lisp_Object f_Vuser_real_login_name;
-
-  Lisp_Object f_Vuser_full_name;
-
-  Lisp_Object f_Vuser_login_name;
-
-  Lisp_Object f_Voperating_system_release;
-
-  /* Command line args from shell, as list of strings.  */
-  Lisp_Object f_Vcommand_line_args;
-
-  /* The name under which Emacs was invoked, with any leading directory
-     names discarded.  */
-  Lisp_Object f_Vinvocation_name;
-
-  /* The directory name from which Emacs was invoked.  */
-  Lisp_Object f_Vinvocation_directory;
-
-  /* The directory name in which to find subdirs such as lisp and etc.
-     nil means get them only from PATH_LOADSEARCH.  */
-  Lisp_Object f_Vinstallation_directory;
-
-  /* The values of `current-time' before and after Emacs initialization.  */
-  Lisp_Object f_Vbefore_init_time;
-  Lisp_Object f_Vafter_init_time;
-
-  /* Hook run by `kill-emacs' before it does really anything.  */
-  Lisp_Object f_Vkill_emacs_hook;
-
-  /* Search path separator.  */
-  Lisp_Object f_Vpath_separator;
-
-  /* Variable whose value is symbol giving operating system type.  */
-  Lisp_Object f_Vsystem_type;
-
-  /* Variable whose value is string giving configuration built for.  */
-  Lisp_Object f_Vsystem_configuration;
-
-  /* Variable whose value is string giving configuration options,
-     for use when reporting bugs.  */
-  Lisp_Object f_Vsystem_configuration_options;
-
-  /* Current and previous system locales for messages and time.  */
-  Lisp_Object f_Vsystem_messages_locale;
-
-  Lisp_Object f_Vprevious_system_messages_locale;
-
-  Lisp_Object f_Vsystem_time_locale;
-
-  Lisp_Object f_Vprevious_system_time_locale;
-
-  /* Copyright and version info.  The version number may be updated by
-     Lisp code.  */
-  Lisp_Object f_Vemacs_copyright;
-  Lisp_Object f_Vemacs_version;
-
-  /* Alist of external libraries and files implementing them.  */
-  Lisp_Object f_Vdynamic_library_alist;
-
-  /* Value of Lisp variable `noninteractive'.
-     Normally same as C variable `noninteractive'
-     but nothing terrible happens if user sets this one.  */
-  int f_noninteractive1;
-
-  /* Nonzero means Emacs was run in --quick mode.  */
-  int f_inhibit_x_resources;
-
-  Lisp_Object f_Vinhibit_quit;
-  Lisp_Object f_Vquit_flag;
-
-  /* Maximum size allowed for specpdl allocation */
-  EMACS_INT f_max_specpdl_size;
-
-  /* Maximum allowed depth in Lisp evaluations and function calls.  */
-  EMACS_INT f_max_lisp_eval_depth;
-
-  /* Nonzero means enter debugger before next function call */
-  int f_debug_on_next_call;
-
-  /* Non-zero means debugger may continue.  This is zero when the
-     debugger is called during redisplay, where it might not be safe to
-     continue the interrupted redisplay. */
-  int f_debugger_may_continue;
-
-  /* List of conditions (non-nil atom means all) which enter the debugger
-     if an error is handled by the command loop's error handler.  */
-  Lisp_Object f_Vdebug_on_error;
-
-  /* List of conditions and regexps specifying error messages which
-     do not enter the debugger even if Vdebug_on_error says they should.  */
-  Lisp_Object f_Vdebug_ignored_errors;
-
-  /* Non-nil means call the debugger even if the error will be handled.  */
-  Lisp_Object f_Vdebug_on_signal;
-
-  /* Hook for edebug to use.  */
-  Lisp_Object f_Vsignal_hook_function;
-
-  /* Nonzero means enter debugger if a quit signal
-     is handled by the command loop's error handler. */
-  int f_debug_on_quit;
-
-  Lisp_Object f_Vdebugger;
-
-  /* Function to process declarations in defmacro forms.  */
-  Lisp_Object f_Vmacro_declaration_function;
-
-  /* Coding system for file names, or nil if none.  */
-  Lisp_Object f_Vfile_name_coding_system;
-
-  /* Coding system for file names used only when
-     Vfile_name_coding_system is nil.  */
-  Lisp_Object f_Vdefault_file_name_coding_system;
-
-  /* Alist of elements (REGEXP . HANDLER) for file names
-     whose I/O is done with a special handler.  */
-  Lisp_Object f_Vfile_name_handler_alist;
-
-  /* Function to be called to decide a coding system of a reading file.  */
-  Lisp_Object f_Vset_auto_coding_function;
-
-  /* Functions to be called to process text properties in inserted file.  */
-  Lisp_Object f_Vafter_insert_file_functions;
-
-  /* Functions to be called to create text property annotations for file.  */
-  Lisp_Object f_Vwrite_region_annotate_functions;
-
-  Lisp_Object f_Vwrite_region_post_annotation_function;
-
-  /* During build_annotations, each time an annotation function is called,
-     this holds the annotations made by the previous functions.  */
-  Lisp_Object f_Vwrite_region_annotations_so_far;
-
-  /* File name in which we write a list of all our auto save files.  */
-  Lisp_Object f_Vauto_save_list_file_name;
-
-  /* Whether or not files are auto-saved into themselves.  */
-  Lisp_Object f_Vauto_save_visited_file_name;
-
-  /* Whether or not to continue auto-saving after a large deletion.  */
-  Lisp_Object f_Vauto_save_include_big_deletions;
-
-  /* Nonzero means skip the call to fsync in Fwrite-region.  */
-  int f_write_region_inhibit_fsync;
-
-  /* Non-zero means call move-file-to-trash in Fdelete_file or
-     Fdelete_directory_internal.  */
-  int f_delete_by_moving_to_trash;
-
-  /* These variables describe handlers that have "already" had a chance
-     to handle the current operation.
-
-     Vinhibit_file_name_handlers is a list of file name handlers.
-     Vinhibit_file_name_operation is the operation being handled.
-     If we try to handle that operation, we ignore those handlers.  */
-  Lisp_Object f_Vinhibit_file_name_handlers;
-
-  Lisp_Object f_Vinhibit_file_name_operation;
-
-  /* The directory for writing temporary files.  */
-  Lisp_Object f_Vtemporary_file_directory;
-
-  /* Nonzero enables use of dialog boxes for questions
-     asked by mouse commands.  */
-  int f_use_dialog_box;
-
-  /* Nonzero enables use of a file dialog for file name
-     questions asked by mouse commands.  */
-  int f_use_file_dialog;
-
-  Lisp_Object f_Vfeatures;
-
-  Lisp_Object f_Vfont_weight_table;
-  Lisp_Object f_Vfont_slant_table;
-  Lisp_Object f_Vfont_width_table;
-
-  Lisp_Object f_Vfont_encoding_alist;
-
-  Lisp_Object f_Vfont_log;
-
-  Lisp_Object f_Vfont_encoding_charset_alist;
-
-  Lisp_Object f_Vuse_default_ascent;
-
-  Lisp_Object f_Vignore_relative_composition;
-
-  Lisp_Object f_Valternate_fontname_alist;
-
-  Lisp_Object f_Vfontset_alias_alist;
-
-  Lisp_Object f_Vvertical_centering_font_regexp;
-
-  Lisp_Object f_Votf_script_alist;
-
-  /* If we shall make pointer invisible when typing or not.  */
-  Lisp_Object f_Vmake_pointer_invisible;
-
-  /* The name we're using in resource queries.  Most often "emacs".  */
-  Lisp_Object f_Vx_resource_name;
-
-  /* The application class we're using in resource queries.
-     Normally "Emacs".  */
-  Lisp_Object f_Vx_resource_class;
-
-  /* Lower limit value of the frame opacity (alpha transparency).  */
-  Lisp_Object f_Vframe_alpha_lower_limit;
-
-  Lisp_Object f_Vmenu_bar_mode;
-  Lisp_Object f_Vtool_bar_mode;
-
-  Lisp_Object f_Vterminal_frame;
-
-  Lisp_Object f_Vdefault_frame_alist;
-
-  Lisp_Object f_Vdefault_frame_scroll_bars;
-
-  Lisp_Object f_Vmouse_position_function;
-
-  Lisp_Object f_Vmouse_highlight;
-
-  Lisp_Object f_Vdelete_frame_functions;
-
-  int f_focus_follows_mouse;
-
-  /* Non-nil means that newline may flow into the right fringe.  */
-  Lisp_Object f_Voverflow_newline_into_fringe;
-
-  /* List of known fringe bitmap symbols.
-
-     The fringe bitmap number is stored in the `fringe' property on
-     those symbols.  Names for the built-in bitmaps are installed by
-     loading fringe.el.
-  */
-  Lisp_Object f_Vfringe_bitmaps;
-
-  /* Search path for bitmap files.  */
-  Lisp_Object f_Vx_bitmap_file_path;
-
-  /* A list of symbols, one for each supported image type.  */
-  Lisp_Object f_Vimage_types;
-
-  /* Time in seconds after which images should be removed from the cache
-     if not displayed.  */
-  Lisp_Object f_Vimage_cache_eviction_delay;
-
-  Lisp_Object f_Vmax_image_size;
-
-  /* Non-zero means draw a cross on images having `:conversion
-     disabled'.  */
-  int f_cross_disabled_images;
-
-  Lisp_Object f_Vimagemagick_render_type;
-
-  /* Indentation can insert tabs if this is non-zero;
-     otherwise always uses spaces.  */
-  int f_indent_tabs_mode;
-
-  /* Non-nil means don't call the after-change-functions right away,
-     just record an element in combine_after_change_list.  */
-  Lisp_Object f_Vcombine_after_change_calls;
-
-  /* Check all markers in the current buffer, looking for something invalid.  */
-  int f_check_markers_debug_flag;
-
-  /* Non-nil if the present key sequence was obtained by shift translation.  */
-  Lisp_Object f_Vthis_command_keys_shift_translated;
-
-  /* If non-nil, the function that implements the display of help.
-     It's called with one argument, the help string to display.  */
-  Lisp_Object f_Vshow_help_function;
-
-  /* Nonzero means do menu prompting.  */
-  int f_menu_prompting;
-
-  /* Character to see next line of menu prompt.  */
-  Lisp_Object f_menu_prompt_more_char;
-
-  /* Nonzero means disregard local maps for the menu bar.  */
-  int f_inhibit_local_menu_bar_menus;
-
-  /* The user's hook function for outputting an error message.  */
-  Lisp_Object f_Vcommand_error_function;
-
-  /* The user's ERASE setting.  */
-  Lisp_Object f_Vtty_erase_char;
-
-  /* Character to recognize as the help char.  */
-  Lisp_Object f_Vhelp_char;
-
-  /* List of other event types to recognize as meaning "help".  */
-  Lisp_Object f_Vhelp_event_list;
-
-  /* Form to execute when help char is typed.  */
-  Lisp_Object f_Vhelp_form;
-
-  /* Command to run when the help character follows a prefix key.  */
-  Lisp_Object f_Vprefix_help_command;
-
-  /* List of items that should move to the end of the menu bar.  */
-  Lisp_Object f_Vmenu_bar_final_items;
-
-  /* Expression to evaluate for the tool bar separator image.
-     This is used for build_desired_tool_bar_string only.  For GTK, we
-     use GTK tool bar seperators.  */
-  Lisp_Object f_Vtool_bar_separator_image_expression;
-
-  /* Non-nil means show the equivalent key-binding for
-     any M-x command that has one.
-     The value can be a length of time to show the message for.
-     If the value is non-nil and not a number, we wait 2 seconds.  */
-  Lisp_Object f_Vsuggest_key_bindings;
-
-  /* How long to display an echo-area message when the minibuffer is active.
-     If the value is not a number, such messages don't time out.  */
-  Lisp_Object f_Vminibuffer_message_timeout;
-
-  /* If non-nil, this is a map that overrides all other local maps.  */
-  Lisp_Object f_Voverriding_local_map;
-
-  /* If non-nil, Voverriding_local_map applies to the menu bar.  */
-  Lisp_Object f_Voverriding_local_map_menu_flag;
-
-  /* Keymap that defines special misc events that should
-     be processed immediately at a low level.  */
-  Lisp_Object f_Vspecial_event_map;
-
-  /* Total number of times command_loop has read a key sequence.  */
-  EMACS_INT f_num_input_keys;
-
-  /* Last input event read as a command.  */
-  Lisp_Object f_last_command_event;
-
-  /* Last input character read as a command, not counting menus
-     reached by the mouse.  */
-  Lisp_Object f_last_nonmenu_event;
-
-  /* Last input event read for any purpose.  */
-  Lisp_Object f_last_input_event;
-
-  /* If not Qnil, a list of objects to be read as subsequent command input.  */
-  Lisp_Object f_Vunread_command_events;
-
-  /* If not Qnil, a list of objects to be read as subsequent command input
-     including input method processing.  */
-  Lisp_Object f_Vunread_input_method_events;
-
-  /* If not Qnil, a list of objects to be read as subsequent command input
-     but NOT including input method processing.  */
-  Lisp_Object f_Vunread_post_input_method_events;
-
-  /* If not -1, an event to be read as subsequent command input.  */
-  EMACS_INT f_unread_command_char;
-
-  /* A mask of extra modifier bits to put into every keyboard char.  */
-  EMACS_INT f_extra_keyboard_modifiers;
-
-  /* Char to use as prefix when a meta character is typed in.
-     This is bound on entry to minibuffer in case ESC is changed there.  */
-  Lisp_Object f_meta_prefix_char;
-
-  /* Number of idle seconds before an auto-save and garbage collection.  */
-  Lisp_Object f_Vauto_save_timeout;
-
-  /* Total number of times read_char has returned, outside of macros.  */
-  EMACS_INT f_num_nonmacro_input_events;
-
-  /* Auto-save automatically when this many characters have been typed
-     since the last time.  */
-  EMACS_INT f_auto_save_interval;
-
-  /* The command being executed by the command loop.
-     Commands may set this, and the value set will be copied into
-     current_kboard->Vlast_command instead of the actual command.  */
-  Lisp_Object f_Vthis_command;
-
-  /* If the lookup of the command returns a binding, the original
-     command is stored in this-original-command.  It is nil otherwise.  */
-  Lisp_Object f_Vthis_original_command;
-
-  /* A user-visible version of the above, intended to allow users to
-     figure out where the last event came from, if the event doesn't
-     carry that information itself (i.e. if it was a character).  */
-  Lisp_Object f_Vlast_event_frame;
-
-  /* If non-nil, active regions automatically become the window selection.  */
-  Lisp_Object f_Vselect_active_regions;
-
-  /* The text in the active region prior to modifying the buffer.
-     Used by the `select-active-regions' feature.  */
-  Lisp_Object f_Vsaved_region_selection;
-
-  /* Echo unfinished commands after this many seconds of pause.  */
-  Lisp_Object f_Vecho_keystrokes;
-
-  /* Form to evaluate (if non-nil) when Emacs is started.  */
-  Lisp_Object f_Vtop_level;
-
-  /* If non-nil, this implements the current input method.  */
-  Lisp_Object f_Vinput_method_function;
-
-  /* When we call Vinput_method_function,
-     this holds the echo area message that was just erased.  */
-  Lisp_Object f_Vinput_method_previous_message;
-
-  /* Non-nil means deactivate the mark at end of this command.  */
-  Lisp_Object f_Vdeactivate_mark;
-
-  /* Menu bar specified in Lucid Emacs fashion.  */
-  Lisp_Object f_Vlucid_menu_bar_dirty_flag;
-
-  Lisp_Object f_Vpre_command_hook;
-
-  Lisp_Object f_Vpost_command_hook;
-
-  Lisp_Object f_Vcommand_hook_internal;
-
-  /* Parent keymap of terminal-local function-key-map instances.  */
-  Lisp_Object f_Vfunction_key_map;
-
-  /* Keymap of key translations that can override keymaps.  */
-  Lisp_Object f_Vkey_translation_map;
-
-  /* List of deferred actions to be performed at a later time.
-     The precise format isn't relevant here; we just check whether it is nil.  */
-  Lisp_Object f_Vdeferred_action_list;
-
-  /* Function to call to handle deferred actions, when there are any.  */
-  Lisp_Object f_Vdeferred_action_function;
-
-  /* If this flag is non-nil, we check mouse_moved to see when the
-     mouse moves, and motion events will appear in the input stream.
-     Otherwise, mouse motion is ignored.  */
-  Lisp_Object f_do_mouse_tracking;
-
-  /* List of absolute timers.  Appears in order of next scheduled event.  */
-  Lisp_Object f_Vtimer_list;
-
-  /* List of idle time timers.  Appears in order of next scheduled event.  */
-  Lisp_Object f_Vtimer_idle_list;
-
-  /* After a command is executed, if point is moved into a region that
-     has specific properties (e.g. composition, display), we adjust
-     point to the boundary of the region.  But, if a command sets this
-     variable to non-nil, we suppress this point adjustment.  This
-     variable is set to nil before reading a command.  */
-  Lisp_Object f_Vdisable_point_adjustment;
-
-  /* If non-nil, always disable point adjustment.  */
-  Lisp_Object f_Vglobal_disable_point_adjustment;
-
-  /* If non-nil, events produced by disabled menu items and tool-bar
-     buttons are not ignored.  Help functions bind this to allow help on
-     those items and buttons.  */
-  Lisp_Object f_Venable_disabled_menus_and_buttons;
-
-  /* Nonzero means don't try to suspend even if the operating system seems
-     to support it.  */
-  int f_cannot_suspend;
-
-  /* Number of seconds between polling for input.  This is a Lisp
-     variable that can be bound.  */
-  EMACS_INT f_polling_period;
-
-  /* subprocesses */
-  Lisp_Object f_Vthrow_on_input;
-
-  /* The maximum time between clicks to make a double-click, or Qnil to
-     disable double-click detection, or Qt for no time limit.  */
-  Lisp_Object f_Vdouble_click_time;
-
-  /* Maximum number of pixels the mouse may be moved between clicks
-     to make a double-click.  */
-  EMACS_INT f_double_click_fuzz;
-
-  /* was MinibufLocalMap */
-  Lisp_Object f_Vminibuffer_local_map;
-
-  /* was MinibufLocalNSMap */
-  Lisp_Object f_Vminibuffer_local_ns_map;
-
-  /* was MinibufLocalCompletionMap */
-  Lisp_Object f_Vminibuffer_local_completion_map;
-
-  /* keymap used for minibuffers when doing completion in filenames */
-  Lisp_Object f_Vminibuffer_local_filename_completion_map;
-
-  /* keymap used for minibuffers when doing completion in filenames
-     with require-match*/
-  Lisp_Object f_Vminibuffer_local_filename_must_match_map;
-
-  /* was MinibufLocalMustMatchMap */
-  Lisp_Object f_Vminibuffer_local_must_match_map;
-
-  /* Alist of minor mode variables and keymaps.  */
-  Lisp_Object f_Vminor_mode_map_alist;
-
-  /* Alist of major-mode-specific overrides for
-     minor mode variables and keymaps.  */
-  Lisp_Object f_Vminor_mode_overriding_map_alist;
-
-  /* List of emulation mode keymap alists.  */
-  Lisp_Object f_Vemulation_mode_map_alists;
-
-  /* A list of all commands given new bindings since a certain time
-     when nil was stored here.
-     This is used to speed up recomputation of menu key equivalents
-     when Emacs starts up.   t means don't record anything here.  */
-  Lisp_Object f_Vdefine_key_rebound_commands;
-
-  Lisp_Object f_Vwhere_is_preferred_modifier;
-
-  Lisp_Object f_Vvalues;
-  Lisp_Object f_Vstandard_input;
-  Lisp_Object f_Vafter_load_alist;
-
-  Lisp_Object f_Veval_buffer_list;
-
-  /* non-zero if inside `load' */
-  int f_load_in_progress;
-
-  /* Directory in which the sources were found.  */
-  Lisp_Object f_Vsource_directory;
-
-  /* Search path and suffixes for files to be loaded. */
-  Lisp_Object f_Vload_path;
-  Lisp_Object f_Vload_suffixes;
-  Lisp_Object f_Vload_file_rep_suffixes;
-
-  /* File name of user's init file.  */
-  Lisp_Object f_Vuser_init_file;
-
-  /* This is the user-visible association list that maps features to
-     lists of defs in their load files. */
-  Lisp_Object f_Vload_history;
-
-  /* This is used to build the load history. */
-  Lisp_Object f_Vcurrent_load_list;
-
-  /* List of files that were preloaded.  */
-  Lisp_Object f_Vpreloaded_file_list;
-
-  /* Name of file actually being read by `load'.  */
-  Lisp_Object f_Vload_file_name;
-
-  /* Function to use for reading, in `load' and friends.  */
-  Lisp_Object f_Vload_read_function;
-
-  /* Non-nil means read recursive structures using #n= and #n# syntax.  */
-  Lisp_Object f_Vread_circle;
-
-  /* Nonzero means load should forcibly load all dynamic doc strings.  */
-  int f_load_force_doc_strings;
-
-  /* Nonzero means read should convert strings to unibyte.  */
-  int f_load_convert_to_unibyte;
-
-  /* Function to use for loading an Emacs Lisp source file (not
-     compiled) instead of readevalloop.  */
-  Lisp_Object f_Vload_source_file_function;
-
-  /* List of all DEFVAR_BOOL variables.  Used by the byte optimizer.  */
-  Lisp_Object f_Vbyte_boolean_vars;
-
-  /* Whether or not to add a `read-positions' property to symbols
-     read. */
-  Lisp_Object f_Vread_with_symbol_positions;
-
-  /* List of (SYMBOL . POSITION) accumulated so far. */
-  Lisp_Object f_Vread_symbol_positions_list;
-
-  Lisp_Object f_Vold_style_backquotes;
-
-  /* Non-zero means load dangerous compiled Lisp files.  */
-  int f_load_dangerous_libraries;
-
-  /* Non-zero means force printing messages when loading Lisp files.  */
-  int f_force_load_messages;
-
-  /* A regular expression used to detect files compiled with Emacs.  */
-  Lisp_Object f_Vbytecomp_version_regexp;
-
-  Lisp_Object f_Vobarray;
-
-  /* Normal hook run whenever a keyboard macro terminates.  */
-  Lisp_Object f_Vkbd_macro_termination_hook;
-
-  /* Kbd macro currently being executed (a string or vector).  */
-  Lisp_Object f_Vexecuting_kbd_macro;
-
-  /* Index of next character to fetch from that macro.  */
-  EMACS_INT f_executing_kbd_macro_index;
-
-  /* Nonzero means enable debugging checks on byte/char correspondences.  */
-  int f_byte_debug_flag;
-
-  Lisp_Object f_Vhistory_length;
-
-  /* No duplicates in history.  */
-  int f_history_delete_duplicates;
-
-  /* Non-nil means add new input to history.  */
-  Lisp_Object f_Vhistory_add_new_input;
-
-  /* Nonzero means let functions called when within a minibuffer
-     invoke recursive minibuffers (to read arguments, or whatever) */
-  int f_enable_recursive_minibuffers;
-
-  /* Nonzero means don't ignore text properties
-     in Fread_from_minibuffer.  */
-  int f_minibuffer_allow_text_properties;
-
-  /* help-form is bound to this while in the minibuffer.  */
-  Lisp_Object f_Vminibuffer_help_form;
-
-  /* Variable which is the history list to add minibuffer values to.  */
-  Lisp_Object f_Vminibuffer_history_variable;
-
-  /* Current position in the history list (adjusted by M-n and M-p).  */
-  Lisp_Object f_Vminibuffer_history_position;
-
-  /* Text properties that are added to minibuffer prompts.
-     These are in addition to the basic `field' property, and stickiness
-     properties.  */
-  Lisp_Object f_Vminibuffer_prompt_properties;
-
-  Lisp_Object f_Vminibuffer_setup_hook;
-
-  Lisp_Object f_Vminibuffer_exit_hook;
-
-  Lisp_Object f_Vread_expression_history;
-
-  /* Function to call to read a buffer name.  */
-  Lisp_Object f_Vread_buffer_function;
-
-  /* Nonzero means completion ignores case.  */
-  int f_completion_ignore_case;
-
-  int f_read_buffer_completion_ignore_case;
-
-  /* List of regexps that should restrict possible completions.  */
-  Lisp_Object f_Vcompletion_regexp_list;
-
-  /* Nonzero means raise the minibuffer frame when the minibuffer
-     is entered.  */
-  int f_minibuffer_auto_raise;
-
-  /* Keymap for reading expressions.  */
-  Lisp_Object f_Vread_expression_map;
-
-  Lisp_Object f_Vminibuffer_completion_table;
-
-  Lisp_Object f_Vminibuffer_completion_predicate;
-
-  Lisp_Object f_Vminibuffer_completion_confirm;
-
-  Lisp_Object f_Vminibuffer_completing_file_name;
-
-  Lisp_Object f_Vdos_unsupported_char_glyph;
-
-  Lisp_Object f_Vstandard_output;
-
-  Lisp_Object f_Vfloat_output_format;
-
-  /* Maximum length of list to print in full; noninteger means
-     effectively infinity */
-  Lisp_Object f_Vprint_length;
-
-  /* Maximum depth of list to print in full; noninteger means
-     effectively infinity.  */
-  Lisp_Object f_Vprint_level;
-
-  /* Nonzero means print newlines in strings as \n.  */
-  int f_print_escape_newlines;
-
-  /* Nonzero means to print single-byte non-ascii characters in strings as
-     octal escapes.  */
-  int f_print_escape_nonascii;
-
-  /* Nonzero means to print multibyte characters in strings as hex escapes.  */
-  int f_print_escape_multibyte;
-
-  /* Nonzero means print (quote foo) forms as 'foo, etc.  */
-  int f_print_quoted;
-
-  /* Non-nil means print #: before uninterned symbols.  */
-  Lisp_Object f_Vprint_gensym;
-
-  /* Non-nil means print recursive structures using #n= and #n# syntax.  */
-  Lisp_Object f_Vprint_circle;
-
-  /* Non-nil means keep continuous number for #n= and #n# syntax
-     between several print functions.  */
-  Lisp_Object f_Vprint_continuous_numbering;
-
-  Lisp_Object f_Vprint_number_table;
-
-  /* A flag to control printing of `charset' text property.
-     The default value is Qdefault. */
-  Lisp_Object f_Vprint_charset_text_property;
-
-  /* Nonzero means delete a process right away if it exits.  */
-  int f_delete_exited_processes;
-
-  /* t means use pty, nil means use a pipe,
-     maybe other values to come.  */
-  Lisp_Object f_Vprocess_connection_type;
-
-  /* Non-nil means to delay reading process output to improve buffering.
-     A value of t means that delay is reset after each send, any other
-     non-nil value does not reset the delay.  A value of nil disables
-     adaptive read buffering completely.  */
-  Lisp_Object f_Vprocess_adaptive_read_buffering;
-
-  Lisp_Object f_Vsearch_spaces_regexp;
-
-  /* If non-nil, the match data will not be changed during call to
-     searching or matching functions.  This variable is for internal use
-     only.  */
-  Lisp_Object f_Vinhibit_changing_match_data;
-
-  int f_words_include_escapes;
-
-  int f_parse_sexp_lookup_properties;
-
-  /* Nonzero means `scan-sexps' treat all multibyte characters as symbol.  */
-  int f_multibyte_syntax_as_symbol;
-
-  /* Non-zero means an open parenthesis in column 0 is always considered
-     to be the start of a defun.  Zero means an open parenthesis in
-     column 0 has no special meaning.  */
-  int f_open_paren_in_column_0_is_defun_start;
-
-  int f_parse_sexp_ignore_comments;
-
-  /* Char-table of functions that find the next or previous word
-     boundary.  */
-  Lisp_Object f_Vfind_word_boundary_function_table;
-
-  /* If true, use "vs", otherwise use "ve" to make the cursor visible.  */
-  int f_visible_cursor;
-
-  /* Functions to call after suspending a tty. */
-  Lisp_Object f_Vsuspend_tty_functions;
-
-  /* Functions to call after resuming a tty. */
-  Lisp_Object f_Vresume_tty_functions;
-
-  /* Nonzero means no need to redraw the entire frame on resuming a
-     suspended Emacs.  This is useful on terminals with multiple
-     pages, where one page is used for Emacs and another for all
-     else. */
-  int f_no_redraw_on_reenter;
-
-  /* Provided for lisp packages.  */
-  int f_system_uses_terminfo;
-
-  /* Function to use to ring the bell.  */
-  Lisp_Object f_Vring_bell_function;
-
-  Lisp_Object f_Vdelete_terminal_functions;
-
-  Lisp_Object f_Vinhibit_point_motion_hooks;
-
-  Lisp_Object f_Vdefault_text_properties;
-
-  Lisp_Object f_Vchar_property_alias_alist;
-
-  Lisp_Object f_Vtext_property_default_nonsticky;
-
-  /* Limits controlling how much undo information to keep.  */
-  EMACS_INT f_undo_limit;
-
-  EMACS_INT f_undo_strong_limit;
-
-  Lisp_Object f_Vundo_outer_limit;
-
-  /* Function to call when undo_outer_limit is exceeded.  */
-  Lisp_Object f_Vundo_outer_limit_function;
-
-  /* Nonzero means do not record point in record_point.  */
-  int f_undo_inhibit_record_point;
-
-  /* Coding system for communicating with other Windows programs via the
-     clipboard.  */
-  Lisp_Object f_Vselection_coding_system;
-
-  /* Coding system for the next communicating with other Windows programs.  */
-  Lisp_Object f_Vnext_selection_coding_system;
-
-  /* Determine whether to make frame dimensions match the screen buffer,
-     or the current window size.  The former is desirable when running
-     over telnet, while the latter is more useful when working directly at
-     the console with a large scroll-back buffer.  */
-  int f_w32_use_full_screen_buffer;
-
-  /* The colormap for converting color names to RGB values */
-  Lisp_Object f_Vw32_color_map;
-
-  /* Non nil if alt key presses are passed on to Windows.  */
-  Lisp_Object f_Vw32_pass_alt_to_system;
-
-  /* Non nil if alt key is translated to meta_modifier, nil if it is translated
-     to alt_modifier.  */
-  Lisp_Object f_Vw32_alt_is_meta;
-
-  /* If non-zero, the windows virtual key code for an alternative quit key. */
-  int f_w32_quit_key;
-
-  /* Non nil if left window key events are passed on to Windows (this only
-     affects whether "tapping" the key opens the Start menu).  */
-  Lisp_Object f_Vw32_pass_lwindow_to_system;
-
-  /* Non nil if right window key events are passed on to Windows (this
-     only affects whether "tapping" the key opens the Start menu).  */
-  Lisp_Object f_Vw32_pass_rwindow_to_system;
-
-  /* Virtual key code used to generate "phantom" key presses in order
-     to stop system from acting on Windows key events.  */
-  Lisp_Object f_Vw32_phantom_key_code;
-
-  /* Modifier associated with the left "Windows" key, or nil to act as a
-     normal key.  */
-  Lisp_Object f_Vw32_lwindow_modifier;
-
-  /* Modifier associated with the right "Windows" key, or nil to act as a
-     normal key.  */
-  Lisp_Object f_Vw32_rwindow_modifier;
-
-  /* Modifier associated with the "Apps" key, or nil to act as a normal
-     key.  */
-  Lisp_Object f_Vw32_apps_modifier;
-
-  /* Value is nil if Num Lock acts as a function key.  */
-  Lisp_Object f_Vw32_enable_num_lock;
-
-  /* Value is nil if Caps Lock acts as a function key.  */
-  Lisp_Object f_Vw32_enable_caps_lock;
-
-  /* Modifier associated with Scroll Lock, or nil to act as a normal key.  */
-  Lisp_Object f_Vw32_scroll_lock_modifier;
-
-  /* Switch to control whether we inhibit requests for synthesized bold
-     and italic versions of fonts.  */
-  int f_w32_enable_synthesized_fonts;
-
-  /* Enable palette management. */
-  Lisp_Object f_Vw32_enable_palette;
-
-  /* Control how close left/right button down events must be to
-     be converted to a middle button down event. */
-  int f_w32_mouse_button_tolerance;
-
-  /* Minimum interval between mouse movement (and scroll bar drag)
-     events that are passed on to the event loop. */
-  int f_w32_mouse_move_interval;
-
-  /* Flag to indicate if XBUTTON events should be passed on to Windows.  */
-  int f_w32_pass_extra_mouse_buttons_to_system;
-
-  /* Flag to indicate if media keys should be passed on to Windows.  */
-  int f_w32_pass_multimedia_buttons_to_system;
-
-  /* Non nil if no window manager is in use.  */
-  Lisp_Object f_Vx_no_window_manager;
-
-  /* The background and shape of the mouse pointer, and shape when not
-     over text or in the modeline.  */
-  Lisp_Object f_Vx_pointer_shape;
-  Lisp_Object f_Vx_nontext_pointer_shape;
-  Lisp_Object f_Vx_mode_pointer_shape;
-
-  /* TODO: Mouse cursor customization.  */
-  Lisp_Object f_Vx_hourglass_pointer_shape;
-  Lisp_Object f_Vx_window_horizontal_drag_shape;
-
-  /* The shape when over mouse-sensitive text.  */
-  Lisp_Object f_Vx_sensitive_text_pointer_shape;
-
-  /* Color of chars displayed in cursor box.  */
-  Lisp_Object f_Vx_cursor_fore_pixel;
-
-  /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
-  Lisp_Object f_Vx_pixel_size_width_font_regexp;
-
-  /* Alist of bdf fonts and the files that define them.  */
-  Lisp_Object f_Vw32_bdf_filename_alist;
-
-  /* A flag to control whether fonts are matched strictly or not.  */
-  int f_w32_strict_fontnames;
-
-  /* A flag to control whether we should only repaint if GetUpdateRect
-     indicates there is an update region.  */
-  int f_w32_strict_painting;
-
-  /* The ANSI codepage.  */
-  int f_w32_ansi_code_page;
-
-  /* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
-  Lisp_Object f_Vx_max_tooltip_size;
-
-  /* Associative list linking character set strings to Windows codepages. */
-  Lisp_Object f_Vw32_charset_info_alist;
-
-  /* Control whether spawnve quotes arguments as necessary to ensure
-     correct parsing by child process.  Because not all uses of spawnve
-     are careful about constructing argv arrays, we make this behavior
-     conditional (off by default). */
-  Lisp_Object f_Vw32_quote_process_args;
-
-  /* Control whether create_child causes the process' window to be
-     hidden.  The default is nil. */
-  Lisp_Object f_Vw32_start_process_show_window;
-
-  /* Control whether create_child causes the process to inherit Emacs'
-     console window, or be given a new one of its own.  The default is
-     nil, to allow multiple DOS programs to run on Win95.  Having separate
-     consoles also allows Emacs to cleanly terminate process groups.  */
-  Lisp_Object f_Vw32_start_process_share_console;
-
-  /* Control whether create_child cause the process to inherit Emacs'
-     error mode setting.  The default is t, to minimize the possibility of
-     subprocesses blocking when accessing unmounted drives.  */
-  Lisp_Object f_Vw32_start_process_inherit_error_mode;
-
-  /* Time to sleep before reading from a subprocess output pipe - this
-     avoids the inefficiency of frequently reading small amounts of data.
-     This is primarily necessary for handling DOS processes on Windows 95,
-     but is useful for W32 processes on both Windows 95 and NT as well.  */
-  int f_w32_pipe_read_delay;
-
-  /* Control conversion of upper case file names to lower case.
-     nil means no, t means yes. */
-  Lisp_Object f_Vw32_downcase_file_names;
-
-  /* Control whether stat() attempts to generate fake but hopefully
-     "accurate" inode values, by hashing the absolute truenames of files.
-     This should detect aliasing between long and short names, but still
-     allows the possibility of hash collisions.  */
-  Lisp_Object f_Vw32_generate_fake_inodes;
-
-  /* Control whether stat() attempts to determine file type and link count
-     exactly, at the expense of slower operation.  Since true hard links
-     are supported on NTFS volumes, this is only relevant on NT.  */
-  Lisp_Object f_Vw32_get_true_file_attributes;
-
-  /* Coding system for communicating with other programs via the
-     clipboard.  */
-
-  /* Coding system for the next communication with other programs.  */
-
-  /* Non-nil means Emacs uses toolkit scroll bars.  */
-  Lisp_Object f_Vx_toolkit_scroll_bars;
-
-  /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
-  int f_x_use_underline_position_properties;
-
-  /* Non-zero means to draw the underline at the same place as the descent line.  */
-  int f_x_underline_at_descent_line;
-
-  int f_w32_use_visible_system_caret;
-
-  int f_w32_num_mouse_buttons;
-
-  Lisp_Object f_Vw32_swap_mouse_buttons;
-
-  /* Control whether x_raise_frame also sets input focus.  */
-  Lisp_Object f_Vw32_grab_focus_on_raise;
-
-  /* Control whether Caps Lock affects non-ascii characters.  */
-  Lisp_Object f_Vw32_capslock_is_shiftlock;
-
-  /* Control whether right-alt and left-ctrl should be recognized as AltGr.  */
-  Lisp_Object f_Vw32_recognize_altgr;
-
-  /* Non-nil means it is the window for C-M-v to scroll
-     when the mini-buffer is selected.  */
-  Lisp_Object f_Vminibuf_scroll_window;
-
-  /* Non-nil means this is the buffer whose window C-M-v should scroll.  */
-  Lisp_Object f_Vother_window_scroll_buffer;
-
-  /* Non-nil means it's function to call to display temp buffers.  */
-  Lisp_Object f_Vtemp_buffer_show_function;
-
-  /* Non-zero means line and page scrolling on tall lines (with images)
-     does partial scrolling by modifying window-vscroll.  */
-  int f_auto_window_vscroll_p;
-
-  /* Non-zero means to use mode-line-inactive face in all windows but the
-     selected-window and the minibuffer-scroll-window when the
-     minibuffer is active.  */
-  int f_mode_line_in_non_selected_windows;
-
-  /* If a window gets smaller than either of these, it is removed. */
-  EMACS_INT f_window_min_height;
-
-  EMACS_INT f_window_min_width;
-
-  /* Number of lines of continuity in scrolling by screenfuls.  */
-  EMACS_INT f_next_screen_context_lines;
-
-  Lisp_Object f_Vwindow_configuration_change_hook;
-
-  /* Non-nil means scroll commands try to put point
-     at the same screen height as previously.  */
-  Lisp_Object f_Vscroll_preserve_screen_position;
-
-  /* Non-nil means that text is inserted before window's markers.  */
-  Lisp_Object f_Vwindow_point_insertion_type;
-
-  /* If non-nil, then the `recenter' command with a nil argument
-     the entire frame to be redrawn; the special value `tty' causes the
-     frame to be redrawn only if it is a tty frame.  */
-  Lisp_Object f_Vrecenter_redisplay;
-
-  Lisp_Object f_Vwindow_scroll_functions;
-
-  Lisp_Object f_Vwindow_text_change_functions;
-
-  Lisp_Object f_Vredisplay_end_trigger_functions;
-
-  /* Functions called to fontify regions of text.  */
-  Lisp_Object f_Vfontification_functions;
-
-  /* Non-nil means automatically select any window when the mouse
-     cursor moves into it.  */
-  Lisp_Object f_Vmouse_autoselect_window;
-
-  Lisp_Object f_Vwrap_prefix;
-
-  Lisp_Object f_Vline_prefix;
-
-  /* Non-zero means draw tool bar buttons raised when the mouse moves
-     over them.  */
-  int f_auto_raise_tool_bar_buttons_p;
-
-  /* Non-zero means to reposition window if cursor line is only partially visible.  */
-  int f_make_cursor_line_fully_visible_p;
-
-  /* Margin below tool bar in pixels.  0 or nil means no margin.
-     If value is `internal-border-width' or `border-width',
-     the corresponding frame parameter is used.  */
-  Lisp_Object f_Vtool_bar_border;
-
-  /* Margin around tool bar buttons in pixels.  */
-  Lisp_Object f_Vtool_bar_button_margin;
-
-  /* Thickness of shadow to draw around tool bar buttons.  */
-  EMACS_INT f_tool_bar_button_relief;
-
-  /* Non-nil means automatically resize tool-bars so that all tool-bar
-     items are visible, and no blank lines remain.
-
-     If value is `grow-only', only make tool-bar bigger.  */
-  Lisp_Object f_Vauto_resize_tool_bars;
-
-  /* Type of tool bar.  Can be symbols image, text, both or both-hroiz.  */
-  Lisp_Object f_Vtool_bar_style;
-
-  /* Maximum number of characters a label can have to be shown.  */
-  EMACS_INT f_tool_bar_max_label_size;
-
-  /* Non-zero means draw block and hollow cursor as wide as the glyph
-     under it.  For example, if a block cursor is over a tab, it will be
-     drawn as wide as that tab on the display.  */
-  int f_x_stretch_cursor_p;
-
-  Lisp_Object f_Vinhibit_redisplay;
-
-  /* Non-zero means Lisp evaluation during redisplay is inhibited.  */
-  int f_inhibit_eval_during_redisplay;
-
-  /* Symbols used in text property values.  */
-  Lisp_Object f_Vdisplay_pixels_per_inch;
-
-  /* Non-nil means highlight trailing whitespace.  */
-  Lisp_Object f_Vshow_trailing_whitespace;
-
-  /* Non-nil means escape non-break space and hyphens.  */
-  Lisp_Object f_Vnobreak_char_display;
-
-  /* Non-nil means show the text cursor in void text areas
-     i.e. in blank areas after eol and eob.  This used to be
-     the default in 21.3.  */
-  Lisp_Object f_Vvoid_text_area_pointer;
-
-  /* Nonzero means truncate lines in all windows less wide than the
-     frame.  */
-  Lisp_Object f_Vtruncate_partial_width_windows;
-
-  /* A flag to control how to display unibyte 8-bit character.  */
-  int f_unibyte_display_via_language_environment;
-
-  /* Nonzero means we have more than one non-mini-buffer-only frame.
-     Not guaranteed to be accurate except while parsing
-     frame-title-format.  */
-  int f_multiple_frames;
-
-  Lisp_Object f_Vglobal_mode_string;
-
-  /* List of variables (symbols) which hold markers for overlay arrows.
-     The symbols on this list are examined during redisplay to determine
-     where to display overlay arrows.  */
-  Lisp_Object f_Voverlay_arrow_variable_list;
-
-  /* Marker for where to display an arrow on top of the buffer text.  */
-  Lisp_Object f_Voverlay_arrow_position;
-
-  /* String to display for the arrow.  Only used on terminal frames.  */
-  Lisp_Object f_Voverlay_arrow_string;
-
-  /* Like mode-line-format, but for the title bar on a visible frame.  */
-  Lisp_Object f_Vframe_title_format;
-
-  /* Like mode-line-format, but for the title bar on an iconified frame.  */
-  Lisp_Object f_Vicon_title_format;
-
-  /* List of functions to call when a window's size changes.  These
-     functions get one arg, a frame on which one or more windows' sizes
-     have changed.  */
-  Lisp_Object f_Vwindow_size_change_functions;
-
-  Lisp_Object f_Vmenu_bar_update_hook;
-
-  /* Nonzero means highlight the region even in nonselected windows.  */
-  int f_highlight_nonselected_windows;
-
-  /* If cursor motion alone moves point off frame, try scrolling this
-     many lines up or down if that will bring it back.  */
-  EMACS_INT f_emacs_scroll_step;
-
-  /* Nonzero means scroll just far enough to bring point back on the
-     screen, when appropriate.  */
-  EMACS_INT f_scroll_conservatively;
-
-  /* Recenter the window whenever point gets within this many lines of
-     the top or bottom of the window.  This value is translated into a
-     pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
-     that there is really a fixed pixel height scroll margin.  */
-  EMACS_INT f_scroll_margin;
-
-  /* Zero means display the mode-line/header-line/menu-bar in the default face
-     (this slightly odd definition is for compatibility with previous versions
-     of emacs), non-zero means display them using their respective faces.
-
-     This variable is deprecated.  */
-  int f_mode_line_inverse_video;
-
-  /* Maximum buffer size for which to display line numbers.  */
-  Lisp_Object f_Vline_number_display_limit;
-
-  /* Line width to consider when repositioning for line number display.  */
-  EMACS_INT f_line_number_display_limit_width;
-
-  /* Number of lines to keep in the message log buffer.  t means
-     infinite.  nil means don't log at all.  */
-  Lisp_Object f_Vmessage_log_max;
-
-  int f_inhibit_menubar_update;
-
-  /* When evaluating expressions from menu bar items (enable conditions,
-     for instance), this is the frame they are being processed for.  */
-  Lisp_Object f_Vmenu_updating_frame;
-
-  /* Maximum height for resizing mini-windows.  Either a float
-     specifying a fraction of the available height, or an integer
-     specifying a number of lines.  */
-  Lisp_Object f_Vmax_mini_window_height;
-
-  /* Non-zero means messages should be displayed with truncated
-     lines instead of being continued.  */
-  int f_message_truncate_lines;
-
-  /* How to blink the default frame cursor off.  */
-  Lisp_Object f_Vblink_cursor_alist;
-
-  /* Variables to turn off display optimizations from Lisp.  */
-  int f_inhibit_try_window_id;
-  int f_inhibit_try_window_reusing;
-
-  int f_inhibit_try_cursor_movement;
-
-  /* Non-zero means automatically scroll windows horizontally to make
-     point visible.  */
-  int f_automatic_hscrolling_p;
-
-  /* How close to the margin can point get before the window is scrolled
-     horizontally.  */
-  EMACS_INT f_hscroll_margin;
-
-  /* How much to scroll horizontally when point is inside the above margin.  */
-  Lisp_Object f_Vhscroll_step;
-
-  /* The variable `resize-mini-windows'.  If nil, don't resize
-     mini-windows.  If t, always resize them to fit the text they
-     display.  If `grow-only', let mini-windows grow only until they
-     become empty.  */
-  Lisp_Object f_Vresize_mini_windows;
-
-  /* Space between overline and text. */
-  EMACS_INT f_overline_margin;
-
-  /* Require underline to be at least this many screen pixels below baseline
-     This to avoid underline "merging" with the base of letters at small
-     font sizes, particularly when x_use_underline_position_properties is on. */
-  EMACS_INT f_underline_minimum_offset;
-
-  /* Non-zero means don't free realized faces.  Bound while freeing
-     realized faces is dangerous because glyph matrices might still
-     reference them.  */
-  int f_inhibit_free_realized_faces;
-
-  /* Non-zero means we're allowed to display a hourglass pointer.  */
-  int f_display_hourglass_p;
-
-  /* Number of seconds to wait before displaying an hourglass cursor.  */
-  Lisp_Object f_Vhourglass_delay;
-
-  /* Char-table to control the display of glyphless characters.  */
-  Lisp_Object f_Vglyphless_char_display;
-
-  EMACS_INT f_debug_end_pos;
-
-  /* Default stipple pattern used on monochrome displays.  This stipple
-     pattern is used on monochrome displays instead of shades of gray
-     for a face background color.  See `set-face-stipple' for possible
-     values for this variable.  */
-  Lisp_Object f_Vface_default_stipple;
-
-  Lisp_Object f_Vscalable_fonts_allowed;
-
-  /* List of regular expressions that matches names of fonts to ignore. */
-  Lisp_Object f_Vface_ignored_fonts;
-
-  /* Alist of font name patterns vs the rescaling factor.  */
-  Lisp_Object f_Vface_font_rescale_alist;
-
-  /* Maximum number of fonts to consider in font_list.  If not an
-     integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead.  */
-  Lisp_Object f_Vfont_list_limit;
-
-  /* Alist of global face definitions.  Each element is of the form
-     (FACE . LFACE) where FACE is a symbol naming a face and LFACE
-     is a Lisp vector of face attributes.  These faces are used
-     to initialize faces for new frames.  */
-  Lisp_Object f_Vface_new_frame_defaults;
-
-  /* Alist of face remappings.  Each element is of the form:
-     (FACE REPLACEMENT...) which causes display of the face FACE to use
-     REPLACEMENT... instead.  REPLACEMENT... is interpreted the same way
-     the value of a `face' text property is: it may be (1) A face name,
-     (2) A list of face names, (3) A property-list of face attribute/value
-     pairs, or (4) A list of face names intermixed with lists containing
-     face attribute/value pairs.
-
-     Multiple entries in REPLACEMENT... are merged together to form the final
-     result, with faces or attributes earlier in the list taking precedence
-     over those that are later.
-
-     Face-name remapping cycles are suppressed; recursive references use
-     the underlying face instead of the remapped face.  */
-  Lisp_Object f_Vface_remapping_alist;
-
-  /* An alist of defined terminal colors and their RGB values.  */
-  Lisp_Object f_Vtty_defined_color_alist;
-
-  /* LessTif/Motif version info.  */
-  Lisp_Object f_Vmotif_version_string;
-
-  /* GTK+ version info */
-  Lisp_Object f_Vgtk_version_string;
-
-  /* Non-zero means prompt with the old GTK file selection dialog.  */
-  int f_x_gtk_use_old_file_dialog;
-
-  /* If non-zero, by default show hidden files in the GTK file chooser.  */
-  int f_x_gtk_show_hidden_files;
-
-  /* If non-zero, don't show additional help text in the GTK file chooser.  */
-  int f_x_gtk_file_dialog_help_text;
-
-  /* If non-zero, don't collapse to tool bar when it is detached.  */
-  int f_x_gtk_whole_detached_tool_bar;
-
-  /* If non-zero, use Gtk+ tooltips.  */
-  int f_x_gtk_use_system_tooltips;
-
-  /* The background and shape of the mouse pointer, and shape when not
-     over text or in the modeline.  */
-
-  /* The shape when over mouse-sensitive text.  */
-
-  /* If non-nil, the pointer shape to indicate that windows can be
-     dragged horizontally.  */
-
-  /* Color of chars displayed in cursor box.  */
-
-  /* Non nil if no window manager is in use.  */
-
-  /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
-
-  /* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
-
-  Lisp_Object f_Vx_lost_selection_functions;
-
-  Lisp_Object f_Vx_sent_selection_functions;
-
-  /* This is an alist whose CARs are selection-types (whose names are the same
-     as the names of X Atoms) and whose CDRs are the names of Lisp functions to
-     call to convert the given Emacs selection value to a string representing
-     the given selection type.  This is for Lisp-level extension of the emacs
-     selection handling.  */
-  Lisp_Object f_Vselection_converter_alist;
-
-  /* If the selection owner takes too long to reply to a selection request,
-     we give up on it.  This is in milliseconds (0 = no timeout.)  */
-  EMACS_INT f_x_selection_timeout;
-
-  int f_use_system_font;
-
-  Lisp_Object f_Vxft_settings;
-
-  /* The client session id for this session as a lisp object.  */
-  Lisp_Object f_Vx_session_id;
-
-  /* The id we had the previous session.  This is only available if we
-     have been started by the session manager with SMID_OPT.  */
-  Lisp_Object f_Vx_session_previous_id;
-
-  /* Non-nil means Emacs uses toolkit scroll bars.  */
-
-  /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
-
-  /* Non-zero means to draw the underline at the same place as the descent line.  */
-
-  /* Non-zero means to not move point as a result of clicking on a
-     frame to focus it (when focus-follows-mouse is nil).  */
-  int f_x_mouse_click_focus_ignore_position;
-
-  /* The keysyms to use for the various modifiers.  */
-  Lisp_Object f_Vx_alt_keysym;
-  Lisp_Object f_Vx_hyper_keysym;
-  Lisp_Object f_Vx_meta_keysym;
-  Lisp_Object f_Vx_super_keysym;
-
-  Lisp_Object f_Vx_keysym_table;
-
-  /* Lisp communications */
-  Lisp_Object f_ns_input_file, f_ns_input_font, f_ns_input_fontsize,
-    f_ns_input_line;
-  Lisp_Object f_ns_input_color, f_ns_input_text, f_ns_working_text;
-  Lisp_Object f_ns_input_spi_name, f_ns_input_spi_arg;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Alternate modifier.  May be Qnone or any of the modifier lisp symbols.
-  */
-  Lisp_Object f_ns_alternate_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the right Alternate modifier.  Has same values as ns_alternate_modifier
-     plus the value Qleft which means whatever value ns_alternate_modifier has.
-  */
-  Lisp_Object f_ns_right_alternate_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Command modifier.  May be any of the modifier lisp symbols. */
-  Lisp_Object f_ns_command_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the right Command modifier.  Has same values as ns_command_modifier plus
-     the value Qleft which means whatever value ns_command_modifier has.  */
-  Lisp_Object f_ns_right_command_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Control modifier.  May be any of the modifier lisp symbols. */
-  Lisp_Object f_ns_control_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the right Control modifier.  Has same values as ns_control_modifier plus
-     the value Qleft which means whatever value ns_control_modifier has.  */
-  Lisp_Object f_ns_right_control_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Function modifier (laptops).  May be any of the modifier lisp symbols.
-  */
-  Lisp_Object f_ns_function_modifier;
-
-  /* Control via default 'GSFontAntiAlias' on OS X and GNUstep. */
-  Lisp_Object f_ns_antialias_text;
-
-  /* Confirm on exit. */
-  Lisp_Object f_ns_confirm_quit;
-
-  /* Alist of elements (REGEXP . IMAGE) for images of icons associated
-     to frames.*/
-  Lisp_Object f_Vns_icon_type_alist;
-
-  /* Toolkit version support. */
-  Lisp_Object f_Vns_version_string;
-
-  Lisp_Object f_Vns_sent_selection_hooks;
-  Lisp_Object f_Vns_lost_selection_hooks;
-
-  /* This is an association list whose elements are of the form
-       ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
-     SELECTION-NAME is a lisp symbol, whose name is the name of an X Atom.
-     SELECTION-VALUE is the value that emacs owns for that selection.
-       It may be any kind of Lisp object.
-     SELECTION-TIMESTAMP is the time at which emacs began owning this
-       selection, as a cons of two 16-bit numbers (making a 32 bit time.)
-     FRAME is the frame for which we made the selection.
-     If there is an entry in this alist, then it can be assumed that Emacs owns
-      that selection.
-     The only (eq) parts of this list that are visible from Lisp are the
-      selection-values.  */
-  Lisp_Object f_Vselection_alist;
-
-  Lisp_Object f_Vns_reg_to_script;
-
-
-};
-
-extern struct emacs_globals globals;
-
-#define Vafter_change_functions \
-    globals.f_Vafter_change_functions
-#define Vafter_init_time \
-    globals.f_Vafter_init_time
-#define Vafter_insert_file_functions \
-    globals.f_Vafter_insert_file_functions
-#define Vafter_load_alist \
-    globals.f_Vafter_load_alist
-#define Valternate_fontname_alist \
-    globals.f_Valternate_fontname_alist
-#define Vauto_composition_function \
-    globals.f_Vauto_composition_function
-#define Vauto_composition_mode \
-    globals.f_Vauto_composition_mode
-#define Vauto_fill_chars \
-    globals.f_Vauto_fill_chars
-#define Vauto_resize_tool_bars \
-    globals.f_Vauto_resize_tool_bars
-#define Vauto_save_include_big_deletions \
-    globals.f_Vauto_save_include_big_deletions
-#define Vauto_save_list_file_name \
-    globals.f_Vauto_save_list_file_name
-#define Vauto_save_timeout \
-    globals.f_Vauto_save_timeout
-#define Vauto_save_visited_file_name \
-    globals.f_Vauto_save_visited_file_name
-#define Vbefore_change_functions \
-    globals.f_Vbefore_change_functions
-#define Vbefore_init_time \
-    globals.f_Vbefore_init_time
-#define Vblink_cursor_alist \
-    globals.f_Vblink_cursor_alist
-#define Vbuffer_access_fontified_property \
-    globals.f_Vbuffer_access_fontified_property
-#define Vbuffer_access_fontify_functions \
-    globals.f_Vbuffer_access_fontify_functions
-#define Vbuild_files \
-    globals.f_Vbuild_files
-#define Vbyte_boolean_vars \
-    globals.f_Vbyte_boolean_vars
-#define Vbyte_code_meter \
-    globals.f_Vbyte_code_meter
-#define Vbytecomp_version_regexp \
-    globals.f_Vbytecomp_version_regexp
-#define Vchange_major_mode_hook \
-    globals.f_Vchange_major_mode_hook
-#define Vchar_direction_table \
-    globals.f_Vchar_direction_table
-#define Vchar_property_alias_alist \
-    globals.f_Vchar_property_alias_alist
-#define Vchar_script_table \
-    globals.f_Vchar_script_table
-#define Vchar_width_table \
-    globals.f_Vchar_width_table
-#define Vcharset_list \
-    globals.f_Vcharset_list
-#define Vcharset_map_path \
-    globals.f_Vcharset_map_path
-#define Vcharset_revision_table \
-    globals.f_Vcharset_revision_table
-#define Vcode_conversion_map_vector \
-    globals.f_Vcode_conversion_map_vector
-#define Vcoding_category_list \
-    globals.f_Vcoding_category_list
-#define Vcoding_system_alist \
-    globals.f_Vcoding_system_alist
-#define Vcoding_system_for_read \
-    globals.f_Vcoding_system_for_read
-#define Vcoding_system_for_write \
-    globals.f_Vcoding_system_for_write
-#define Vcoding_system_list \
-    globals.f_Vcoding_system_list
-#define Vcombine_after_change_calls \
-    globals.f_Vcombine_after_change_calls
-#define Vcommand_debug_status \
-    globals.f_Vcommand_debug_status
-#define Vcommand_error_function \
-    globals.f_Vcommand_error_function
-#define Vcommand_history \
-    globals.f_Vcommand_history
-#define Vcommand_hook_internal \
-    globals.f_Vcommand_hook_internal
-#define Vcommand_line_args \
-    globals.f_Vcommand_line_args
-#define Vcompletion_ignored_extensions \
-    globals.f_Vcompletion_ignored_extensions
-#define Vcompletion_regexp_list \
-    globals.f_Vcompletion_regexp_list
-#define Vcompose_chars_after_function \
-    globals.f_Vcompose_chars_after_function
-#define Vcomposition_function_table \
-    globals.f_Vcomposition_function_table
-#define Vconfigure_info_directory \
-    globals.f_Vconfigure_info_directory
-#define Vcurrent_iso639_language \
-    globals.f_Vcurrent_iso639_language
-#define Vcurrent_load_list \
-    globals.f_Vcurrent_load_list
-#define Vcurrent_prefix_arg \
-    globals.f_Vcurrent_prefix_arg
-#define Vdata_directory \
-    globals.f_Vdata_directory
-#define Vdbus_debug \
-    globals.f_Vdbus_debug
-#define Vdbus_registered_buses \
-    globals.f_Vdbus_registered_buses
-#define Vdbus_registered_objects_table \
-    globals.f_Vdbus_registered_objects_table
-#define Vdeactivate_mark \
-    globals.f_Vdeactivate_mark
-#define Vdebug_ignored_errors \
-    globals.f_Vdebug_ignored_errors
-#define Vdebug_on_error \
-    globals.f_Vdebug_on_error
-#define Vdebug_on_signal \
-    globals.f_Vdebug_on_signal
-#define Vdebugger \
-    globals.f_Vdebugger
-#define Vdefault_file_name_coding_system \
-    globals.f_Vdefault_file_name_coding_system
-#define Vdefault_frame_alist \
-    globals.f_Vdefault_frame_alist
-#define Vdefault_frame_scroll_bars \
-    globals.f_Vdefault_frame_scroll_bars
-#define Vdefault_process_coding_system \
-    globals.f_Vdefault_process_coding_system
-#define Vdefault_text_properties \
-    globals.f_Vdefault_text_properties
-#define Vdeferred_action_function \
-    globals.f_Vdeferred_action_function
-#define Vdeferred_action_list \
-    globals.f_Vdeferred_action_list
-#define Vdefine_key_rebound_commands \
-    globals.f_Vdefine_key_rebound_commands
-#define Vdelete_frame_functions \
-    globals.f_Vdelete_frame_functions
-#define Vdelete_terminal_functions \
-    globals.f_Vdelete_terminal_functions
-#define Vdisable_point_adjustment \
-    globals.f_Vdisable_point_adjustment
-#define Vdisplay_pixels_per_inch \
-    globals.f_Vdisplay_pixels_per_inch
-#define Vdoc_directory \
-    globals.f_Vdoc_directory
-#define Vdoc_file_name \
-    globals.f_Vdoc_file_name
-#define Vdos_display_scancodes \
-    globals.f_Vdos_display_scancodes
-#define Vdos_unsupported_char_glyph \
-    globals.f_Vdos_unsupported_char_glyph
-#define Vdos_version \
-    globals.f_Vdos_version
-#define Vdos_windows_version \
-    globals.f_Vdos_windows_version
-#define Vdouble_click_time \
-    globals.f_Vdouble_click_time
-#define Vdynamic_library_alist \
-    globals.f_Vdynamic_library_alist
-#define Vecho_keystrokes \
-    globals.f_Vecho_keystrokes
-#define Vemacs_copyright \
-    globals.f_Vemacs_copyright
-#define Vemacs_version \
-    globals.f_Vemacs_version
-#define Vemulation_mode_map_alists \
-    globals.f_Vemulation_mode_map_alists
-#define Venable_character_translation \
-    globals.f_Venable_character_translation
-#define Venable_disabled_menus_and_buttons \
-    globals.f_Venable_disabled_menus_and_buttons
-#define Veval_buffer_list \
-    globals.f_Veval_buffer_list
-#define Vexec_directory \
-    globals.f_Vexec_directory
-#define Vexec_path \
-    globals.f_Vexec_path
-#define Vexec_suffixes \
-    globals.f_Vexec_suffixes
-#define Vkbd_macro_termination_hook \
-    globals.f_Vkbd_macro_termination_hook
-#define Vexecuting_kbd_macro \
-    globals.f_Vexecuting_kbd_macro
-#define Vface_default_stipple \
-    globals.f_Vface_default_stipple
-#define Vface_font_rescale_alist \
-    globals.f_Vface_font_rescale_alist
-#define Vface_ignored_fonts \
-    globals.f_Vface_ignored_fonts
-#define Vface_new_frame_defaults \
-    globals.f_Vface_new_frame_defaults
-#define Vface_remapping_alist \
-    globals.f_Vface_remapping_alist
-#define Vfeatures \
-    globals.f_Vfeatures
-#define Vfile_coding_system_alist \
-    globals.f_Vfile_coding_system_alist
-#define Vfile_name_coding_system \
-    globals.f_Vfile_name_coding_system
-#define Vfile_name_handler_alist \
-    globals.f_Vfile_name_handler_alist
-#define Vfind_word_boundary_function_table \
-    globals.f_Vfind_word_boundary_function_table
-#define Vfirst_change_hook \
-    globals.f_Vfirst_change_hook
-#define Vfloat_output_format \
-    globals.f_Vfloat_output_format
-#define Vfont_ccl_encoder_alist \
-    globals.f_Vfont_ccl_encoder_alist
-#define Vfont_encoding_alist \
-    globals.f_Vfont_encoding_alist
-#define Vfont_encoding_charset_alist \
-    globals.f_Vfont_encoding_charset_alist
-#define Vfont_list_limit \
-    globals.f_Vfont_list_limit
-#define Vfont_log \
-    globals.f_Vfont_log
-#define Vfont_slant_table \
-    globals.f_Vfont_slant_table
-#define Vfont_weight_table \
-    globals.f_Vfont_weight_table
-#define Vfont_width_table \
-    globals.f_Vfont_width_table
-#define Vfontification_functions \
-    globals.f_Vfontification_functions
-#define Vfontset_alias_alist \
-    globals.f_Vfontset_alias_alist
-#define Vframe_alpha_lower_limit \
-    globals.f_Vframe_alpha_lower_limit
-#define Vframe_title_format \
-    globals.f_Vframe_title_format
-#define Vfringe_bitmaps \
-    globals.f_Vfringe_bitmaps
-#define Vfunction_key_map \
-    globals.f_Vfunction_key_map
-#define Vgc_cons_percentage \
-    globals.f_Vgc_cons_percentage
-#define Vgc_elapsed \
-    globals.f_Vgc_elapsed
-#define Vglobal_disable_point_adjustment \
-    globals.f_Vglobal_disable_point_adjustment
-#define Vglobal_mode_string \
-    globals.f_Vglobal_mode_string
-#define Vglyph_table \
-    globals.f_Vglyph_table
-#define Vglyphless_char_display \
-    globals.f_Vglyphless_char_display
-#define Vgtk_version_string \
-    globals.f_Vgtk_version_string
-#define Vhelp_char \
-    globals.f_Vhelp_char
-#define Vhelp_event_list \
-    globals.f_Vhelp_event_list
-#define Vhelp_form \
-    globals.f_Vhelp_form
-#define Vhistory_add_new_input \
-    globals.f_Vhistory_add_new_input
-#define Vhistory_length \
-    globals.f_Vhistory_length
-#define Vhourglass_delay \
-    globals.f_Vhourglass_delay
-#define Vhscroll_step \
-    globals.f_Vhscroll_step
-#define Vicon_title_format \
-    globals.f_Vicon_title_format
-#define Vignore_relative_composition \
-    globals.f_Vignore_relative_composition
-#define Vimage_cache_eviction_delay \
-    globals.f_Vimage_cache_eviction_delay
-#define Vimage_types \
-    globals.f_Vimage_types
-#define Vimagemagick_render_type \
-    globals.f_Vimagemagick_render_type
-#define Vinhibit_changing_match_data \
-    globals.f_Vinhibit_changing_match_data
-#define Vinhibit_field_text_motion \
-    globals.f_Vinhibit_field_text_motion
-#define Vinhibit_file_name_handlers \
-    globals.f_Vinhibit_file_name_handlers
-#define Vinhibit_file_name_operation \
-    globals.f_Vinhibit_file_name_operation
-#define Vinhibit_point_motion_hooks \
-    globals.f_Vinhibit_point_motion_hooks
-#define Vinhibit_quit \
-    globals.f_Vinhibit_quit
-#define Vinhibit_read_only \
-    globals.f_Vinhibit_read_only
-#define Vinhibit_redisplay \
-    globals.f_Vinhibit_redisplay
-#define Vinitial_environment \
-    globals.f_Vinitial_environment
-#define Vinitial_window_system \
-    globals.f_Vinitial_window_system
-#define Vinput_method_function \
-    globals.f_Vinput_method_function
-#define Vinput_method_previous_message \
-    globals.f_Vinput_method_previous_message
-#define Vinstallation_directory \
-    globals.f_Vinstallation_directory
-#define Vinvocation_directory \
-    globals.f_Vinvocation_directory
-#define Vinvocation_name \
-    globals.f_Vinvocation_name
-#define Vkey_translation_map \
-    globals.f_Vkey_translation_map
-#define Vkill_buffer_query_functions \
-    globals.f_Vkill_buffer_query_functions
-#define Vkill_emacs_hook \
-    globals.f_Vkill_emacs_hook
-#define Vlast_code_conversion_error \
-    globals.f_Vlast_code_conversion_error
-#define Vlast_coding_system_used \
-    globals.f_Vlast_coding_system_used
-#define Vlast_event_frame \
-    globals.f_Vlast_event_frame
-#define Vlatin_extra_code_table \
-    globals.f_Vlatin_extra_code_table
-#define Vline_number_display_limit \
-    globals.f_Vline_number_display_limit
-#define Vline_prefix \
-    globals.f_Vline_prefix
-#define Vload_file_name \
-    globals.f_Vload_file_name
-#define Vload_file_rep_suffixes \
-    globals.f_Vload_file_rep_suffixes
-#define Vload_history \
-    globals.f_Vload_history
-#define Vload_path \
-    globals.f_Vload_path
-#define Vload_read_function \
-    globals.f_Vload_read_function
-#define Vload_source_file_function \
-    globals.f_Vload_source_file_function
-#define Vload_suffixes \
-    globals.f_Vload_suffixes
-#define Vlocale_coding_system \
-    globals.f_Vlocale_coding_system
-#define Vlucid_menu_bar_dirty_flag \
-    globals.f_Vlucid_menu_bar_dirty_flag
-#define Vmacro_declaration_function \
-    globals.f_Vmacro_declaration_function
-#define Vmake_pointer_invisible \
-    globals.f_Vmake_pointer_invisible
-#define Vmark_even_if_inactive \
-    globals.f_Vmark_even_if_inactive
-#define Vmax_image_size \
-    globals.f_Vmax_image_size
-#define Vmax_mini_window_height \
-    globals.f_Vmax_mini_window_height
-#define Vmemory_full \
-    globals.f_Vmemory_full
-#define Vmemory_signal_data \
-    globals.f_Vmemory_signal_data
-#define Vmenu_bar_final_items \
-    globals.f_Vmenu_bar_final_items
-#define Vmenu_bar_mode \
-    globals.f_Vmenu_bar_mode
-#define Vmenu_bar_update_hook \
-    globals.f_Vmenu_bar_update_hook
-#define Vmenu_updating_frame \
-    globals.f_Vmenu_updating_frame
-#define Vmessage_log_max \
-    globals.f_Vmessage_log_max
-#define Vminibuf_scroll_window \
-    globals.f_Vminibuf_scroll_window
-#define Vminibuffer_completing_file_name \
-    globals.f_Vminibuffer_completing_file_name
-#define Vminibuffer_completion_confirm \
-    globals.f_Vminibuffer_completion_confirm
-#define Vminibuffer_completion_predicate \
-    globals.f_Vminibuffer_completion_predicate
-#define Vminibuffer_completion_table \
-    globals.f_Vminibuffer_completion_table
-#define Vminibuffer_exit_hook \
-    globals.f_Vminibuffer_exit_hook
-#define Vminibuffer_help_form \
-    globals.f_Vminibuffer_help_form
-#define Vminibuffer_history_position \
-    globals.f_Vminibuffer_history_position
-#define Vminibuffer_history_variable \
-    globals.f_Vminibuffer_history_variable
-#define Vminibuffer_local_completion_map \
-    globals.f_Vminibuffer_local_completion_map
-#define Vminibuffer_local_filename_completion_map \
-    globals.f_Vminibuffer_local_filename_completion_map
-#define Vminibuffer_local_filename_must_match_map \
-    globals.f_Vminibuffer_local_filename_must_match_map
-#define Vminibuffer_local_map \
-    globals.f_Vminibuffer_local_map
-#define Vminibuffer_local_must_match_map \
-    globals.f_Vminibuffer_local_must_match_map
-#define Vminibuffer_local_ns_map \
-    globals.f_Vminibuffer_local_ns_map
-#define Vminibuffer_message_timeout \
-    globals.f_Vminibuffer_message_timeout
-#define Vminibuffer_prompt_properties \
-    globals.f_Vminibuffer_prompt_properties
-#define Vminibuffer_setup_hook \
-    globals.f_Vminibuffer_setup_hook
-#define Vminor_mode_map_alist \
-    globals.f_Vminor_mode_map_alist
-#define Vminor_mode_overriding_map_alist \
-    globals.f_Vminor_mode_overriding_map_alist
-#define Vmost_negative_fixnum \
-    globals.f_Vmost_negative_fixnum
-#define Vmost_positive_fixnum \
-    globals.f_Vmost_positive_fixnum
-#define Vmotif_version_string \
-    globals.f_Vmotif_version_string
-#define Vmouse_autoselect_window \
-    globals.f_Vmouse_autoselect_window
-#define Vmouse_highlight \
-    globals.f_Vmouse_highlight
-#define Vmouse_leave_buffer_hook \
-    globals.f_Vmouse_leave_buffer_hook
-#define Vmouse_position_function \
-    globals.f_Vmouse_position_function
-#define Vnetwork_coding_system_alist \
-    globals.f_Vnetwork_coding_system_alist
-#define Vnext_selection_coding_system \
-    globals.f_Vnext_selection_coding_system
-#define Vnobreak_char_display \
-    globals.f_Vnobreak_char_display
-#define Vobarray \
-    globals.f_Vobarray
-#define Vold_style_backquotes \
-    globals.f_Vold_style_backquotes
-#define Voperating_system_release \
-    globals.f_Voperating_system_release
-#define Votf_script_alist \
-    globals.f_Votf_script_alist
-#define Vother_window_scroll_buffer \
-    globals.f_Vother_window_scroll_buffer
-#define Voverflow_newline_into_fringe \
-    globals.f_Voverflow_newline_into_fringe
-#define Voverlay_arrow_position \
-    globals.f_Voverlay_arrow_position
-#define Voverlay_arrow_string \
-    globals.f_Voverlay_arrow_string
-#define Voverlay_arrow_variable_list \
-    globals.f_Voverlay_arrow_variable_list
-#define Voverriding_local_map \
-    globals.f_Voverriding_local_map
-#define Voverriding_local_map_menu_flag \
-    globals.f_Voverriding_local_map_menu_flag
-#define Vpath_separator \
-    globals.f_Vpath_separator
-#define Vpost_command_hook \
-    globals.f_Vpost_command_hook
-#define Vpost_gc_hook \
-    globals.f_Vpost_gc_hook
-#define Vpost_self_insert_hook \
-    globals.f_Vpost_self_insert_hook
-#define Vpre_command_hook \
-    globals.f_Vpre_command_hook
-#define Vprefix_help_command \
-    globals.f_Vprefix_help_command
-#define Vpreloaded_file_list \
-    globals.f_Vpreloaded_file_list
-#define Vprevious_system_messages_locale \
-    globals.f_Vprevious_system_messages_locale
-#define Vprevious_system_time_locale \
-    globals.f_Vprevious_system_time_locale
-#define Vprint_charset_text_property \
-    globals.f_Vprint_charset_text_property
-#define Vprint_circle \
-    globals.f_Vprint_circle
-#define Vprint_continuous_numbering \
-    globals.f_Vprint_continuous_numbering
-#define Vprint_gensym \
-    globals.f_Vprint_gensym
-#define Vprint_length \
-    globals.f_Vprint_length
-#define Vprint_level \
-    globals.f_Vprint_level
-#define Vprint_number_table \
-    globals.f_Vprint_number_table
-#define Vprintable_chars \
-    globals.f_Vprintable_chars
-#define Vprocess_adaptive_read_buffering \
-    globals.f_Vprocess_adaptive_read_buffering
-#define Vprocess_coding_system_alist \
-    globals.f_Vprocess_coding_system_alist
-#define Vprocess_connection_type \
-    globals.f_Vprocess_connection_type
-#define Vprocess_environment \
-    globals.f_Vprocess_environment
-#define Vpurify_flag \
-    globals.f_Vpurify_flag
-#define Vquit_flag \
-    globals.f_Vquit_flag
-#define Vread_buffer_function \
-    globals.f_Vread_buffer_function
-#define Vread_expression_history \
-    globals.f_Vread_expression_history
-#define Vread_circle \
-    globals.f_Vread_circle
-#define Vread_expression_map \
-    globals.f_Vread_expression_map
-#define Vread_symbol_positions_list \
-    globals.f_Vread_symbol_positions_list
-#define Vread_with_symbol_positions \
-    globals.f_Vread_with_symbol_positions
-#define Vrecenter_redisplay \
-    globals.f_Vrecenter_redisplay
-#define Vredisplay_end_trigger_functions \
-    globals.f_Vredisplay_end_trigger_functions
-#define Vredisplay_preemption_period \
-    globals.f_Vredisplay_preemption_period
-#define Vresize_mini_windows \
-    globals.f_Vresize_mini_windows
-#define Vresume_tty_functions \
-    globals.f_Vresume_tty_functions
-#define Vring_bell_function \
-    globals.f_Vring_bell_function
-#define Vsaved_region_selection \
-    globals.f_Vsaved_region_selection
-#define Vscalable_fonts_allowed \
-    globals.f_Vscalable_fonts_allowed
-#define Vscript_representative_chars \
-    globals.f_Vscript_representative_chars
-#define Vscroll_preserve_screen_position \
-    globals.f_Vscroll_preserve_screen_position
-#define Vsearch_spaces_regexp \
-    globals.f_Vsearch_spaces_regexp
-#define Vselect_active_regions \
-    globals.f_Vselect_active_regions
-#define Vselect_safe_coding_system_function \
-    globals.f_Vselect_safe_coding_system_function
-#define Vselection_coding_system \
-    globals.f_Vselection_coding_system
-#define Vselection_converter_alist \
-    globals.f_Vselection_converter_alist
-#define Vset_auto_coding_function \
-    globals.f_Vset_auto_coding_function
-#define Vshared_game_score_directory \
-    globals.f_Vshared_game_score_directory
-#define Vshell_file_name \
-    globals.f_Vshell_file_name
-#define Vshow_help_function \
-    globals.f_Vshow_help_function
-#define Vshow_trailing_whitespace \
-    globals.f_Vshow_trailing_whitespace
-#define Vsignal_hook_function \
-    globals.f_Vsignal_hook_function
-#define Vsource_directory \
-    globals.f_Vsource_directory
-#define Vspecial_event_map \
-    globals.f_Vspecial_event_map
-#define Vstandard_display_table \
-    globals.f_Vstandard_display_table
-#define Vstandard_input \
-    globals.f_Vstandard_input
-#define Vstandard_output \
-    globals.f_Vstandard_output
-#define Vstandard_translation_table_for_decode \
-    globals.f_Vstandard_translation_table_for_decode
-#define Vstandard_translation_table_for_encode \
-    globals.f_Vstandard_translation_table_for_encode
-#define Vsuggest_key_bindings \
-    globals.f_Vsuggest_key_bindings
-#define Vsuspend_tty_functions \
-    globals.f_Vsuspend_tty_functions
-#define Vsystem_configuration \
-    globals.f_Vsystem_configuration
-#define Vsystem_configuration_options \
-    globals.f_Vsystem_configuration_options
-#define Vsystem_messages_locale \
-    globals.f_Vsystem_messages_locale
-#define Vsystem_name \
-    globals.f_Vsystem_name
-#define Vsystem_time_locale \
-    globals.f_Vsystem_time_locale
-#define Vsystem_type \
-    globals.f_Vsystem_type
-#define Vtemp_buffer_show_function \
-    globals.f_Vtemp_buffer_show_function
-#define Vtemporary_file_directory \
-    globals.f_Vtemporary_file_directory
-#define Vterminal_frame \
-    globals.f_Vterminal_frame
-#define Vtext_property_default_nonsticky \
-    globals.f_Vtext_property_default_nonsticky
-#define Vthis_command \
-    globals.f_Vthis_command
-#define Vthis_command_keys_shift_translated \
-    globals.f_Vthis_command_keys_shift_translated
-#define Vthis_original_command \
-    globals.f_Vthis_original_command
-#define Vthrow_on_input \
-    globals.f_Vthrow_on_input
-#define Vtimer_idle_list \
-    globals.f_Vtimer_idle_list
-#define Vtimer_list \
-    globals.f_Vtimer_list
-#define Vtool_bar_border \
-    globals.f_Vtool_bar_border
-#define Vtool_bar_button_margin \
-    globals.f_Vtool_bar_button_margin
-#define Vtool_bar_mode \
-    globals.f_Vtool_bar_mode
-#define Vtool_bar_separator_image_expression \
-    globals.f_Vtool_bar_separator_image_expression
-#define Vtool_bar_style \
-    globals.f_Vtool_bar_style
-#define Vtop_level \
-    globals.f_Vtop_level
-#define Vtransient_mark_mode \
-    globals.f_Vtransient_mark_mode
-#define Vtranslation_hash_table_vector \
-    globals.f_Vtranslation_hash_table_vector
-#define Vtranslation_table_for_input \
-    globals.f_Vtranslation_table_for_input
-#define Vtranslation_table_vector \
-    globals.f_Vtranslation_table_vector
-#define Vtruncate_partial_width_windows \
-    globals.f_Vtruncate_partial_width_windows
-#define Vtty_defined_color_alist \
-    globals.f_Vtty_defined_color_alist
-#define Vtty_erase_char \
-    globals.f_Vtty_erase_char
-#define Vundo_outer_limit \
-    globals.f_Vundo_outer_limit
-#define Vundo_outer_limit_function \
-    globals.f_Vundo_outer_limit_function
-#define Vunicode_category_table \
-    globals.f_Vunicode_category_table
-#define Vunread_command_events \
-    globals.f_Vunread_command_events
-#define Vunread_input_method_events \
-    globals.f_Vunread_input_method_events
-#define Vunread_post_input_method_events \
-    globals.f_Vunread_post_input_method_events
-#define Vuse_default_ascent \
-    globals.f_Vuse_default_ascent
-#define Vuser_full_name \
-    globals.f_Vuser_full_name
-#define Vuser_init_file \
-    globals.f_Vuser_init_file
-#define Vuser_login_name \
-    globals.f_Vuser_login_name
-#define Vuser_real_login_name \
-    globals.f_Vuser_real_login_name
-#define Vvalues \
-    globals.f_Vvalues
-#define Vvertical_centering_font_regexp \
-    globals.f_Vvertical_centering_font_regexp
-#define Vvoid_text_area_pointer \
-    globals.f_Vvoid_text_area_pointer
-#define Vw32_alt_is_meta \
-    globals.f_Vw32_alt_is_meta
-#define Vw32_apps_modifier \
-    globals.f_Vw32_apps_modifier
-#define Vw32_bdf_filename_alist \
-    globals.f_Vw32_bdf_filename_alist
-#define Vw32_capslock_is_shiftlock \
-    globals.f_Vw32_capslock_is_shiftlock
-#define Vw32_charset_info_alist \
-    globals.f_Vw32_charset_info_alist
-#define Vw32_color_map \
-    globals.f_Vw32_color_map
-#define Vw32_downcase_file_names \
-    globals.f_Vw32_downcase_file_names
-#define Vw32_enable_caps_lock \
-    globals.f_Vw32_enable_caps_lock
-#define Vw32_enable_num_lock \
-    globals.f_Vw32_enable_num_lock
-#define Vw32_enable_palette \
-    globals.f_Vw32_enable_palette
-#define Vw32_generate_fake_inodes \
-    globals.f_Vw32_generate_fake_inodes
-#define Vw32_get_true_file_attributes \
-    globals.f_Vw32_get_true_file_attributes
-#define Vw32_grab_focus_on_raise \
-    globals.f_Vw32_grab_focus_on_raise
-#define Vw32_lwindow_modifier \
-    globals.f_Vw32_lwindow_modifier
-#define Vw32_pass_alt_to_system \
-    globals.f_Vw32_pass_alt_to_system
-#define Vw32_pass_lwindow_to_system \
-    globals.f_Vw32_pass_lwindow_to_system
-#define Vw32_pass_rwindow_to_system \
-    globals.f_Vw32_pass_rwindow_to_system
-#define Vw32_phantom_key_code \
-    globals.f_Vw32_phantom_key_code
-#define Vw32_quote_process_args \
-    globals.f_Vw32_quote_process_args
-#define Vw32_recognize_altgr \
-    globals.f_Vw32_recognize_altgr
-#define Vw32_rwindow_modifier \
-    globals.f_Vw32_rwindow_modifier
-#define Vw32_scroll_lock_modifier \
-    globals.f_Vw32_scroll_lock_modifier
-#define Vw32_start_process_inherit_error_mode \
-    globals.f_Vw32_start_process_inherit_error_mode
-#define Vw32_start_process_share_console \
-    globals.f_Vw32_start_process_share_console
-#define Vw32_start_process_show_window \
-    globals.f_Vw32_start_process_show_window
-#define Vw32_swap_mouse_buttons \
-    globals.f_Vw32_swap_mouse_buttons
-#define Vwhere_is_preferred_modifier \
-    globals.f_Vwhere_is_preferred_modifier
-#define Vwindow_configuration_change_hook \
-    globals.f_Vwindow_configuration_change_hook
-#define Vwindow_point_insertion_type \
-    globals.f_Vwindow_point_insertion_type
-#define Vwindow_scroll_functions \
-    globals.f_Vwindow_scroll_functions
-#define Vwindow_size_change_functions \
-    globals.f_Vwindow_size_change_functions
-#define Vwindow_system_version \
-    globals.f_Vwindow_system_version
-#define Vwindow_text_change_functions \
-    globals.f_Vwindow_text_change_functions
-#define Vword_combining_categories \
-    globals.f_Vword_combining_categories
-#define Vword_separating_categories \
-    globals.f_Vword_separating_categories
-#define Vwrap_prefix \
-    globals.f_Vwrap_prefix
-#define Vwrite_region_annotate_functions \
-    globals.f_Vwrite_region_annotate_functions
-#define Vwrite_region_annotations_so_far \
-    globals.f_Vwrite_region_annotations_so_far
-#define Vwrite_region_post_annotation_function \
-    globals.f_Vwrite_region_post_annotation_function
-#define Vx_alt_keysym \
-    globals.f_Vx_alt_keysym
-#define Vx_bitmap_file_path \
-    globals.f_Vx_bitmap_file_path
-#define Vx_cursor_fore_pixel \
-    globals.f_Vx_cursor_fore_pixel
-#define Vx_hourglass_pointer_shape \
-    globals.f_Vx_hourglass_pointer_shape
-#define Vx_hyper_keysym \
-    globals.f_Vx_hyper_keysym
-#define Vx_keysym_table \
-    globals.f_Vx_keysym_table
-#define Vx_lost_selection_functions \
-    globals.f_Vx_lost_selection_functions
-#define Vx_max_tooltip_size \
-    globals.f_Vx_max_tooltip_size
-#define Vx_meta_keysym \
-    globals.f_Vx_meta_keysym
-#define Vx_mode_pointer_shape \
-    globals.f_Vx_mode_pointer_shape
-#define Vx_no_window_manager \
-    globals.f_Vx_no_window_manager
-#define Vx_nontext_pointer_shape \
-    globals.f_Vx_nontext_pointer_shape
-#define Vx_pixel_size_width_font_regexp \
-    globals.f_Vx_pixel_size_width_font_regexp
-#define Vx_pointer_shape \
-    globals.f_Vx_pointer_shape
-#define Vx_resource_class \
-    globals.f_Vx_resource_class
-#define Vx_resource_name \
-    globals.f_Vx_resource_name
-#define Vx_sensitive_text_pointer_shape \
-    globals.f_Vx_sensitive_text_pointer_shape
-#define Vx_sent_selection_functions \
-    globals.f_Vx_sent_selection_functions
-#define Vx_session_id \
-    globals.f_Vx_session_id
-#define Vx_session_previous_id \
-    globals.f_Vx_session_previous_id
-#define Vx_super_keysym \
-    globals.f_Vx_super_keysym
-#define Vx_toolkit_scroll_bars \
-    globals.f_Vx_toolkit_scroll_bars
-#define Vx_window_horizontal_drag_shape \
-    globals.f_Vx_window_horizontal_drag_shape
-#define Vxft_settings \
-    globals.f_Vxft_settings
-#define auto_raise_tool_bar_buttons_p \
-    globals.f_auto_raise_tool_bar_buttons_p
-#define auto_save_interval \
-    globals.f_auto_save_interval
-#define auto_window_vscroll_p \
-    globals.f_auto_window_vscroll_p
-#define automatic_hscrolling_p \
-    globals.f_automatic_hscrolling_p
-#define baud_rate \
-    globals.f_baud_rate
-#define byte_debug_flag \
-    globals.f_byte_debug_flag
-#define byte_metering_on \
-    globals.f_byte_metering_on
-#define cannot_suspend \
-    globals.f_cannot_suspend
-#define check_markers_debug_flag \
-    globals.f_check_markers_debug_flag
-#define coding_system_require_warning \
-    globals.f_coding_system_require_warning
-#define completion_ignore_case \
-    globals.f_completion_ignore_case
-#define cons_cells_consed \
-    globals.f_cons_cells_consed
-#define cross_disabled_images \
-    globals.f_cross_disabled_images
-#define cursor_in_echo_area \
-    globals.f_cursor_in_echo_area
-#define debug_end_pos \
-    globals.f_debug_end_pos
-#define debug_on_next_call \
-    globals.f_debug_on_next_call
-#define debug_on_quit \
-    globals.f_debug_on_quit
-#define debugger_may_continue \
-    globals.f_debugger_may_continue
-#define delete_by_moving_to_trash \
-    globals.f_delete_by_moving_to_trash
-#define delete_exited_processes \
-    globals.f_delete_exited_processes
-#define display_hourglass_p \
-    globals.f_display_hourglass_p
-#define do_mouse_tracking \
-    globals.f_do_mouse_tracking
-#define dos_codepage \
-    globals.f_dos_codepage
-#define dos_country_code \
-    globals.f_dos_country_code
-#define dos_decimal_point \
-    globals.f_dos_decimal_point
-#define dos_hyper_key \
-    globals.f_dos_hyper_key
-#define dos_keyboard_layout \
-    globals.f_dos_keyboard_layout
-#define dos_keypad_mode \
-    globals.f_dos_keypad_mode
-#define dos_super_key \
-    globals.f_dos_super_key
-#define dos_timezone_offset \
-    globals.f_dos_timezone_offset
-#define double_click_fuzz \
-    globals.f_double_click_fuzz
-#define emacs_scroll_step \
-    globals.f_emacs_scroll_step
-#define enable_recursive_minibuffers \
-    globals.f_enable_recursive_minibuffers
-#define eol_mnemonic_dos \
-    globals.f_eol_mnemonic_dos
-#define eol_mnemonic_mac \
-    globals.f_eol_mnemonic_mac
-#define eol_mnemonic_undecided \
-    globals.f_eol_mnemonic_undecided
-#define eol_mnemonic_unix \
-    globals.f_eol_mnemonic_unix
-#define executing_kbd_macro_index \
-    globals.f_executing_kbd_macro_index
-#define extra_keyboard_modifiers \
-    globals.f_extra_keyboard_modifiers
-#define floats_consed \
-    globals.f_floats_consed
-#define focus_follows_mouse \
-    globals.f_focus_follows_mouse
-#define force_load_messages \
-    globals.f_force_load_messages
-#define garbage_collection_messages \
-    globals.f_garbage_collection_messages
-#define gc_cons_threshold \
-    globals.f_gc_cons_threshold
-#define gcs_done \
-    globals.f_gcs_done
-#define highlight_nonselected_windows \
-    globals.f_highlight_nonselected_windows
-#define history_delete_duplicates \
-    globals.f_history_delete_duplicates
-#define hscroll_margin \
-    globals.f_hscroll_margin
-#define indent_tabs_mode \
-    globals.f_indent_tabs_mode
-#define inherit_process_coding_system \
-    globals.f_inherit_process_coding_system
-#define inhibit_eol_conversion \
-    globals.f_inhibit_eol_conversion
-#define inhibit_eval_during_redisplay \
-    globals.f_inhibit_eval_during_redisplay
-#define inhibit_free_realized_faces \
-    globals.f_inhibit_free_realized_faces
-#define inhibit_iso_escape_detection \
-    globals.f_inhibit_iso_escape_detection
-#define inhibit_load_charset_map \
-    globals.f_inhibit_load_charset_map
-#define inhibit_local_menu_bar_menus \
-    globals.f_inhibit_local_menu_bar_menus
-#define inhibit_menubar_update \
-    globals.f_inhibit_menubar_update
-#define inhibit_modification_hooks \
-    globals.f_inhibit_modification_hooks
-#define inhibit_null_byte_detection \
-    globals.f_inhibit_null_byte_detection
-#define inhibit_try_cursor_movement \
-    globals.f_inhibit_try_cursor_movement
-#define inhibit_try_window_id \
-    globals.f_inhibit_try_window_id
-#define inhibit_try_window_reusing \
-    globals.f_inhibit_try_window_reusing
-#define inhibit_x_resources \
-    globals.f_inhibit_x_resources
-#define intervals_consed \
-    globals.f_intervals_consed
-#define inverse_video \
-    globals.f_inverse_video
-#define last_command_event \
-    globals.f_last_command_event
-#define last_input_event \
-    globals.f_last_input_event
-#define last_nonmenu_event \
-    globals.f_last_nonmenu_event
-#define line_number_display_limit_width \
-    globals.f_line_number_display_limit_width
-#define load_convert_to_unibyte \
-    globals.f_load_convert_to_unibyte
-#define load_dangerous_libraries \
-    globals.f_load_dangerous_libraries
-#define load_force_doc_strings \
-    globals.f_load_force_doc_strings
-#define load_in_progress \
-    globals.f_load_in_progress
-#define make_cursor_line_fully_visible_p \
-    globals.f_make_cursor_line_fully_visible_p
-#define max_lisp_eval_depth \
-    globals.f_max_lisp_eval_depth
-#define max_specpdl_size \
-    globals.f_max_specpdl_size
-#define menu_prompt_more_char \
-    globals.f_menu_prompt_more_char
-#define menu_prompting \
-    globals.f_menu_prompting
-#define message_truncate_lines \
-    globals.f_message_truncate_lines
-#define meta_prefix_char \
-    globals.f_meta_prefix_char
-#define minibuffer_allow_text_properties \
-    globals.f_minibuffer_allow_text_properties
-#define minibuffer_auto_raise \
-    globals.f_minibuffer_auto_raise
-#define misc_objects_consed \
-    globals.f_misc_objects_consed
-#define mode_line_in_non_selected_windows \
-    globals.f_mode_line_in_non_selected_windows
-#define mode_line_inverse_video \
-    globals.f_mode_line_inverse_video
-#define multibyte_syntax_as_symbol \
-    globals.f_multibyte_syntax_as_symbol
-#define multiple_frames \
-    globals.f_multiple_frames
-#define next_screen_context_lines \
-    globals.f_next_screen_context_lines
-#define no_redraw_on_reenter \
-    globals.f_no_redraw_on_reenter
-#define noninteractive1 \
-    globals.f_noninteractive1
-#define num_input_keys \
-    globals.f_num_input_keys
-#define num_nonmacro_input_events \
-    globals.f_num_nonmacro_input_events
-#define open_paren_in_column_0_is_defun_start \
-    globals.f_open_paren_in_column_0_is_defun_start
-#define overline_margin \
-    globals.f_overline_margin
-#define parse_sexp_ignore_comments \
-    globals.f_parse_sexp_ignore_comments
-#define parse_sexp_lookup_properties \
-    globals.f_parse_sexp_lookup_properties
-#define polling_period \
-    globals.f_polling_period
-#define print_escape_multibyte \
-    globals.f_print_escape_multibyte
-#define print_escape_newlines \
-    globals.f_print_escape_newlines
-#define print_escape_nonascii \
-    globals.f_print_escape_nonascii
-#define print_quoted \
-    globals.f_print_quoted
-#define pure_bytes_used \
-    globals.f_pure_bytes_used
-#define read_buffer_completion_ignore_case \
-    globals.f_read_buffer_completion_ignore_case
-#define redisplay_dont_pause \
-    globals.f_redisplay_dont_pause
-#define scroll_conservatively \
-    globals.f_scroll_conservatively
-#define scroll_margin \
-    globals.f_scroll_margin
-#define string_chars_consed \
-    globals.f_string_chars_consed
-#define strings_consed \
-    globals.f_strings_consed
-#define symbols_consed \
-    globals.f_symbols_consed
-#define system_uses_terminfo \
-    globals.f_system_uses_terminfo
-#define tool_bar_button_relief \
-    globals.f_tool_bar_button_relief
-#define tool_bar_max_label_size \
-    globals.f_tool_bar_max_label_size
-#define underline_minimum_offset \
-    globals.f_underline_minimum_offset
-#define undo_inhibit_record_point \
-    globals.f_undo_inhibit_record_point
-#define undo_limit \
-    globals.f_undo_limit
-#define undo_strong_limit \
-    globals.f_undo_strong_limit
-#define unibyte_display_via_language_environment \
-    globals.f_unibyte_display_via_language_environment
-#define unread_command_char \
-    globals.f_unread_command_char
-#define use_dialog_box \
-    globals.f_use_dialog_box
-#define use_file_dialog \
-    globals.f_use_file_dialog
-#define use_system_font \
-    globals.f_use_system_font
-#define vector_cells_consed \
-    globals.f_vector_cells_consed
-#define visible_bell \
-    globals.f_visible_bell
-#define visible_cursor \
-    globals.f_visible_cursor
-#define w32_ansi_code_page \
-    globals.f_w32_ansi_code_page
-#define w32_enable_synthesized_fonts \
-    globals.f_w32_enable_synthesized_fonts
-#define w32_mouse_button_tolerance \
-    globals.f_w32_mouse_button_tolerance
-#define w32_mouse_move_interval \
-    globals.f_w32_mouse_move_interval
-#define w32_num_mouse_buttons \
-    globals.f_w32_num_mouse_buttons
-#define w32_pass_extra_mouse_buttons_to_system \
-    globals.f_w32_pass_extra_mouse_buttons_to_system
-#define w32_pass_multimedia_buttons_to_system \
-    globals.f_w32_pass_multimedia_buttons_to_system
-#define w32_pipe_read_delay \
-    globals.f_w32_pipe_read_delay
-#define w32_quit_key \
-    globals.f_w32_quit_key
-#define w32_strict_fontnames \
-    globals.f_w32_strict_fontnames
-#define w32_strict_painting \
-    globals.f_w32_strict_painting
-#define w32_use_full_screen_buffer \
-    globals.f_w32_use_full_screen_buffer
-#define w32_use_visible_system_caret \
-    globals.f_w32_use_visible_system_caret
-#define window_min_height \
-    globals.f_window_min_height
-#define window_min_width \
-    globals.f_window_min_width
-#define words_include_escapes \
-    globals.f_words_include_escapes
-#define write_region_inhibit_fsync \
-    globals.f_write_region_inhibit_fsync
-#define x_gtk_file_dialog_help_text \
-    globals.f_x_gtk_file_dialog_help_text
-#define x_gtk_show_hidden_files \
-    globals.f_x_gtk_show_hidden_files
-#define x_gtk_use_old_file_dialog \
-    globals.f_x_gtk_use_old_file_dialog
-#define x_gtk_use_system_tooltips \
-    globals.f_x_gtk_use_system_tooltips
-#define x_gtk_whole_detached_tool_bar \
-    globals.f_x_gtk_whole_detached_tool_bar
-#define x_mouse_click_focus_ignore_position \
-    globals.f_x_mouse_click_focus_ignore_position
-#define x_selection_timeout \
-    globals.f_x_selection_timeout
-#define x_stretch_cursor_p \
-    globals.f_x_stretch_cursor_p
-#define x_underline_at_descent_line \
-    globals.f_x_underline_at_descent_line
-#define x_use_underline_position_properties \
-    globals.f_x_use_underline_position_properties
-#define ns_input_file \
-    globals.f_ns_input_file
-#define ns_input_font \
-    globals.f_ns_input_font
-#define ns_input_fontsize \
-    globals.f_ns_input_fontsize
-#define ns_input_line \
-    globals.f_ns_input_line
-#define ns_input_color \
-    globals.f_ns_input_color
-#define ns_input_text \
-    globals.f_ns_input_text
-#define ns_working_text \
-    globals.f_ns_working_text
-#define ns_input_spi_name \
-    globals.f_ns_input_spi_name
-#define ns_input_spi_arg \
-    globals.f_ns_input_spi_arg
-#define ns_alternate_modifier \
-    globals.f_ns_alternate_modifier
-#define ns_right_alternate_modifier \
-    globals.f_ns_right_alternate_modifier
-#define ns_command_modifier \
-    globals.f_ns_command_modifier
-#define ns_right_command_modifier \
-    globals.f_ns_right_command_modifier
-#define ns_control_modifier \
-    globals.f_ns_control_modifier
-#define ns_right_control_modifier \
-    globals.f_ns_right_control_modifier
-#define ns_function_modifier \
-    globals.f_ns_function_modifier
-#define ns_antialias_text \
-    globals.f_ns_antialias_text
-#define ns_confirm_quit \
-    globals.f_ns_confirm_quit
-#define Vns_icon_type_alist \
-    globals.f_Vns_icon_type_alist
-#define Vns_version_string \
-    globals.f_Vns_version_string
-#define Vns_sent_selection_hooks \
-    globals.f_Vns_sent_selection_hooks
-#define Vns_lost_selection_hooks \
-    globals.f_Vns_lost_selection_hooks
-#define Vselection_alist \
-    globals.f_Vselection_alist
-#define Vns_reg_to_script \
-    globals.f_Vns_reg_to_script

=== modified file 'src/xselect.c'
--- src/xselect.c	2011-01-30 22:17:44 +0000
+++ src/xselect.c	2011-02-01 22:01:16 +0000
@@ -126,6 +126,20 @@
 /* Defined in keyboard.c.  */
 extern unsigned long last_event_timestamp;
 
+/* This is an association list whose elements are of the form
+     ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
+   SELECTION-NAME is a lisp symbol, whose name is the name of an X Atom.
+   SELECTION-VALUE is the value that emacs owns for that selection.
+     It may be any kind of Lisp object.
+   SELECTION-TIMESTAMP is the time at which emacs began owning this selection,
+     as a cons of two 16-bit numbers (making a 32 bit time.)
+   FRAME is the frame for which we made the selection.
+   If there is an entry in this alist, then it can be assumed that Emacs owns
+    that selection.
+   The only (eq) parts of this list that are visible from Lisp are the
+    selection-values.  */
+static Lisp_Object Vselection_alist;
+
 
 \f
 /* Define a queue to save up SELECTION_REQUEST_EVENT events for later




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 18:26         ` Tom Tromey
                             ` (2 preceding siblings ...)
  2011-02-01 21:59           ` Tom Tromey
@ 2011-02-01 22:21           ` Stefan Monnier
  2011-02-08 16:38             ` Tom Tromey
  2011-02-11 21:48             ` Tom Tromey
  3 siblings, 2 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-01 22:21 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> I wrote an evil sed script to generate globals.h from the .c files.
> I used sed and not anything nicer since that is what the GNU coding
> standards specify.

Using sed means that it can't be used for the Windows build, i.e. it
would then have to be handled like `configure' and a few other generated
files which are kept in Bzr.

It's not the end of the world, but it's not ideal.  This said, since
globals.h is already under Bzr, it's no worse than what we already have,
so feel free to install a patch that adds a Makefile entry to regenerate
globals.h and install the corresponding newly generated globals.h.

> Maybe Andreas' idea of reusing the doc extractor would be better.
> I have not looked at that.

It might be a better solution, indeed, which should work for Windows and
MS-DOS as well.

Note that this auto-generation of globals.h might trigger some related
neurons and bring up related desires.  E.g. auto-generate the `defsubr'
calls and all the intern_c_string+staticpro for Q<foo> vars ;-)


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 21:59           ` Tom Tromey
@ 2011-02-02  0:44             ` Paul Eggert
  2011-02-02  3:49             ` Stefan Monnier
  1 sibling, 0 replies; 123+ messages in thread
From: Paul Eggert @ 2011-02-02  0:44 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

On 02/01/11 13:59, Tom Tromey wrote:
> +gl-stamp: $(ALL_SOURCES)
> +	@rm -f gl-tmp
> +	echo "/* This file was auto-generated */" > gl-tmp
> +	echo "/* DO NOT EDIT */" >> gl-tmp
> +	echo "struct emacs_globals {" >> gl-tmp
> +	...

It'd be better to package that shell-script code into
a shell script named (say) globals.sh.  Then the make
rule could be much simpler:

$(srcdir)/gl-stamp: $(ALL_SOURCES) $(srcdir)/globals.sh
	rm -f gl-stamp.tmp
	$(srcdir)/globals.sh $(ALL_SOURCES) >gl-stamp.tmp
	$(srcdir)/../move-if-change gl-stamp.tmp $@

and there would be no need for the files globals-1.sed and
globals-2.sed, as their contents could be put into strings in
gl-stamp.sh.

The rule for "make clean" should also remove *.tmp, to clean
any leftover temporaries.

> +ALL_SOURCES = alloc.c atimer.c bidi.c buffer.c bytecode.c callint.c \

These files all need $(srcdir)/ prepended to their names.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 12:09         ` Stephen J. Turnbull
@ 2011-02-02  2:41           ` Richard Stallman
  0 siblings, 0 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-02  2:41 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: tromey, monnier, emacs-devel

     > > I don't think preemptive thread switching is a sensible goal.  It is
     > > so much trouble that it isn't worth doing even in the long term.
     > 
     > I don't think we will get to choose.

    FWIW, Guido Van Rossum is about +0.5 in Richard's camp.

I am not saying anything against parallel programming as a general
issue.  But the code needs to be written for that.  The code in Emacs
wasn't.  I devised the mechanism of the QUIT macro as a simple way to
avoid the need to confront lots of issues of the sort, "What happens
if Lisp code gets to run at some point in the middle of this?"  I made
only Eval call GC as a simple way to avoid lots of issues of the sort,
"What happens if it GCs right HERE?"

To make Emacs safe for parallelism, those issues would need to be
confronted.

I won't say it is impossible.  I do say it is a very large job,
which dwarfs that of handling variable bindings.  It is also the sort
of job which is error prone.


-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:44           ` Tom Tromey
@ 2011-02-02  2:42             ` Richard Stallman
  0 siblings, 0 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-02  2:42 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

    RMS> This seems to give the right semantics, but having a pointer in
    RMS> each thread for each DEFVAR_LISP variable makes threads rather
    RMS> heavy.  How many such variables are there now?  I'd expect
    RMS> thousands.

    562.

Fewer than I thought.  I suppose 2k is not a big deal compared with
a real thread that executes concurrently.  So I withdraw that criticism.

However, the job of rewriting the code to work concurrently could be
enormous.


-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:51           ` Tom Tromey
@ 2011-02-02  2:42             ` Richard Stallman
  2011-02-02  4:16               ` Tom Tromey
  2011-02-11 21:51               ` Tom Tromey
  0 siblings, 2 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-02  2:42 UTC (permalink / raw)
  To: Tom Tromey; +Cc: dan.colascione, emacs-devel

    One thing worth noting is that if the concurrency branch is a huge
    failure, it is simple to back out at least the buffer change.

That is true.

      And, since there is no performance penalty
    possible until concurrency is actually merged, I think the risks
    associated with moving forward are rather low.

If the new macros expand into the existing code, they won't cause
a slowdown.  They only make the code less natural.

So why merge the macro calls into the trunk?
You could put them in a branch.  If you ever get preemptive threads
working such that we want to install it, we could install that change then.

    The point of this patch series is to make it simpler to work on the
    other problems on a branch.

That goal seems unobjectionable, but why do you need to change these
calls in the trunk to be able to work on your branch?


-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 20:04           ` Patch for fields of `struct buffer' Daniel Colascione
@ 2011-02-02  2:43             ` Richard Stallman
  0 siblings, 0 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-02  2:43 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: tromey, emacs-devel

    If you link against GNU Pth, the threading primitives become practically
    free aside from the few hundred pointers referring to global Lisp
    variables. I doubt the aggregate impact of following those indirections
    would have much of an impact over all the pointer-chasing Lisp code
    already performs. (How many cons cell are used for the output of
    parse-partial-sexp?)

Emacs is sometimes rather slow already on this machine.

    One approach successfully applied to other systems that make assumptions
    about a lack of preemptive concurrency is to put large locks around the
    sensitive portions and gradually split these locks up over time as the
    code is improved. Subrs not specially marked as concurrency-safe could
    be made to automatically take such a lock on entry,

I don't know how well that would work out in practice in Emacs,
but someone could give it a try.

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 21:59           ` Tom Tromey
  2011-02-02  0:44             ` Paul Eggert
@ 2011-02-02  3:49             ` Stefan Monnier
  2011-02-02 16:26               ` Tom Tromey
  2011-02-08 15:07               ` Tom Tromey
  1 sibling, 2 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-02  3:49 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> I think this will break the nextstep build, since there Vselection_alist
> was erroneously moved to globals.h.  Only DEFVARs have to be in
> globals.h, other globals do not.  I reverted a similar change to
> xselect.c, because I was able to test that one.

I much prefer an untested fix than no fix at all.
Especially when the untested fix can be based on the code that was there
before your global.h change, i.e. pretty likely to work even if you
can't test it.

> Let me know what you think.  I'm not excessively happy about the
> ALL_SOURCES bit in src/Makefile.in.

The ALL_SOURCES is indeed bad.  We already have equivalent data, so
please adjust your patch to try and use it (a good starting point is to
look at the dependencies of the make-docfile rule).


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02  2:42             ` Richard Stallman
@ 2011-02-02  4:16               ` Tom Tromey
  2011-02-02  5:04                 ` Stefan Monnier
  2011-02-11 21:51               ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-02  4:16 UTC (permalink / raw)
  To: rms; +Cc: dan.colascione, emacs-devel

RMS> So why merge the macro calls into the trunk?
RMS> You could put them in a branch.  If you ever get preemptive threads
RMS> working such that we want to install it, we could install that change then.
[...]
RMS> That goal seems unobjectionable, but why do you need to change these
RMS> calls in the trunk to be able to work on your branch?

We did have a branch, but it quickly got stale.  Because the needed
infrastructure changes are pervasive, it was very hard to do merges --
there were a lot of conflicts.

This is not a problem in itself, since we could simply not do merges.
But, then that also would greatly reduce the prospects for ever merging
back.  Putting these changes on the trunk makes it possible to keep the
branch relatively up-to-date, making it simpler to merge into trunk when
the time comes.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02  4:16               ` Tom Tromey
@ 2011-02-02  5:04                 ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-02  5:04 UTC (permalink / raw)
  To: Tom Tromey; +Cc: dan.colascione, rms, emacs-devel

> This is not a problem in itself, since we could simply not do merges.
> But, then that also would greatly reduce the prospects for ever merging
> back.  Putting these changes on the trunk makes it possible to keep the
> branch relatively up-to-date, making it simpler to merge into trunk when
> the time comes.

Exactly.  And since this can make the main code worse, it's good to make
up for it by providing scripts that automate some tasks, e.g. generate
the var declarations automatically from the DEFVARs.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02  3:49             ` Stefan Monnier
@ 2011-02-02 16:26               ` Tom Tromey
  2011-02-02 16:37                 ` Stefan Monnier
  2011-02-08 15:07               ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-02 16:26 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan> I much prefer an untested fix than no fix at all.
Stefan> Especially when the untested fix can be based on the code that was there
Stefan> before your global.h change, i.e. pretty likely to work even if you
Stefan> can't test it.

Ok.

Tom> Let me know what you think.  I'm not excessively happy about the
Tom> ALL_SOURCES bit in src/Makefile.in.

Stefan> The ALL_SOURCES is indeed bad.  We already have equivalent data, so
Stefan> please adjust your patch to try and use it (a good starting point is to
Stefan> look at the dependencies of the make-docfile rule).

I did look at this, but I think it won't work.

The rule that runs make-docfile depends on the object files.  This won't
work here, since we need to create globals.h before doing any
compilation.

Also, make-docfile.c takes the .o file name and turns it into a .c or
.m, depending on what it finds in the source tree.  We need to do this
transformation in the Makefile to make the dependencies correct.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02 16:26               ` Tom Tromey
@ 2011-02-02 16:37                 ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-02 16:37 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> The rule that runs make-docfile depends on the object files.  This won't
> work here, since we need to create globals.h before doing any
> compilation.

> Also, make-docfile.c takes the .o file name and turns it into a .c or
> .m, depending on what it finds in the source tree.  We need to do this
> transformation in the Makefile to make the dependencies correct.

Then maybe the right fix is to change the current Makefile to use *.m
and *.c names and turn then into *.o where/when needed.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-29 13:42           ` Eli Zaretskii
@ 2011-02-02 18:17             ` Juanma Barranquero
  2011-02-02 19:51               ` Eli Zaretskii
  0 siblings, 1 reply; 123+ messages in thread
From: Juanma Barranquero @ 2011-02-02 18:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On Sat, Jan 29, 2011 at 14:42, Eli Zaretskii <eliz@gnu.org> wrote:

> Thanks.  Please try again.

I get this warning while building DOC:

"./oo-spd/i386/make-docfile" -o DOC -d ../src dosfns.o msdos.o xterm.o
xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o fontset.o
menu.o w32.o w32console.o w32fns.o w32heap.o w32inevt.o w32menu.o
w32proc.o w32reg.o w32select.o w32term.o w32xfns.o font.o w32font.o
w32uniscribe.o dispnew.o frame.o scroll.o xdisp.o window.o bidi.o
charset.o coding.o category.o ccl.o character.o chartab.o cm.o term.o
terminal.o xfaces.o emacs.o keyboard.o macros.o keymap.o sysdep.o
buffer.o filelock.o insdel.o marker.o minibuf.o fileio.o dired.o
filemode.o cmds.o casetab.o casefiddle.o indent.o search.o regex.o
undo.o alloc.o data.o doc.o editfns.o callint.o eval.o floatfns.o
fns.o print.o lread.o syntax.o bytecode.o process.o callproc.o
unexw32.o region-cache.o sound.o atimer.o doprnt.o strftime.o
intervals.o textprop.o composite.o md5.o
strftime.c: No such file or directory

because on lib-src/makefile.w32-in, strftime.o is in $(obj), but the
file strftime.o is not in src/oo*/i386/, but in lib/oo*/i386/.

    Juanma



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02 18:17             ` Juanma Barranquero
@ 2011-02-02 19:51               ` Eli Zaretskii
  0 siblings, 0 replies; 123+ messages in thread
From: Eli Zaretskii @ 2011-02-02 19:51 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: emacs-devel

> From: Juanma Barranquero <lekktu@gmail.com>
> Date: Wed, 2 Feb 2011 19:17:47 +0100
> Cc: emacs-devel@gnu.org
> 
> I get this warning while building DOC:
> 
> "./oo-spd/i386/make-docfile" -o DOC -d ../src dosfns.o msdos.o xterm.o
> xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o fontset.o
> menu.o w32.o w32console.o w32fns.o w32heap.o w32inevt.o w32menu.o
> w32proc.o w32reg.o w32select.o w32term.o w32xfns.o font.o w32font.o
> w32uniscribe.o dispnew.o frame.o scroll.o xdisp.o window.o bidi.o
> charset.o coding.o category.o ccl.o character.o chartab.o cm.o term.o
> terminal.o xfaces.o emacs.o keyboard.o macros.o keymap.o sysdep.o
> buffer.o filelock.o insdel.o marker.o minibuf.o fileio.o dired.o
> filemode.o cmds.o casetab.o casefiddle.o indent.o search.o regex.o
> undo.o alloc.o data.o doc.o editfns.o callint.o eval.o floatfns.o
> fns.o print.o lread.o syntax.o bytecode.o process.o callproc.o
> unexw32.o region-cache.o sound.o atimer.o doprnt.o strftime.o
> intervals.o textprop.o composite.o md5.o
> strftime.c: No such file or directory
> 
> because on lib-src/makefile.w32-in, strftime.o is in $(obj), but the
> file strftime.o is not in src/oo*/i386/, but in lib/oo*/i386/.

Thanks.  I fixed this by removing strftime.o from the list, since it
does not (and cannot) have any Lisp doc strings.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 10:54             ` Daniel Colascione
@ 2011-02-07  2:34               ` Tom Tromey
  2011-02-07 19:48                 ` concurrency suggestions for Gnus (was: Patch for fields of `struct buffer') Ted Zlatanov
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-07  2:34 UTC (permalink / raw)
  To: Daniel Colascione; +Cc: emacs-devel, David De La Harpe Golden

>>>>> "Daniel" == Daniel Colascione <dan.colascione@gmail.com> writes:

Tom> Instead of explicit locks, just let any symbol function as a lock, and
Tom> have the locks hidden in the C code.

Daniel> While elegant, I'm afraid using symbols as locks would lead to a
Daniel> proliferation of locks of code, not data. Using a symbol as a big global
Daniel> lock is easier than using gensym to get per-object locks.

I don't really understand this.  I think it doesn't matter, though,
since after thinking about it some more, I think that it at least makes
sense to want to lock buffers.

Tom> (Or an extension of this idea, let
Tom> any Lisp object be a lock -- "Java style".)

Daniel> This approach has potential. I believe JVMs get away with this trick at
Daniel> a cost of a machine word per object --- that's a big addition to a
Daniel> simple cons cell, of which Emacs has quite a few.

Modern JVMs don't pay anywhere near this price.  JVM developers noticed
a long time ago that most object's locks are never acquired, and that
those that are acquired are usually uncontended, and optimized their
implementations accordingly.

If we went the "lock anything" route, I would suggest a weak hash table
for locks, instead of putting the lock into the object.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 15:43             ` Patch for fields of `struct buffer' Stefan Monnier
  2011-02-01 16:28               ` Helmut Eller
@ 2011-02-07  2:44               ` Tom Tromey
  2011-02-07  8:05                 ` Helmut Eller
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-07  2:44 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, David De La Harpe Golden

>>>>> "Stefan" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

Stefan> Erlang-style concurrency is nice and clean, but I'm not sure it'll
Stefan> integrate well with existing code which stomps over a global state all
Stefan> the time.  This doesn't mean it won't work.  If we can make it work
Stefan> something like "one agent per buffer" and turn `set-buffer' into a kind
Stefan> of message maybe we could get some good results, but it seems tricky.

I couldn't think of a way to make this work, at least not with
`set-buffer' as the primitive.

I think it could be done by having all other buffer-manipulating
primitives (e.g., `insert') work by message-passing to some other
thread.  This is basically like a buffer lock.

Stefan> Threads and locks don't look too good: too low-level.  If we go
Stefan> in that direction, then STM seems a lot more appealing.

I read up on STM and then spent some time thinking about it this
weekend.  I don't see how it could be implemented in Emacs without
extreme hairiness in the C code.  My thinking is along the lines of: a
transaction could conceivably touch any lisp object, including buffer
contents (I was thinking along the lines of: each call-interactively is
a transaction automatically).  So, any change anywhere would have to be
logged and then potentially rolled back if a transaction is aborted.

In particular, all heap modifications in the C code would need to be
intercepted... orders of magnitude uglier than my proposed `struct
buffer' patch.  (Though FWIW I have thought about this particular change
for other reasons -- you could introduce a software write barrier for
the GC this way :-)

Also I think heap reads would need to be intercepted and indirected to
make transactions not prematurely affect other threads.  So, this is
quite hard and inefficient.


I am interested in reasoned arguments, grounded in real Emacs code, to
the contrary for either STM or CSP.  Otherwise, sucky as it is, I think
the approach will be explicit locking.  I know I can make that one work
ok, or "ok enough".

After thinking about the Bordeaux threads model a bit more, I have come
to the conclusion that I would prefer something simpler.  E.g., if we
went "Java style" and only provided `with-lock-held' (and not separate
lock- and unlock- primitives), then we could eliminate a class of bugs.
Likewise, I think (and I know we already disagree here) that only having
recursive locks similarly eliminates a source of bugs.  I think these
issues are important because such bugs will show up to Emacs users in a
particular un-fun way.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 16:28               ` Helmut Eller
@ 2011-02-07  2:47                 ` Tom Tromey
  0 siblings, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-07  2:47 UTC (permalink / raw)
  To: Helmut Eller; +Cc: emacs-devel

>>>>> "Helmut" == Helmut Eller <eller.helmut@gmail.com> writes:

Helmut> Is there a way to evaluate the different approaches against each
Helmut> other?

I think only based on your experiences reading and writing Emacs Lisp
code, and to a somewhat lesser degree your experiences with other
threaded programs.

Helmut> What are the uses cases where concurrency should be used in the
Helmut> future?

My earlier target was gnus, but I think Lars has probably already
rewritten all the slow bits.  Surely making it fully async can't be far
behind :-)

Now I think my main interest is in making it possible for different
keyboards to run in parallel.  This would make it possible to, e.g.,
connect `emacsclient -t' to Emacs and do stuff while gnus or something
is blocking in another frame (initially for "blocking" meaning "waiting
for I/O").

Beyond that, I don't have anything specific.  Making the GC run in
parallel would be cool, and is something I have looked into, but it
isn't a lisp-level problem.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-07  2:44               ` Tom Tromey
@ 2011-02-07  8:05                 ` Helmut Eller
  2011-02-07 19:23                   ` Richard Stallman
  2011-02-08 16:26                   ` Tom Tromey
  0 siblings, 2 replies; 123+ messages in thread
From: Helmut Eller @ 2011-02-07  8:05 UTC (permalink / raw)
  To: emacs-devel

* Tom Tromey [2011-02-07 02:44] writes:

>>>>>> "Stefan" == Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
> Stefan> Erlang-style concurrency is nice and clean, but I'm not sure it'll
> Stefan> integrate well with existing code which stomps over a global state all
> Stefan> the time.  This doesn't mean it won't work.  If we can make it work
> Stefan> something like "one agent per buffer" and turn `set-buffer' into a kind
> Stefan> of message maybe we could get some good results, but it seems tricky.
>
> I couldn't think of a way to make this work, at least not with
> `set-buffer' as the primitive.

How does a thread get the buffer in the first place?  In an Erlang-style
model a thread either has to create the buffer or receive it as a
message from an other thread.  Message passing could do some magic to
pass ownership: the receiver is the new owner of the buffer and the
sender loses ownership.  set-buffer would then check that the current
thread is the owner.  As a refinement we could have something like
"read-capability" and "write-capability".  Capabilities are also passed
with message passing.  A thread that has write-capability can modify the
buffer as usual.  Threads with read-capability can read the buffer but
this kind of reading--especially buffer properties or buffer local
variables--needs to copy the value (sometimes) to avoid sharing state.

Does that sound too complicated?

> I think it could be done by having all other buffer-manipulating
> primitives (e.g., `insert') work by message-passing to some other
> thread.  This is basically like a buffer lock.

Well, no mutable objects could be shared, which is quite different from
a lock; especially the case when somebody forgets to use the lock.

> I am interested in reasoned arguments, grounded in real Emacs code, to
> the contrary for either STM or CSP.

With some hand-waving, the current way to deal with external processes
can be seen as form of CSP.  Otherwise I'd say current Emacs code
neither uses STM nor CSP nor locks, which makes it hard to meet your
request.

Helmut




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-07  8:05                 ` Helmut Eller
@ 2011-02-07 19:23                   ` Richard Stallman
  2011-02-08 16:30                     ` Tom Tromey
  2011-02-08 16:26                   ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Richard Stallman @ 2011-02-07 19:23 UTC (permalink / raw)
  To: Helmut Eller; +Cc: emacs-devel

    How does a thread get the buffer in the first place?  In an Erlang-style
    model a thread either has to create the buffer or receive it as a
    message from an other thread.

In Emacs, a program can find a buffer as the value of a global variable.
It can also call `get-buffer' with a string as argument to get its hands
on any buffer.  To remove these facilities would be such a big loss
that it is not worth considering.

It would be easy enough to stop one buffer from being current in more
than one thread.  Just make set-buffer do the interlocking.  That
would be an easy change, and it would block threads less often than
the above idea.

But even that could be too much blocking of threads.  If a thread
is sitting idle with a certain buffer current, that would block
all other threads from operating on it.  That would be a big problem.


-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* concurrency suggestions for Gnus (was: Patch for fields of `struct buffer')
  2011-02-07  2:34               ` Tom Tromey
@ 2011-02-07 19:48                 ` Ted Zlatanov
  2011-02-08  4:31                   ` concurrency suggestions for Gnus Miles Bader
  2011-02-10  8:17                   ` concurrency suggestions for Gnus Lars Ingebrigtsen
  0 siblings, 2 replies; 123+ messages in thread
From: Ted Zlatanov @ 2011-02-07 19:48 UTC (permalink / raw)
  To: emacs-devel

On Sun, 06 Feb 2011 19:34:51 -0700 Tom Tromey <tromey@redhat.com> wrote: 

Tom> If we went the "lock anything" route, I would suggest a weak hash table
Tom> for locks, instead of putting the lock into the object.

A bloom filter would guarantee no false negatives, which as you noted is
the vast majority of the cases, requires very little space per element
(about 16 bytes to ensure max 0.1% false positives), and runs in
constant time.  So maybe that's a better first-check data structure in
this particular case with the hash table as the authoritative check.

On Sun, 06 Feb 2011 19:47:51 -0700 Tom Tromey <tromey@redhat.com> wrote: 

Tom> My earlier target was gnus, but I think Lars has probably already
Tom> rewritten all the slow bits.  Surely making it fully async can't be far
Tom> behind :-)

Here are some Gnus ideas:

Rebuilding the thread tree in the summary buffer can probably be
parallelized.  For large summaries (over 5000 articles) it can be a long
wait.

The Gnus registry is a way to track messages by message ID.  It needs to
process completely independent lists of data in parallel (classic
map-reduce) all the time, but does it serially right now.  It can
probably add extra baggage to each list to help this tracking, but that
would make the registry less generic and more complicated.  So
parallelizing that search would be nice.

The spam.el library does many spam check/process funcalls.  This can be
slow when the spam processing backend uses an ELisp function and it's
annoyingly complicated when shell commands are used.

Splitting incoming mail can generally be parallelized since each message
is split independently of the others.  This is not true in some cases
but the majority should benefit.

The auth-source.el library could search multiple backends simultaneously
(this refers to a recent rewrite that's currently in a branch in the
Gnus Git repo).  This parallel search is not possible right now.

Ted




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: concurrency suggestions for Gnus
  2011-02-07 19:48                 ` concurrency suggestions for Gnus (was: Patch for fields of `struct buffer') Ted Zlatanov
@ 2011-02-08  4:31                   ` Miles Bader
  2011-02-08 12:55                     ` Andy Moreton
                                       ` (2 more replies)
  2011-02-10  8:17                   ` concurrency suggestions for Gnus Lars Ingebrigtsen
  1 sibling, 3 replies; 123+ messages in thread
From: Miles Bader @ 2011-02-08  4:31 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: emacs-devel

Ted Zlatanov <tzz@lifelogs.com> writes:
> Tom> If we went the "lock anything" route, I would suggest a weak hash table
> Tom> for locks, instead of putting the lock into the object.
>
> A bloom filter would guarantee no false negatives, which as you noted is
> the vast majority of the cases, requires very little space per element

A bloom filter...?!

http://www.graphics.cornell.edu/pubs/1995/SSZG95.html

-miles

-- 
Bigot, n. One who is obstinately and zealously attached to an opinion that
you do not entertain.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: concurrency suggestions for Gnus
  2011-02-08  4:31                   ` concurrency suggestions for Gnus Miles Bader
@ 2011-02-08 12:55                     ` Andy Moreton
  2011-02-08 12:55                     ` Justin Lilly
  2011-02-08 14:41                     ` bloom filters (was: concurrency suggestions for Gnus) Ted Zlatanov
  2 siblings, 0 replies; 123+ messages in thread
From: Andy Moreton @ 2011-02-08 12:55 UTC (permalink / raw)
  To: emacs-devel

On Tue 08 Feb 2011, Miles Bader wrote:

> Ted Zlatanov <tzz@lifelogs.com> writes:
>> Tom> If we went the "lock anything" route, I would suggest a weak hash table
>> Tom> for locks, instead of putting the lock into the object.
>>
>> A bloom filter would guarantee no false negatives, which as you noted is
>> the vast majority of the cases, requires very little space per element
>
> A bloom filter...?!
>
> http://www.graphics.cornell.edu/pubs/1995/SSZG95.html
>
> -miles

Not that sort of bloom :-)

    http://en.wikipedia.org/wiki/Bloom_filter

    AndyM




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: concurrency suggestions for Gnus
  2011-02-08  4:31                   ` concurrency suggestions for Gnus Miles Bader
  2011-02-08 12:55                     ` Andy Moreton
@ 2011-02-08 12:55                     ` Justin Lilly
  2011-02-08 14:41                     ` bloom filters (was: concurrency suggestions for Gnus) Ted Zlatanov
  2 siblings, 0 replies; 123+ messages in thread
From: Justin Lilly @ 2011-02-08 12:55 UTC (permalink / raw)
  To: Miles Bader; +Cc: Ted Zlatanov, emacs-devel

http://en.wikipedia.org/wiki/Bloom_filter

On Mon, Feb 7, 2011 at 11:31 PM, Miles Bader <miles@gnu.org> wrote:
> Ted Zlatanov <tzz@lifelogs.com> writes:
>> Tom> If we went the "lock anything" route, I would suggest a weak hash table
>> Tom> for locks, instead of putting the lock into the object.
>>
>> A bloom filter would guarantee no false negatives, which as you noted is
>> the vast majority of the cases, requires very little space per element
>
> A bloom filter...?!
>
> http://www.graphics.cornell.edu/pubs/1995/SSZG95.html
>
> -miles
>
> --
> Bigot, n. One who is obstinately and zealously attached to an opinion that
> you do not entertain.
>
>



^ permalink raw reply	[flat|nested] 123+ messages in thread

* bloom filters (was: concurrency suggestions for Gnus)
  2011-02-08  4:31                   ` concurrency suggestions for Gnus Miles Bader
  2011-02-08 12:55                     ` Andy Moreton
  2011-02-08 12:55                     ` Justin Lilly
@ 2011-02-08 14:41                     ` Ted Zlatanov
  2011-02-08 15:15                       ` Stephen J. Turnbull
  2 siblings, 1 reply; 123+ messages in thread
From: Ted Zlatanov @ 2011-02-08 14:41 UTC (permalink / raw)
  To: emacs-devel

On Tue, 08 Feb 2011 13:31:39 +0900 Miles Bader <miles@gnu.org> wrote: 

MB> Ted Zlatanov <tzz@lifelogs.com> writes:
Tom> If we went the "lock anything" route, I would suggest a weak hash table
Tom> for locks, instead of putting the lock into the object.
>> 
>> A bloom filter would guarantee no false negatives, which as you noted is
>> the vast majority of the cases, requires very little space per element

MB> A bloom filter...?!

(changing the subject accordingly)

Basically a fast membership query that uses pairwise independent hash
functions.  Runs in constant time, has no false negatives, and has a
false positive rate correlated to the number of bits per element.  It
would actually be a nice addition to the Emacs core to have a C
implementation.

Ted




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02  3:49             ` Stefan Monnier
  2011-02-02 16:26               ` Tom Tromey
@ 2011-02-08 15:07               ` Tom Tromey
  2011-02-08 21:02                 ` Stefan Monnier
  2011-02-08 21:58                 ` Andreas Schwab
  1 sibling, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-08 15:07 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Tom> I think this will break the nextstep build, since there Vselection_alist
Tom> was erroneously moved to globals.h.  Only DEFVARs have to be in
Tom> globals.h, other globals do not.  I reverted a similar change to
Tom> xselect.c, because I was able to test that one.

Stefan> I much prefer an untested fix than no fix at all.
Stefan> Especially when the untested fix can be based on the code that was there
Stefan> before your global.h change, i.e. pretty likely to work even if you
Stefan> can't test it.

Ok, I included the change I think is needed.

Tom> Let me know what you think.  I'm not excessively happy about the
Tom> ALL_SOURCES bit in src/Makefile.in.

Stefan> The ALL_SOURCES is indeed bad.  We already have equivalent data, so
Stefan> please adjust your patch to try and use it (a good starting point is to
Stefan> look at the dependencies of the make-docfile rule).

Here is another version.  This one hacks make-docfile instead of adding
scripts, and it makes a less invasive change to the Makefile.

Let me know what you think.

Tom

2011-02-08  Tom Tromey  <tromey@redhat.com>

	* make-docfile.c: Unconditionally include stdlib.h.
	(generate_globals): New global.
	(xrealloc): New function.
	(main): Handle '-g'.  Call start_globals, write_globals.
	(scan_file): Conditionally call put_filename.
	(start_globals): New function.
	(struct global): New.
	(num_globals, globals): New globals.
	(add_global, compare_globals, write_globals): New functions.
	(scan_c_file): Update for "-g".
	(scan_lisp_file): Fail if "-g".

2011-02-08  Tom Tromey  <tromey@redhat.com>

	* Makefile.in (NS_OBJC_OBJ): New variable.
	(base_obj): Rename from 'obj'.
	(obj): New variable.
	(globals.h, gl-stamp, $(obj)): New targets.
	(GLOBAL_SOURCES): New variable.
	* globals.h: Remove.
	* nsselect.m (Vselection_alist): Define.  Reverts part of
	r102904.
	* buffer.c: Don't use "no_cell" for name of kill-buffer-hook's
	variable.
	* xselect.c (Vselection_alist): Define.  Reverts part of r102908.

=== modified file 'ChangeLog'
--- ChangeLog	2011-02-07 01:01:26 +0000
+++ ChangeLog	2011-02-08 14:49:45 +0000
@@ -1,3 +1,8 @@
+2011-02-08  Tom Tromey  <tromey@redhat.com>
+
+	* configure: Rebuild.
+	* configure.in (NS_OBJC_OBJ): New subst.
+
 2011-02-06  Paul Eggert  <eggert@cs.ucla.edu>
 
 	gnulib: allow multiple gnulib generated replacements to coexist

=== modified file 'configure'
--- configure	2011-02-05 22:30:14 +0000
+++ configure	2011-02-08 14:54:38 +0000
@@ -864,6 +864,7 @@
 HAVE_XSERVER
 LIB_STANDARD
 NS_SUPPORT
+NS_OBJC_OBJ
 NS_OBJ
 TEMACS_LDFLAGS2
 LD_SWITCH_X_SITE_AUX_RPATH
@@ -1042,9 +1043,6 @@
 LIBS
 CPPFLAGS
 CPP
-CPPFLAGS
-CPP
-CPPFLAGS
 XMKMF'
 
 
@@ -8791,6 +8789,7 @@
 
 ns_frag=/dev/null
 NS_OBJ=
+NS_OBJC_OBJ=
 NS_SUPPORT=
 if test "${HAVE_NS}" = yes; then
   window_system=nextstep
@@ -8802,7 +8801,8 @@
      prefix=${ns_appresdir}
   fi
   ns_frag=$srcdir/src/ns.mk
-  NS_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o fontset.o fringe.o image.o"
+  NS_OBJ="fontset.o fringe.o image.o"
+  NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o"
   NS_SUPPORT="\${lispsource}/emacs-lisp/easymenu.elc \${lispsource}/term/ns-win.elc"
 fi
 CFLAGS="$tmp_CFLAGS"
@@ -8812,6 +8812,7 @@
 
 
 
+
 case "${window_system}" in
   x11 )
     HAVE_X_WINDOWS=yes

=== modified file 'configure.in'
--- configure.in	2011-02-05 22:30:14 +0000
+++ configure.in	2011-02-07 21:47:58 +0000
@@ -1519,6 +1519,7 @@
 
 ns_frag=/dev/null
 NS_OBJ=
+NS_OBJC_OBJ=
 NS_SUPPORT=
 if test "${HAVE_NS}" = yes; then
   window_system=nextstep
@@ -1530,12 +1531,14 @@
      prefix=${ns_appresdir}
   fi
   ns_frag=$srcdir/src/ns.mk
-  NS_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o fontset.o fringe.o image.o"
+  NS_OBJ="fontset.o fringe.o image.o"
+  NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o"
   NS_SUPPORT="\${lispsource}/emacs-lisp/easymenu.elc \${lispsource}/term/ns-win.elc"
 fi
 CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
 AC_SUBST(NS_OBJ)
+AC_SUBST(NS_OBJC_OBJ)
 AC_SUBST(NS_SUPPORT)
 AC_SUBST(LIB_STANDARD)
 AC_SUBST_FILE(ns_frag)

=== modified file 'lib-src/make-docfile.c'
--- lib-src/make-docfile.c	2011-01-30 09:17:36 +0000
+++ lib-src/make-docfile.c	2011-02-08 14:16:03 +0000
@@ -41,11 +41,11 @@
 #undef chdir
 
 #include <stdio.h>
-#ifdef MSDOS
-#include <fcntl.h>
-#endif /* MSDOS */
-#ifdef WINDOWSNT
 #include <stdlib.h>
+#ifdef MSDOS
+#include <fcntl.h>
+#endif /* MSDOS */
+#ifdef WINDOWSNT
 #include <fcntl.h>
 #include <direct.h>
 #endif /* WINDOWSNT */
@@ -70,6 +70,8 @@
 int scan_lisp_file (const char *filename, const char *mode);
 int scan_c_file (char *filename, const char *mode);
 void fatal (const char *s1, const char *s2) NO_RETURN;
+void start_globals (void);
+void write_globals (void);
 
 #ifdef MSDOS
 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
@@ -85,6 +87,9 @@
 /* Name this program was invoked with.  */
 char *progname;
 
+/* Nonzero if this invocation is generating globals.h.  */
+int generate_globals;
+
 /* Print error message.  `s1' is printf control string, `s2' is arg for it.  */
 
 /* VARARGS1 */
@@ -116,6 +121,18 @@
     fatal ("virtual memory exhausted", 0);
   return result;
 }
+
+/* Like realloc but get fatal error if memory is exhausted.  */
+
+void *
+xrealloc (void *arg, unsigned int size)
+{
+  void *result = (void *) realloc (arg, size);
+  if (result == NULL)
+    fatal ("virtual memory exhausted", 0);
+  return result;
+}
+
 \f
 int
 main (int argc, char **argv)
@@ -164,10 +181,18 @@
 	}
       i += 2;
     }
+  if (argc > i && !strcmp (argv[i], "-g"))
+    {
+      generate_globals = 1;
+      ++i;
+    }
 
   if (outfile == 0)
     fatal ("No output file specified", "");
 
+  if (generate_globals)
+    start_globals ();
+
   first_infile = i;
   for (; i < argc; i++)
     {
@@ -179,6 +204,10 @@
       if (j == i)
 	err_count += scan_file (argv[i]);
     }
+
+  if (err_count == 0 && generate_globals)
+    write_globals ();
+
   return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
@@ -208,7 +237,8 @@
 
   size_t len = strlen (filename);
 
-  put_filename (filename);
+  if (!generate_globals)
+    put_filename (filename);
   if (len > 4 && !strcmp (filename + len - 4, ".elc"))
     return scan_lisp_file (filename, READ_BINARY);
   else if (len > 3 && !strcmp (filename + len - 3, ".el"))
@@ -216,6 +246,14 @@
   else
     return scan_c_file (filename, READ_TEXT);
 }
+
+void
+start_globals (void)
+{
+  fprintf (outfile, "/* This file was auto-generated by make-docfile.  */\n");
+  fprintf (outfile, "/* DO NOT EDIT.  */\n");
+  fprintf (outfile, "struct emacs_globals {\n");
+}
 \f
 char buf[128];
 
@@ -517,6 +555,69 @@
   putc (')', out);
 }
 \f
+/* A single global.  */
+struct global
+{
+  char type;
+  char *name;
+};
+
+/* All the variable names we saw while scanning C sources in `-g'
+   mode.  */
+int num_globals;
+struct global *globals;
+
+static void
+add_global (char type, char *name)
+{
+  /* Ignore the one non-symbol that can occur.  */
+  if (strcmp (name, "..."))
+    {
+      ++num_globals;
+      globals = xrealloc (globals, num_globals * sizeof (struct global));
+      globals[num_globals - 1].type = type;
+      globals[num_globals - 1].name = name;
+    }
+}
+
+static int
+compare_globals (const void *a, const void *b)
+{
+  const struct global *ga = a;
+  const struct global *gb = b;
+  return strcmp (ga->name, gb->name);
+}
+
+void
+write_globals (void)
+{
+  int i;
+  qsort (globals, num_globals, sizeof (struct global), compare_globals);
+  for (i = 0; i < num_globals; ++i)
+    {
+      char *type;
+      if (globals[i].type == 'I')
+	type = "EMACS_INT";
+      else if (globals[i].type == 'B')
+	type = "int";
+      else if (globals[i].type == 'L')
+	type = "Lisp_Object";
+      else
+	fatal ("not a recognized DEFVAR_", 0);
+
+      fprintf (outfile, "  %s f_%s;\n", type, globals[i].name);
+      fprintf (outfile, "#define %s globals.f_%s\n",
+	       globals[i].name, globals[i].name);
+      while (i + 1 < num_globals
+	     && !strcmp (globals[i].name, globals[i + 1].name))
+	++i;
+    }
+
+  fprintf (outfile, "};\n");
+  fprintf (outfile, "extern struct emacs_globals globals;\n");
+}
+
+\f
 /* Read through a c file.  If a .o file is named,
    the corresponding .c or .m file is read instead.
    Looks for DEFUN constructs such as are defined in ../src/lisp.h.
@@ -533,6 +634,7 @@
   register int defvarflag;
   int minargs, maxargs;
   int extension = filename[strlen (filename) - 1];
+  char type;
 
   if (extension == 'o')
     filename[strlen (filename) - 1] = 'c';
@@ -599,8 +701,13 @@
 
 	  c = getc (infile);
 	  defvarperbufferflag = (c == 'P');
+	  type = c;
 
 	  c = getc (infile);
+	  /* We need to distinguish between DEFVAR_BOOL and
+	     DEFVAR_BUFFER_DEFAULTS.  */
+	  if (generate_globals && type == 'B' && c != 'O')
+	    type = 'X';
 	}
       else if (c == 'D')
 	{
@@ -617,6 +724,11 @@
 	}
       else continue;
 
+      if (generate_globals && (!defvarflag || defvarperbufferflag
+			       || (type != 'I' && type != 'B'
+				   && type != 'L')))
+	continue;
+
       while (c != '(')
 	{
 	  if (c < 0)
@@ -630,6 +742,34 @@
 	continue;
       c = read_c_string_or_comment (infile, -1, 0, 0);
 
+      if (generate_globals)
+	{
+	  int i = 0;
+	  char *name;
+
+	  /* Skip "," and whitespace.  */
+	  do
+	    {
+	      c = getc (infile);
+	    }
+	  while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r');
+
+	  /* Read in the identifier.  */
+	  do
+	    {
+	      buf[i++] = c;
+	      c = getc (infile);
+	    }
+	  while (! (c == ',' || c == ' ' || c == '\t' ||
+		    c == '\n' || c == '\r'));
+	  buf[i] = '\0';
+
+	  name = xmalloc (i + 1);
+	  memcpy (name, buf, i + 1);
+	  add_global (type, name);
+	  continue;
+	}
+
       /* DEFVAR_LISP ("name", addr, "doc")
 	 DEFVAR_LISP ("name", addr /\* doc *\/)
 	 DEFVAR_LISP ("name", addr, doc: /\* doc *\/)  */
@@ -845,6 +985,9 @@
   register int c;
   char *saved_string = 0;
 
+  if (generate_globals)
+    fatal ("scanning lisp file when -g specified", 0);
+
   infile = fopen (filename, mode);
   if (infile == NULL)
     {

=== modified file 'src/Makefile.in'
--- src/Makefile.in	2011-01-30 23:34:18 +0000
+++ src/Makefile.in	2011-02-07 21:49:22 +0000
@@ -247,6 +247,7 @@
 ns_appbindir=@ns_appbindir@
 ns_appsrc=@ns_appsrc@
 NS_OBJ=@NS_OBJ@
+NS_OBJC_OBJ=@NS_OBJC_OBJ@
 NS_SUPPORT=@NS_SUPPORT@
 ## Only set if NS_IMPL_GNUSTEP.
 GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@
@@ -341,7 +342,7 @@
 
 ## lastfile must follow all files whose initialized data areas should
 ## be dumped as pure by dump-emacs.
-obj=    dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
+base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
 	charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
 	cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
 	emacs.o keyboard.o macros.o keymap.o sysdep.o \
@@ -355,6 +356,7 @@
 	region-cache.o sound.o atimer.o \
 	doprnt.o intervals.o textprop.o composite.o md5.o xml.o \
 	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
+obj = $(base_obj) $(NS_OBJC_OBJ)
 
 ## Object files used on some machine or other.
 ## These go in the DOC file on all machines in case they are needed.
@@ -645,6 +647,18 @@
 buildobj.h: Makefile
 	echo "#define BUILDOBJ \"$(obj) $(otherobj) " "\"" > buildobj.h
 
+globals.h: gl-stamp
+	cp gl-stamp globals.h
+
+GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m)
+
+gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES)
+	@rm -f gl-tmp
+	$(libsrc)/make-docfile -d $(srcdir) -g $(SOME_MACHINE_OBJECTS) $(obj) > gl-tmp
+	$(srcdir)/../move-if-change gl-tmp gl-stamp
+
+$(obj): globals.h
+
 $(lib)/libgnu.a: $(config_h)
 	cd $(lib) && $(MAKE) libgnu.a
 

=== modified file 'src/buffer.c'
--- src/buffer.c	2011-02-06 19:44:36 +0000
+++ src/buffer.c	2011-02-07 21:46:20 +0000
@@ -1320,7 +1320,7 @@
 }
 
 /*
-  DEFVAR_LISP ("kill-buffer-hook", no_cell, "\
+  DEFVAR_LISP ("kill-buffer-hook", ..., "\
 Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
 The buffer being killed will be current while the hook is running.\n\
 See `kill-buffer'."

=== removed file 'src/globals.h'
--- src/globals.h	2011-01-26 20:02:07 +0000
+++ src/globals.h	1970-01-01 00:00:00 +0000
@@ -1,2900 +0,0 @@
-/* Declare all global lisp variables.
-
-   Copyright (C) 2011  Free Software Foundation, Inc.
-
-   This file is part of GNU Emacs.
-
-   GNU Emacs is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   GNU Emacs is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
-
-struct emacs_globals
-{
-
-  /* Count the amount of consing of various sorts of space.  */
-  EMACS_INT f_cons_cells_consed;
-
-  EMACS_INT f_floats_consed;
-
-  EMACS_INT f_vector_cells_consed;
-
-  EMACS_INT f_symbols_consed;
-
-  EMACS_INT f_string_chars_consed;
-
-  EMACS_INT f_misc_objects_consed;
-
-  EMACS_INT f_intervals_consed;
-
-  EMACS_INT f_strings_consed;
-
-  /* Minimum number of bytes of consing since GC before next GC. */
-  EMACS_INT f_gc_cons_threshold;
-
-  Lisp_Object f_Vgc_cons_percentage;
-
-  /* Nonzero means display messages at beginning and end of GC.  */
-  int f_garbage_collection_messages;
-
-  /* Non-nil means defun should do purecopy on the function definition.  */
-  Lisp_Object f_Vpurify_flag;
-
-  /* Non-nil means we are handling a memory-full error.  */
-  Lisp_Object f_Vmemory_full;
-
-  /* Total number of bytes allocated in pure storage. */
-  EMACS_INT f_pure_bytes_used;
-
-  /* Pre-computed signal argument for use when memory is exhausted.  */
-  Lisp_Object f_Vmemory_signal_data;
-
-  Lisp_Object f_Vpost_gc_hook;
-
-  Lisp_Object f_Vgc_elapsed;
-
-  EMACS_INT f_gcs_done;
-
-  /* Functions to call before and after each text change. */
-  Lisp_Object f_Vbefore_change_functions;
-
-  Lisp_Object f_Vafter_change_functions;
-
-  Lisp_Object f_Vtransient_mark_mode;
-
-  /* t means ignore all read-only text properties.
-     A list means ignore such a property if its value is a member of the list.
-     Any non-nil value means ignore buffer-read-only.  */
-  Lisp_Object f_Vinhibit_read_only;
-
-  /* List of functions to call that can query about killing a buffer.
-     If any of these functions returns nil, we don't kill it.  */
-  Lisp_Object f_Vkill_buffer_query_functions;
-
-  Lisp_Object f_Vchange_major_mode_hook;
-
-  /* List of functions to call before changing an unmodified buffer.  */
-  Lisp_Object f_Vfirst_change_hook;
-
-  /* If nonzero, all modification hooks are suppressed.  */
-  int f_inhibit_modification_hooks;
-
-  Lisp_Object f_Vbyte_code_meter;
-
-  int f_byte_metering_on;
-
-  Lisp_Object f_Vcurrent_prefix_arg;
-
-  Lisp_Object f_Vcommand_history;
-
-  Lisp_Object f_Vcommand_debug_status;
-
-  /* Non-nil means treat the mark as active
-     even if mark_active is 0.  */
-  Lisp_Object f_Vmark_even_if_inactive;
-
-  Lisp_Object f_Vmouse_leave_buffer_hook;
-
-  Lisp_Object f_Vexec_path;
-  Lisp_Object f_Vexec_directory;
-  Lisp_Object f_Vexec_suffixes;
-
-  Lisp_Object f_Vdata_directory;
-  Lisp_Object f_Vdoc_directory;
-
-  Lisp_Object f_Vconfigure_info_directory;
-  Lisp_Object f_Vshared_game_score_directory;
-
-  Lisp_Object f_Vshell_file_name;
-
-  Lisp_Object f_Vprocess_environment;
-  Lisp_Object f_Vinitial_environment;
-
-  /* Variables to determine word boundary.  */
-  Lisp_Object f_Vword_combining_categories;
-  Lisp_Object f_Vword_separating_categories;
-
-  /* This contains all code conversion map available to CCL.  */
-  Lisp_Object f_Vcode_conversion_map_vector;
-
-  /* Alist of fontname patterns vs corresponding CCL program.  */
-  Lisp_Object f_Vfont_ccl_encoder_alist;
-
-  /* Vector of registered hash tables for translation.  */
-  Lisp_Object f_Vtranslation_hash_table_vector;
-
-  /* Vector of translation table ever defined.
-     ID of a translation table is used to index this vector.  */
-  Lisp_Object f_Vtranslation_table_vector;
-
-  /* A char-table for characters which may invoke auto-filling.  */
-  Lisp_Object f_Vauto_fill_chars;
-
-  /* A char-table.  An element is non-nil iff the corresponding
-     character has a printable glyph.  */
-  Lisp_Object f_Vprintable_chars;
-
-  /* A char-table.  An elemnent is a column-width of the corresponding
-     character.  */
-  Lisp_Object f_Vchar_width_table;
-
-  /* A char-table.  An element is a symbol indicating the direction
-     property of corresponding character.  */
-  Lisp_Object f_Vchar_direction_table;
-
-  /* Char table of scripts.  */
-  Lisp_Object f_Vchar_script_table;
-
-  /* Alist of scripts vs representative characters.  */
-  Lisp_Object f_Vscript_representative_chars;
-
-  Lisp_Object f_Vunicode_category_table;
-
-  /* List of all charsets.  This variable is used only from Emacs
-     Lisp.  */
-  Lisp_Object f_Vcharset_list;
-
-  Lisp_Object f_Vcharset_map_path;
-
-  /* If nonzero, don't load charset maps.  */
-  int f_inhibit_load_charset_map;
-
-  Lisp_Object f_Vcurrent_iso639_language;
-
-  Lisp_Object f_Vpost_self_insert_hook;
-
-  int f_coding_system_require_warning;
-
-  Lisp_Object f_Vselect_safe_coding_system_function;
-
-  /* Mnemonic string for each format of end-of-line.  */
-  Lisp_Object f_eol_mnemonic_unix;
-  Lisp_Object f_eol_mnemonic_dos;
-  Lisp_Object f_eol_mnemonic_mac;
-
-  /* Mnemonic string to indicate format of end-of-line is not yet
-     decided.  */
-  Lisp_Object f_eol_mnemonic_undecided;
-
-  Lisp_Object f_Vcoding_system_list;
-  Lisp_Object f_Vcoding_system_alist;
-
-  /* Coding-system for reading files and receiving data from process.  */
-  Lisp_Object f_Vcoding_system_for_read;
-
-  /* Coding-system for writing files and sending data to process.  */
-  Lisp_Object f_Vcoding_system_for_write;
-
-  /* Coding-system actually used in the latest I/O.  */
-  Lisp_Object f_Vlast_coding_system_used;
-
-  /* Set to non-nil when an error is detected while code conversion.  */
-  Lisp_Object f_Vlast_code_conversion_error;
-
-  /* A vector of length 256 which contains information about special
-     Latin codes (especially for dealing with Microsoft codes).  */
-  Lisp_Object f_Vlatin_extra_code_table;
-
-  /* Flag to inhibit code conversion of end-of-line format.  */
-  int f_inhibit_eol_conversion;
-
-  /* Flag to inhibit ISO2022 escape sequence detection.  */
-  int f_inhibit_iso_escape_detection;
-
-  /* Flag to inhibit detection of binary files through null bytes.  */
-  int f_inhibit_null_byte_detection;
-
-  /* Flag to make buffer-file-coding-system inherit from process-coding.  */
-  int f_inherit_process_coding_system;
-
-  Lisp_Object f_Vfile_coding_system_alist;
-
-  Lisp_Object f_Vprocess_coding_system_alist;
-
-  Lisp_Object f_Vnetwork_coding_system_alist;
-
-  Lisp_Object f_Vlocale_coding_system;
-
-  /* Flag to tell if we look up translation table on character code
-     conversion.  */
-  Lisp_Object f_Venable_character_translation;
-
-  /* Standard translation table to look up on decoding (reading).  */
-  Lisp_Object f_Vstandard_translation_table_for_decode;
-
-  /* Standard translation table to look up on encoding (writing).  */
-  Lisp_Object f_Vstandard_translation_table_for_encode;
-
-  /* Alist of charsets vs revision number.  */
-  Lisp_Object f_Vcharset_revision_table;
-
-  /* Default coding systems used for process I/O.  */
-  Lisp_Object f_Vdefault_process_coding_system;
-
-  /* Char table for translating Quail and self-inserting input.  */
-  Lisp_Object f_Vtranslation_table_for_input;
-
-  /* List of symbols `coding-category-xxx' ordered by priority.  This
-     variable is exposed to Emacs Lisp.  */
-  Lisp_Object f_Vcoding_category_list;
-
-  /* Function to call to adjust composition.  */
-  Lisp_Object f_Vcompose_chars_after_function;
-
-  Lisp_Object f_Vauto_composition_mode;
-
-  Lisp_Object f_Vauto_composition_function;
-
-  Lisp_Object f_Vcomposition_function_table;
-
-  Lisp_Object f_Vmost_positive_fixnum;
-  Lisp_Object f_Vmost_negative_fixnum;
-
-  /* Registered buses.  */
-  Lisp_Object f_Vdbus_registered_buses;
-
-  /* Hash table which keeps function definitions.  */
-  Lisp_Object f_Vdbus_registered_objects_table;
-
-  /* Whether to debug D-Bus.  */
-  Lisp_Object f_Vdbus_debug;
-
-  Lisp_Object f_Vcompletion_ignored_extensions;
-
-  /* Non-zero means don't pause redisplay for pending input.  (This is
-     for debugging and for a future implementation of EDT-like
-     scrolling.  */
-  int f_redisplay_dont_pause;
-
-  /* If a number (float), check for user input every N seconds.  */
-  Lisp_Object f_Vredisplay_preemption_period;
-
-  /* Lisp variable visible-bell; enables use of screen-flash instead of
-     audible bell.  */
-  int f_visible_bell;
-
-  /* Invert the color of the whole frame, at a low level.  */
-  int f_inverse_video;
-
-  /* Line speed of the terminal.  */
-  EMACS_INT f_baud_rate;
-
-  /* Either nil or a symbol naming the window system under which Emacs
-     creates the first frame.  */
-  Lisp_Object f_Vinitial_window_system;
-
-  /* Version number of X windows: 10, 11 or nil.  */
-  Lisp_Object f_Vwindow_system_version;
-
-  /* Vector of glyph definitions.  Indexed by glyph number, the contents
-     are a string which is how to output the glyph.
-
-     If Vglyph_table is nil, a glyph is output by using its low 8 bits
-     as a character code.
-
-     This is an obsolete feature that is no longer used.  The variable
-     is retained for compatibility.  */
-  Lisp_Object f_Vglyph_table;
-
-  /* Display table to use for vectors that don't specify their own.  */
-  Lisp_Object f_Vstandard_display_table;
-
-  /* Nonzero means reading single-character input with prompt so put
-     cursor on mini-buffer after the prompt.  Positive means at end of
-     text in echo area; negative means at beginning of line.  */
-  int f_cursor_in_echo_area;
-
-  Lisp_Object f_Vdoc_file_name;
-
-  /* A list of files used to build this Emacs binary.  */
-  Lisp_Object f_Vbuild_files;
-
-  /* country info */
-  EMACS_INT f_dos_country_code;
-
-  EMACS_INT f_dos_codepage;
-
-  EMACS_INT f_dos_timezone_offset;
-
-  EMACS_INT f_dos_decimal_point;
-
-  EMACS_INT f_dos_keyboard_layout;
-
-  EMACS_INT f_dos_hyper_key;
-
-  EMACS_INT f_dos_super_key;
-
-  EMACS_INT f_dos_keypad_mode;
-
-  Lisp_Object f_Vdos_version;
-
-  Lisp_Object f_Vdos_display_scancodes;
-
-  Lisp_Object f_Vdos_windows_version;
-
-  Lisp_Object f_Vbuffer_access_fontify_functions;
-
-  Lisp_Object f_Vbuffer_access_fontified_property;
-
-  /* Non-nil means don't stop at field boundary in text motion commands.  */
-  Lisp_Object f_Vinhibit_field_text_motion;
-
-  /* Some static data, and a function to initialize it for each run */
-  Lisp_Object f_Vsystem_name;
-
-  Lisp_Object f_Vuser_real_login_name;
-
-  Lisp_Object f_Vuser_full_name;
-
-  Lisp_Object f_Vuser_login_name;
-
-  Lisp_Object f_Voperating_system_release;
-
-  /* Command line args from shell, as list of strings.  */
-  Lisp_Object f_Vcommand_line_args;
-
-  /* The name under which Emacs was invoked, with any leading directory
-     names discarded.  */
-  Lisp_Object f_Vinvocation_name;
-
-  /* The directory name from which Emacs was invoked.  */
-  Lisp_Object f_Vinvocation_directory;
-
-  /* The directory name in which to find subdirs such as lisp and etc.
-     nil means get them only from PATH_LOADSEARCH.  */
-  Lisp_Object f_Vinstallation_directory;
-
-  /* The values of `current-time' before and after Emacs initialization.  */
-  Lisp_Object f_Vbefore_init_time;
-  Lisp_Object f_Vafter_init_time;
-
-  /* Hook run by `kill-emacs' before it does really anything.  */
-  Lisp_Object f_Vkill_emacs_hook;
-
-  /* Search path separator.  */
-  Lisp_Object f_Vpath_separator;
-
-  /* Variable whose value is symbol giving operating system type.  */
-  Lisp_Object f_Vsystem_type;
-
-  /* Variable whose value is string giving configuration built for.  */
-  Lisp_Object f_Vsystem_configuration;
-
-  /* Variable whose value is string giving configuration options,
-     for use when reporting bugs.  */
-  Lisp_Object f_Vsystem_configuration_options;
-
-  /* Current and previous system locales for messages and time.  */
-  Lisp_Object f_Vsystem_messages_locale;
-
-  Lisp_Object f_Vprevious_system_messages_locale;
-
-  Lisp_Object f_Vsystem_time_locale;
-
-  Lisp_Object f_Vprevious_system_time_locale;
-
-  /* Copyright and version info.  The version number may be updated by
-     Lisp code.  */
-  Lisp_Object f_Vemacs_copyright;
-  Lisp_Object f_Vemacs_version;
-
-  /* Alist of external libraries and files implementing them.  */
-  Lisp_Object f_Vdynamic_library_alist;
-
-  /* Value of Lisp variable `noninteractive'.
-     Normally same as C variable `noninteractive'
-     but nothing terrible happens if user sets this one.  */
-  int f_noninteractive1;
-
-  /* Nonzero means Emacs was run in --quick mode.  */
-  int f_inhibit_x_resources;
-
-  Lisp_Object f_Vinhibit_quit;
-  Lisp_Object f_Vquit_flag;
-
-  /* Maximum size allowed for specpdl allocation */
-  EMACS_INT f_max_specpdl_size;
-
-  /* Maximum allowed depth in Lisp evaluations and function calls.  */
-  EMACS_INT f_max_lisp_eval_depth;
-
-  /* Nonzero means enter debugger before next function call */
-  int f_debug_on_next_call;
-
-  /* Non-zero means debugger may continue.  This is zero when the
-     debugger is called during redisplay, where it might not be safe to
-     continue the interrupted redisplay. */
-  int f_debugger_may_continue;
-
-  /* List of conditions (non-nil atom means all) which enter the debugger
-     if an error is handled by the command loop's error handler.  */
-  Lisp_Object f_Vdebug_on_error;
-
-  /* List of conditions and regexps specifying error messages which
-     do not enter the debugger even if Vdebug_on_error says they should.  */
-  Lisp_Object f_Vdebug_ignored_errors;
-
-  /* Non-nil means call the debugger even if the error will be handled.  */
-  Lisp_Object f_Vdebug_on_signal;
-
-  /* Hook for edebug to use.  */
-  Lisp_Object f_Vsignal_hook_function;
-
-  /* Nonzero means enter debugger if a quit signal
-     is handled by the command loop's error handler. */
-  int f_debug_on_quit;
-
-  Lisp_Object f_Vdebugger;
-
-  /* Function to process declarations in defmacro forms.  */
-  Lisp_Object f_Vmacro_declaration_function;
-
-  /* Coding system for file names, or nil if none.  */
-  Lisp_Object f_Vfile_name_coding_system;
-
-  /* Coding system for file names used only when
-     Vfile_name_coding_system is nil.  */
-  Lisp_Object f_Vdefault_file_name_coding_system;
-
-  /* Alist of elements (REGEXP . HANDLER) for file names
-     whose I/O is done with a special handler.  */
-  Lisp_Object f_Vfile_name_handler_alist;
-
-  /* Function to be called to decide a coding system of a reading file.  */
-  Lisp_Object f_Vset_auto_coding_function;
-
-  /* Functions to be called to process text properties in inserted file.  */
-  Lisp_Object f_Vafter_insert_file_functions;
-
-  /* Functions to be called to create text property annotations for file.  */
-  Lisp_Object f_Vwrite_region_annotate_functions;
-
-  Lisp_Object f_Vwrite_region_post_annotation_function;
-
-  /* During build_annotations, each time an annotation function is called,
-     this holds the annotations made by the previous functions.  */
-  Lisp_Object f_Vwrite_region_annotations_so_far;
-
-  /* File name in which we write a list of all our auto save files.  */
-  Lisp_Object f_Vauto_save_list_file_name;
-
-  /* Whether or not files are auto-saved into themselves.  */
-  Lisp_Object f_Vauto_save_visited_file_name;
-
-  /* Whether or not to continue auto-saving after a large deletion.  */
-  Lisp_Object f_Vauto_save_include_big_deletions;
-
-  /* Nonzero means skip the call to fsync in Fwrite-region.  */
-  int f_write_region_inhibit_fsync;
-
-  /* Non-zero means call move-file-to-trash in Fdelete_file or
-     Fdelete_directory_internal.  */
-  int f_delete_by_moving_to_trash;
-
-  /* These variables describe handlers that have "already" had a chance
-     to handle the current operation.
-
-     Vinhibit_file_name_handlers is a list of file name handlers.
-     Vinhibit_file_name_operation is the operation being handled.
-     If we try to handle that operation, we ignore those handlers.  */
-  Lisp_Object f_Vinhibit_file_name_handlers;
-
-  Lisp_Object f_Vinhibit_file_name_operation;
-
-  /* The directory for writing temporary files.  */
-  Lisp_Object f_Vtemporary_file_directory;
-
-  /* Nonzero enables use of dialog boxes for questions
-     asked by mouse commands.  */
-  int f_use_dialog_box;
-
-  /* Nonzero enables use of a file dialog for file name
-     questions asked by mouse commands.  */
-  int f_use_file_dialog;
-
-  Lisp_Object f_Vfeatures;
-
-  Lisp_Object f_Vfont_weight_table;
-  Lisp_Object f_Vfont_slant_table;
-  Lisp_Object f_Vfont_width_table;
-
-  Lisp_Object f_Vfont_encoding_alist;
-
-  Lisp_Object f_Vfont_log;
-
-  Lisp_Object f_Vfont_encoding_charset_alist;
-
-  Lisp_Object f_Vuse_default_ascent;
-
-  Lisp_Object f_Vignore_relative_composition;
-
-  Lisp_Object f_Valternate_fontname_alist;
-
-  Lisp_Object f_Vfontset_alias_alist;
-
-  Lisp_Object f_Vvertical_centering_font_regexp;
-
-  Lisp_Object f_Votf_script_alist;
-
-  /* If we shall make pointer invisible when typing or not.  */
-  Lisp_Object f_Vmake_pointer_invisible;
-
-  /* The name we're using in resource queries.  Most often "emacs".  */
-  Lisp_Object f_Vx_resource_name;
-
-  /* The application class we're using in resource queries.
-     Normally "Emacs".  */
-  Lisp_Object f_Vx_resource_class;
-
-  /* Lower limit value of the frame opacity (alpha transparency).  */
-  Lisp_Object f_Vframe_alpha_lower_limit;
-
-  Lisp_Object f_Vmenu_bar_mode;
-  Lisp_Object f_Vtool_bar_mode;
-
-  Lisp_Object f_Vterminal_frame;
-
-  Lisp_Object f_Vdefault_frame_alist;
-
-  Lisp_Object f_Vdefault_frame_scroll_bars;
-
-  Lisp_Object f_Vmouse_position_function;
-
-  Lisp_Object f_Vmouse_highlight;
-
-  Lisp_Object f_Vdelete_frame_functions;
-
-  int f_focus_follows_mouse;
-
-  /* Non-nil means that newline may flow into the right fringe.  */
-  Lisp_Object f_Voverflow_newline_into_fringe;
-
-  /* List of known fringe bitmap symbols.
-
-     The fringe bitmap number is stored in the `fringe' property on
-     those symbols.  Names for the built-in bitmaps are installed by
-     loading fringe.el.
-  */
-  Lisp_Object f_Vfringe_bitmaps;
-
-  /* Search path for bitmap files.  */
-  Lisp_Object f_Vx_bitmap_file_path;
-
-  /* A list of symbols, one for each supported image type.  */
-  Lisp_Object f_Vimage_types;
-
-  /* Time in seconds after which images should be removed from the cache
-     if not displayed.  */
-  Lisp_Object f_Vimage_cache_eviction_delay;
-
-  Lisp_Object f_Vmax_image_size;
-
-  /* Non-zero means draw a cross on images having `:conversion
-     disabled'.  */
-  int f_cross_disabled_images;
-
-  Lisp_Object f_Vimagemagick_render_type;
-
-  /* Indentation can insert tabs if this is non-zero;
-     otherwise always uses spaces.  */
-  int f_indent_tabs_mode;
-
-  /* Non-nil means don't call the after-change-functions right away,
-     just record an element in combine_after_change_list.  */
-  Lisp_Object f_Vcombine_after_change_calls;
-
-  /* Check all markers in the current buffer, looking for something invalid.  */
-  int f_check_markers_debug_flag;
-
-  /* Non-nil if the present key sequence was obtained by shift translation.  */
-  Lisp_Object f_Vthis_command_keys_shift_translated;
-
-  /* If non-nil, the function that implements the display of help.
-     It's called with one argument, the help string to display.  */
-  Lisp_Object f_Vshow_help_function;
-
-  /* Nonzero means do menu prompting.  */
-  int f_menu_prompting;
-
-  /* Character to see next line of menu prompt.  */
-  Lisp_Object f_menu_prompt_more_char;
-
-  /* Nonzero means disregard local maps for the menu bar.  */
-  int f_inhibit_local_menu_bar_menus;
-
-  /* The user's hook function for outputting an error message.  */
-  Lisp_Object f_Vcommand_error_function;
-
-  /* The user's ERASE setting.  */
-  Lisp_Object f_Vtty_erase_char;
-
-  /* Character to recognize as the help char.  */
-  Lisp_Object f_Vhelp_char;
-
-  /* List of other event types to recognize as meaning "help".  */
-  Lisp_Object f_Vhelp_event_list;
-
-  /* Form to execute when help char is typed.  */
-  Lisp_Object f_Vhelp_form;
-
-  /* Command to run when the help character follows a prefix key.  */
-  Lisp_Object f_Vprefix_help_command;
-
-  /* List of items that should move to the end of the menu bar.  */
-  Lisp_Object f_Vmenu_bar_final_items;
-
-  /* Expression to evaluate for the tool bar separator image.
-     This is used for build_desired_tool_bar_string only.  For GTK, we
-     use GTK tool bar seperators.  */
-  Lisp_Object f_Vtool_bar_separator_image_expression;
-
-  /* Non-nil means show the equivalent key-binding for
-     any M-x command that has one.
-     The value can be a length of time to show the message for.
-     If the value is non-nil and not a number, we wait 2 seconds.  */
-  Lisp_Object f_Vsuggest_key_bindings;
-
-  /* How long to display an echo-area message when the minibuffer is active.
-     If the value is not a number, such messages don't time out.  */
-  Lisp_Object f_Vminibuffer_message_timeout;
-
-  /* If non-nil, this is a map that overrides all other local maps.  */
-  Lisp_Object f_Voverriding_local_map;
-
-  /* If non-nil, Voverriding_local_map applies to the menu bar.  */
-  Lisp_Object f_Voverriding_local_map_menu_flag;
-
-  /* Keymap that defines special misc events that should
-     be processed immediately at a low level.  */
-  Lisp_Object f_Vspecial_event_map;
-
-  /* Total number of times command_loop has read a key sequence.  */
-  EMACS_INT f_num_input_keys;
-
-  /* Last input event read as a command.  */
-  Lisp_Object f_last_command_event;
-
-  /* Last input character read as a command, not counting menus
-     reached by the mouse.  */
-  Lisp_Object f_last_nonmenu_event;
-
-  /* Last input event read for any purpose.  */
-  Lisp_Object f_last_input_event;
-
-  /* If not Qnil, a list of objects to be read as subsequent command input.  */
-  Lisp_Object f_Vunread_command_events;
-
-  /* If not Qnil, a list of objects to be read as subsequent command input
-     including input method processing.  */
-  Lisp_Object f_Vunread_input_method_events;
-
-  /* If not Qnil, a list of objects to be read as subsequent command input
-     but NOT including input method processing.  */
-  Lisp_Object f_Vunread_post_input_method_events;
-
-  /* If not -1, an event to be read as subsequent command input.  */
-  EMACS_INT f_unread_command_char;
-
-  /* A mask of extra modifier bits to put into every keyboard char.  */
-  EMACS_INT f_extra_keyboard_modifiers;
-
-  /* Char to use as prefix when a meta character is typed in.
-     This is bound on entry to minibuffer in case ESC is changed there.  */
-  Lisp_Object f_meta_prefix_char;
-
-  /* Number of idle seconds before an auto-save and garbage collection.  */
-  Lisp_Object f_Vauto_save_timeout;
-
-  /* Total number of times read_char has returned, outside of macros.  */
-  EMACS_INT f_num_nonmacro_input_events;
-
-  /* Auto-save automatically when this many characters have been typed
-     since the last time.  */
-  EMACS_INT f_auto_save_interval;
-
-  /* The command being executed by the command loop.
-     Commands may set this, and the value set will be copied into
-     current_kboard->Vlast_command instead of the actual command.  */
-  Lisp_Object f_Vthis_command;
-
-  /* If the lookup of the command returns a binding, the original
-     command is stored in this-original-command.  It is nil otherwise.  */
-  Lisp_Object f_Vthis_original_command;
-
-  /* A user-visible version of the above, intended to allow users to
-     figure out where the last event came from, if the event doesn't
-     carry that information itself (i.e. if it was a character).  */
-  Lisp_Object f_Vlast_event_frame;
-
-  /* If non-nil, active regions automatically become the window selection.  */
-  Lisp_Object f_Vselect_active_regions;
-
-  /* The text in the active region prior to modifying the buffer.
-     Used by the `select-active-regions' feature.  */
-  Lisp_Object f_Vsaved_region_selection;
-
-  /* Echo unfinished commands after this many seconds of pause.  */
-  Lisp_Object f_Vecho_keystrokes;
-
-  /* Form to evaluate (if non-nil) when Emacs is started.  */
-  Lisp_Object f_Vtop_level;
-
-  /* If non-nil, this implements the current input method.  */
-  Lisp_Object f_Vinput_method_function;
-
-  /* When we call Vinput_method_function,
-     this holds the echo area message that was just erased.  */
-  Lisp_Object f_Vinput_method_previous_message;
-
-  /* Non-nil means deactivate the mark at end of this command.  */
-  Lisp_Object f_Vdeactivate_mark;
-
-  /* Menu bar specified in Lucid Emacs fashion.  */
-  Lisp_Object f_Vlucid_menu_bar_dirty_flag;
-
-  Lisp_Object f_Vpre_command_hook;
-
-  Lisp_Object f_Vpost_command_hook;
-
-  Lisp_Object f_Vcommand_hook_internal;
-
-  /* Parent keymap of terminal-local function-key-map instances.  */
-  Lisp_Object f_Vfunction_key_map;
-
-  /* Keymap of key translations that can override keymaps.  */
-  Lisp_Object f_Vkey_translation_map;
-
-  /* List of deferred actions to be performed at a later time.
-     The precise format isn't relevant here; we just check whether it is nil.  */
-  Lisp_Object f_Vdeferred_action_list;
-
-  /* Function to call to handle deferred actions, when there are any.  */
-  Lisp_Object f_Vdeferred_action_function;
-
-  /* If this flag is non-nil, we check mouse_moved to see when the
-     mouse moves, and motion events will appear in the input stream.
-     Otherwise, mouse motion is ignored.  */
-  Lisp_Object f_do_mouse_tracking;
-
-  /* List of absolute timers.  Appears in order of next scheduled event.  */
-  Lisp_Object f_Vtimer_list;
-
-  /* List of idle time timers.  Appears in order of next scheduled event.  */
-  Lisp_Object f_Vtimer_idle_list;
-
-  /* After a command is executed, if point is moved into a region that
-     has specific properties (e.g. composition, display), we adjust
-     point to the boundary of the region.  But, if a command sets this
-     variable to non-nil, we suppress this point adjustment.  This
-     variable is set to nil before reading a command.  */
-  Lisp_Object f_Vdisable_point_adjustment;
-
-  /* If non-nil, always disable point adjustment.  */
-  Lisp_Object f_Vglobal_disable_point_adjustment;
-
-  /* If non-nil, events produced by disabled menu items and tool-bar
-     buttons are not ignored.  Help functions bind this to allow help on
-     those items and buttons.  */
-  Lisp_Object f_Venable_disabled_menus_and_buttons;
-
-  /* Nonzero means don't try to suspend even if the operating system seems
-     to support it.  */
-  int f_cannot_suspend;
-
-  /* Number of seconds between polling for input.  This is a Lisp
-     variable that can be bound.  */
-  EMACS_INT f_polling_period;
-
-  /* subprocesses */
-  Lisp_Object f_Vthrow_on_input;
-
-  /* The maximum time between clicks to make a double-click, or Qnil to
-     disable double-click detection, or Qt for no time limit.  */
-  Lisp_Object f_Vdouble_click_time;
-
-  /* Maximum number of pixels the mouse may be moved between clicks
-     to make a double-click.  */
-  EMACS_INT f_double_click_fuzz;
-
-  /* was MinibufLocalMap */
-  Lisp_Object f_Vminibuffer_local_map;
-
-  /* was MinibufLocalNSMap */
-  Lisp_Object f_Vminibuffer_local_ns_map;
-
-  /* was MinibufLocalCompletionMap */
-  Lisp_Object f_Vminibuffer_local_completion_map;
-
-  /* keymap used for minibuffers when doing completion in filenames */
-  Lisp_Object f_Vminibuffer_local_filename_completion_map;
-
-  /* keymap used for minibuffers when doing completion in filenames
-     with require-match*/
-  Lisp_Object f_Vminibuffer_local_filename_must_match_map;
-
-  /* was MinibufLocalMustMatchMap */
-  Lisp_Object f_Vminibuffer_local_must_match_map;
-
-  /* Alist of minor mode variables and keymaps.  */
-  Lisp_Object f_Vminor_mode_map_alist;
-
-  /* Alist of major-mode-specific overrides for
-     minor mode variables and keymaps.  */
-  Lisp_Object f_Vminor_mode_overriding_map_alist;
-
-  /* List of emulation mode keymap alists.  */
-  Lisp_Object f_Vemulation_mode_map_alists;
-
-  /* A list of all commands given new bindings since a certain time
-     when nil was stored here.
-     This is used to speed up recomputation of menu key equivalents
-     when Emacs starts up.   t means don't record anything here.  */
-  Lisp_Object f_Vdefine_key_rebound_commands;
-
-  Lisp_Object f_Vwhere_is_preferred_modifier;
-
-  Lisp_Object f_Vvalues;
-  Lisp_Object f_Vstandard_input;
-  Lisp_Object f_Vafter_load_alist;
-
-  Lisp_Object f_Veval_buffer_list;
-
-  /* non-zero if inside `load' */
-  int f_load_in_progress;
-
-  /* Directory in which the sources were found.  */
-  Lisp_Object f_Vsource_directory;
-
-  /* Search path and suffixes for files to be loaded. */
-  Lisp_Object f_Vload_path;
-  Lisp_Object f_Vload_suffixes;
-  Lisp_Object f_Vload_file_rep_suffixes;
-
-  /* File name of user's init file.  */
-  Lisp_Object f_Vuser_init_file;
-
-  /* This is the user-visible association list that maps features to
-     lists of defs in their load files. */
-  Lisp_Object f_Vload_history;
-
-  /* This is used to build the load history. */
-  Lisp_Object f_Vcurrent_load_list;
-
-  /* List of files that were preloaded.  */
-  Lisp_Object f_Vpreloaded_file_list;
-
-  /* Name of file actually being read by `load'.  */
-  Lisp_Object f_Vload_file_name;
-
-  /* Function to use for reading, in `load' and friends.  */
-  Lisp_Object f_Vload_read_function;
-
-  /* Non-nil means read recursive structures using #n= and #n# syntax.  */
-  Lisp_Object f_Vread_circle;
-
-  /* Nonzero means load should forcibly load all dynamic doc strings.  */
-  int f_load_force_doc_strings;
-
-  /* Nonzero means read should convert strings to unibyte.  */
-  int f_load_convert_to_unibyte;
-
-  /* Function to use for loading an Emacs Lisp source file (not
-     compiled) instead of readevalloop.  */
-  Lisp_Object f_Vload_source_file_function;
-
-  /* List of all DEFVAR_BOOL variables.  Used by the byte optimizer.  */
-  Lisp_Object f_Vbyte_boolean_vars;
-
-  /* Whether or not to add a `read-positions' property to symbols
-     read. */
-  Lisp_Object f_Vread_with_symbol_positions;
-
-  /* List of (SYMBOL . POSITION) accumulated so far. */
-  Lisp_Object f_Vread_symbol_positions_list;
-
-  Lisp_Object f_Vold_style_backquotes;
-
-  /* Non-zero means load dangerous compiled Lisp files.  */
-  int f_load_dangerous_libraries;
-
-  /* Non-zero means force printing messages when loading Lisp files.  */
-  int f_force_load_messages;
-
-  /* A regular expression used to detect files compiled with Emacs.  */
-  Lisp_Object f_Vbytecomp_version_regexp;
-
-  Lisp_Object f_Vobarray;
-
-  /* Normal hook run whenever a keyboard macro terminates.  */
-  Lisp_Object f_Vkbd_macro_termination_hook;
-
-  /* Kbd macro currently being executed (a string or vector).  */
-  Lisp_Object f_Vexecuting_kbd_macro;
-
-  /* Index of next character to fetch from that macro.  */
-  EMACS_INT f_executing_kbd_macro_index;
-
-  /* Nonzero means enable debugging checks on byte/char correspondences.  */
-  int f_byte_debug_flag;
-
-  Lisp_Object f_Vhistory_length;
-
-  /* No duplicates in history.  */
-  int f_history_delete_duplicates;
-
-  /* Non-nil means add new input to history.  */
-  Lisp_Object f_Vhistory_add_new_input;
-
-  /* Nonzero means let functions called when within a minibuffer
-     invoke recursive minibuffers (to read arguments, or whatever) */
-  int f_enable_recursive_minibuffers;
-
-  /* Nonzero means don't ignore text properties
-     in Fread_from_minibuffer.  */
-  int f_minibuffer_allow_text_properties;
-
-  /* help-form is bound to this while in the minibuffer.  */
-  Lisp_Object f_Vminibuffer_help_form;
-
-  /* Variable which is the history list to add minibuffer values to.  */
-  Lisp_Object f_Vminibuffer_history_variable;
-
-  /* Current position in the history list (adjusted by M-n and M-p).  */
-  Lisp_Object f_Vminibuffer_history_position;
-
-  /* Text properties that are added to minibuffer prompts.
-     These are in addition to the basic `field' property, and stickiness
-     properties.  */
-  Lisp_Object f_Vminibuffer_prompt_properties;
-
-  Lisp_Object f_Vminibuffer_setup_hook;
-
-  Lisp_Object f_Vminibuffer_exit_hook;
-
-  Lisp_Object f_Vread_expression_history;
-
-  /* Function to call to read a buffer name.  */
-  Lisp_Object f_Vread_buffer_function;
-
-  /* Nonzero means completion ignores case.  */
-  int f_completion_ignore_case;
-
-  int f_read_buffer_completion_ignore_case;
-
-  /* List of regexps that should restrict possible completions.  */
-  Lisp_Object f_Vcompletion_regexp_list;
-
-  /* Nonzero means raise the minibuffer frame when the minibuffer
-     is entered.  */
-  int f_minibuffer_auto_raise;
-
-  /* Keymap for reading expressions.  */
-  Lisp_Object f_Vread_expression_map;
-
-  Lisp_Object f_Vminibuffer_completion_table;
-
-  Lisp_Object f_Vminibuffer_completion_predicate;
-
-  Lisp_Object f_Vminibuffer_completion_confirm;
-
-  Lisp_Object f_Vminibuffer_completing_file_name;
-
-  Lisp_Object f_Vdos_unsupported_char_glyph;
-
-  Lisp_Object f_Vstandard_output;
-
-  Lisp_Object f_Vfloat_output_format;
-
-  /* Maximum length of list to print in full; noninteger means
-     effectively infinity */
-  Lisp_Object f_Vprint_length;
-
-  /* Maximum depth of list to print in full; noninteger means
-     effectively infinity.  */
-  Lisp_Object f_Vprint_level;
-
-  /* Nonzero means print newlines in strings as \n.  */
-  int f_print_escape_newlines;
-
-  /* Nonzero means to print single-byte non-ascii characters in strings as
-     octal escapes.  */
-  int f_print_escape_nonascii;
-
-  /* Nonzero means to print multibyte characters in strings as hex escapes.  */
-  int f_print_escape_multibyte;
-
-  /* Nonzero means print (quote foo) forms as 'foo, etc.  */
-  int f_print_quoted;
-
-  /* Non-nil means print #: before uninterned symbols.  */
-  Lisp_Object f_Vprint_gensym;
-
-  /* Non-nil means print recursive structures using #n= and #n# syntax.  */
-  Lisp_Object f_Vprint_circle;
-
-  /* Non-nil means keep continuous number for #n= and #n# syntax
-     between several print functions.  */
-  Lisp_Object f_Vprint_continuous_numbering;
-
-  Lisp_Object f_Vprint_number_table;
-
-  /* A flag to control printing of `charset' text property.
-     The default value is Qdefault. */
-  Lisp_Object f_Vprint_charset_text_property;
-
-  /* Nonzero means delete a process right away if it exits.  */
-  int f_delete_exited_processes;
-
-  /* t means use pty, nil means use a pipe,
-     maybe other values to come.  */
-  Lisp_Object f_Vprocess_connection_type;
-
-  /* Non-nil means to delay reading process output to improve buffering.
-     A value of t means that delay is reset after each send, any other
-     non-nil value does not reset the delay.  A value of nil disables
-     adaptive read buffering completely.  */
-  Lisp_Object f_Vprocess_adaptive_read_buffering;
-
-  Lisp_Object f_Vsearch_spaces_regexp;
-
-  /* If non-nil, the match data will not be changed during call to
-     searching or matching functions.  This variable is for internal use
-     only.  */
-  Lisp_Object f_Vinhibit_changing_match_data;
-
-  int f_words_include_escapes;
-
-  int f_parse_sexp_lookup_properties;
-
-  /* Nonzero means `scan-sexps' treat all multibyte characters as symbol.  */
-  int f_multibyte_syntax_as_symbol;
-
-  /* Non-zero means an open parenthesis in column 0 is always considered
-     to be the start of a defun.  Zero means an open parenthesis in
-     column 0 has no special meaning.  */
-  int f_open_paren_in_column_0_is_defun_start;
-
-  int f_parse_sexp_ignore_comments;
-
-  /* Char-table of functions that find the next or previous word
-     boundary.  */
-  Lisp_Object f_Vfind_word_boundary_function_table;
-
-  /* If true, use "vs", otherwise use "ve" to make the cursor visible.  */
-  int f_visible_cursor;
-
-  /* Functions to call after suspending a tty. */
-  Lisp_Object f_Vsuspend_tty_functions;
-
-  /* Functions to call after resuming a tty. */
-  Lisp_Object f_Vresume_tty_functions;
-
-  /* Nonzero means no need to redraw the entire frame on resuming a
-     suspended Emacs.  This is useful on terminals with multiple
-     pages, where one page is used for Emacs and another for all
-     else. */
-  int f_no_redraw_on_reenter;
-
-  /* Provided for lisp packages.  */
-  int f_system_uses_terminfo;
-
-  /* Function to use to ring the bell.  */
-  Lisp_Object f_Vring_bell_function;
-
-  Lisp_Object f_Vdelete_terminal_functions;
-
-  Lisp_Object f_Vinhibit_point_motion_hooks;
-
-  Lisp_Object f_Vdefault_text_properties;
-
-  Lisp_Object f_Vchar_property_alias_alist;
-
-  Lisp_Object f_Vtext_property_default_nonsticky;
-
-  /* Limits controlling how much undo information to keep.  */
-  EMACS_INT f_undo_limit;
-
-  EMACS_INT f_undo_strong_limit;
-
-  Lisp_Object f_Vundo_outer_limit;
-
-  /* Function to call when undo_outer_limit is exceeded.  */
-  Lisp_Object f_Vundo_outer_limit_function;
-
-  /* Nonzero means do not record point in record_point.  */
-  int f_undo_inhibit_record_point;
-
-  /* Coding system for communicating with other Windows programs via the
-     clipboard.  */
-  Lisp_Object f_Vselection_coding_system;
-
-  /* Coding system for the next communicating with other Windows programs.  */
-  Lisp_Object f_Vnext_selection_coding_system;
-
-  /* Determine whether to make frame dimensions match the screen buffer,
-     or the current window size.  The former is desirable when running
-     over telnet, while the latter is more useful when working directly at
-     the console with a large scroll-back buffer.  */
-  int f_w32_use_full_screen_buffer;
-
-  /* The colormap for converting color names to RGB values */
-  Lisp_Object f_Vw32_color_map;
-
-  /* Non nil if alt key presses are passed on to Windows.  */
-  Lisp_Object f_Vw32_pass_alt_to_system;
-
-  /* Non nil if alt key is translated to meta_modifier, nil if it is translated
-     to alt_modifier.  */
-  Lisp_Object f_Vw32_alt_is_meta;
-
-  /* If non-zero, the windows virtual key code for an alternative quit key. */
-  int f_w32_quit_key;
-
-  /* Non nil if left window key events are passed on to Windows (this only
-     affects whether "tapping" the key opens the Start menu).  */
-  Lisp_Object f_Vw32_pass_lwindow_to_system;
-
-  /* Non nil if right window key events are passed on to Windows (this
-     only affects whether "tapping" the key opens the Start menu).  */
-  Lisp_Object f_Vw32_pass_rwindow_to_system;
-
-  /* Virtual key code used to generate "phantom" key presses in order
-     to stop system from acting on Windows key events.  */
-  Lisp_Object f_Vw32_phantom_key_code;
-
-  /* Modifier associated with the left "Windows" key, or nil to act as a
-     normal key.  */
-  Lisp_Object f_Vw32_lwindow_modifier;
-
-  /* Modifier associated with the right "Windows" key, or nil to act as a
-     normal key.  */
-  Lisp_Object f_Vw32_rwindow_modifier;
-
-  /* Modifier associated with the "Apps" key, or nil to act as a normal
-     key.  */
-  Lisp_Object f_Vw32_apps_modifier;
-
-  /* Value is nil if Num Lock acts as a function key.  */
-  Lisp_Object f_Vw32_enable_num_lock;
-
-  /* Value is nil if Caps Lock acts as a function key.  */
-  Lisp_Object f_Vw32_enable_caps_lock;
-
-  /* Modifier associated with Scroll Lock, or nil to act as a normal key.  */
-  Lisp_Object f_Vw32_scroll_lock_modifier;
-
-  /* Switch to control whether we inhibit requests for synthesized bold
-     and italic versions of fonts.  */
-  int f_w32_enable_synthesized_fonts;
-
-  /* Enable palette management. */
-  Lisp_Object f_Vw32_enable_palette;
-
-  /* Control how close left/right button down events must be to
-     be converted to a middle button down event. */
-  int f_w32_mouse_button_tolerance;
-
-  /* Minimum interval between mouse movement (and scroll bar drag)
-     events that are passed on to the event loop. */
-  int f_w32_mouse_move_interval;
-
-  /* Flag to indicate if XBUTTON events should be passed on to Windows.  */
-  int f_w32_pass_extra_mouse_buttons_to_system;
-
-  /* Flag to indicate if media keys should be passed on to Windows.  */
-  int f_w32_pass_multimedia_buttons_to_system;
-
-  /* Non nil if no window manager is in use.  */
-  Lisp_Object f_Vx_no_window_manager;
-
-  /* The background and shape of the mouse pointer, and shape when not
-     over text or in the modeline.  */
-  Lisp_Object f_Vx_pointer_shape;
-  Lisp_Object f_Vx_nontext_pointer_shape;
-  Lisp_Object f_Vx_mode_pointer_shape;
-
-  /* TODO: Mouse cursor customization.  */
-  Lisp_Object f_Vx_hourglass_pointer_shape;
-  Lisp_Object f_Vx_window_horizontal_drag_shape;
-
-  /* The shape when over mouse-sensitive text.  */
-  Lisp_Object f_Vx_sensitive_text_pointer_shape;
-
-  /* Color of chars displayed in cursor box.  */
-  Lisp_Object f_Vx_cursor_fore_pixel;
-
-  /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
-  Lisp_Object f_Vx_pixel_size_width_font_regexp;
-
-  /* Alist of bdf fonts and the files that define them.  */
-  Lisp_Object f_Vw32_bdf_filename_alist;
-
-  /* A flag to control whether fonts are matched strictly or not.  */
-  int f_w32_strict_fontnames;
-
-  /* A flag to control whether we should only repaint if GetUpdateRect
-     indicates there is an update region.  */
-  int f_w32_strict_painting;
-
-  /* The ANSI codepage.  */
-  int f_w32_ansi_code_page;
-
-  /* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
-  Lisp_Object f_Vx_max_tooltip_size;
-
-  /* Associative list linking character set strings to Windows codepages. */
-  Lisp_Object f_Vw32_charset_info_alist;
-
-  /* Control whether spawnve quotes arguments as necessary to ensure
-     correct parsing by child process.  Because not all uses of spawnve
-     are careful about constructing argv arrays, we make this behavior
-     conditional (off by default). */
-  Lisp_Object f_Vw32_quote_process_args;
-
-  /* Control whether create_child causes the process' window to be
-     hidden.  The default is nil. */
-  Lisp_Object f_Vw32_start_process_show_window;
-
-  /* Control whether create_child causes the process to inherit Emacs'
-     console window, or be given a new one of its own.  The default is
-     nil, to allow multiple DOS programs to run on Win95.  Having separate
-     consoles also allows Emacs to cleanly terminate process groups.  */
-  Lisp_Object f_Vw32_start_process_share_console;
-
-  /* Control whether create_child cause the process to inherit Emacs'
-     error mode setting.  The default is t, to minimize the possibility of
-     subprocesses blocking when accessing unmounted drives.  */
-  Lisp_Object f_Vw32_start_process_inherit_error_mode;
-
-  /* Time to sleep before reading from a subprocess output pipe - this
-     avoids the inefficiency of frequently reading small amounts of data.
-     This is primarily necessary for handling DOS processes on Windows 95,
-     but is useful for W32 processes on both Windows 95 and NT as well.  */
-  int f_w32_pipe_read_delay;
-
-  /* Control conversion of upper case file names to lower case.
-     nil means no, t means yes. */
-  Lisp_Object f_Vw32_downcase_file_names;
-
-  /* Control whether stat() attempts to generate fake but hopefully
-     "accurate" inode values, by hashing the absolute truenames of files.
-     This should detect aliasing between long and short names, but still
-     allows the possibility of hash collisions.  */
-  Lisp_Object f_Vw32_generate_fake_inodes;
-
-  /* Control whether stat() attempts to determine file type and link count
-     exactly, at the expense of slower operation.  Since true hard links
-     are supported on NTFS volumes, this is only relevant on NT.  */
-  Lisp_Object f_Vw32_get_true_file_attributes;
-
-  /* Coding system for communicating with other programs via the
-     clipboard.  */
-
-  /* Coding system for the next communication with other programs.  */
-
-  /* Non-nil means Emacs uses toolkit scroll bars.  */
-  Lisp_Object f_Vx_toolkit_scroll_bars;
-
-  /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
-  int f_x_use_underline_position_properties;
-
-  /* Non-zero means to draw the underline at the same place as the descent line.  */
-  int f_x_underline_at_descent_line;
-
-  int f_w32_use_visible_system_caret;
-
-  int f_w32_num_mouse_buttons;
-
-  Lisp_Object f_Vw32_swap_mouse_buttons;
-
-  /* Control whether x_raise_frame also sets input focus.  */
-  Lisp_Object f_Vw32_grab_focus_on_raise;
-
-  /* Control whether Caps Lock affects non-ascii characters.  */
-  Lisp_Object f_Vw32_capslock_is_shiftlock;
-
-  /* Control whether right-alt and left-ctrl should be recognized as AltGr.  */
-  Lisp_Object f_Vw32_recognize_altgr;
-
-  /* Non-nil means it is the window for C-M-v to scroll
-     when the mini-buffer is selected.  */
-  Lisp_Object f_Vminibuf_scroll_window;
-
-  /* Non-nil means this is the buffer whose window C-M-v should scroll.  */
-  Lisp_Object f_Vother_window_scroll_buffer;
-
-  /* Non-nil means it's function to call to display temp buffers.  */
-  Lisp_Object f_Vtemp_buffer_show_function;
-
-  /* Non-zero means line and page scrolling on tall lines (with images)
-     does partial scrolling by modifying window-vscroll.  */
-  int f_auto_window_vscroll_p;
-
-  /* Non-zero means to use mode-line-inactive face in all windows but the
-     selected-window and the minibuffer-scroll-window when the
-     minibuffer is active.  */
-  int f_mode_line_in_non_selected_windows;
-
-  /* If a window gets smaller than either of these, it is removed. */
-  EMACS_INT f_window_min_height;
-
-  EMACS_INT f_window_min_width;
-
-  /* Number of lines of continuity in scrolling by screenfuls.  */
-  EMACS_INT f_next_screen_context_lines;
-
-  Lisp_Object f_Vwindow_configuration_change_hook;
-
-  /* Non-nil means scroll commands try to put point
-     at the same screen height as previously.  */
-  Lisp_Object f_Vscroll_preserve_screen_position;
-
-  /* Non-nil means that text is inserted before window's markers.  */
-  Lisp_Object f_Vwindow_point_insertion_type;
-
-  /* If non-nil, then the `recenter' command with a nil argument
-     the entire frame to be redrawn; the special value `tty' causes the
-     frame to be redrawn only if it is a tty frame.  */
-  Lisp_Object f_Vrecenter_redisplay;
-
-  Lisp_Object f_Vwindow_scroll_functions;
-
-  Lisp_Object f_Vwindow_text_change_functions;
-
-  Lisp_Object f_Vredisplay_end_trigger_functions;
-
-  /* Functions called to fontify regions of text.  */
-  Lisp_Object f_Vfontification_functions;
-
-  /* Non-nil means automatically select any window when the mouse
-     cursor moves into it.  */
-  Lisp_Object f_Vmouse_autoselect_window;
-
-  Lisp_Object f_Vwrap_prefix;
-
-  Lisp_Object f_Vline_prefix;
-
-  /* Non-zero means draw tool bar buttons raised when the mouse moves
-     over them.  */
-  int f_auto_raise_tool_bar_buttons_p;
-
-  /* Non-zero means to reposition window if cursor line is only partially visible.  */
-  int f_make_cursor_line_fully_visible_p;
-
-  /* Margin below tool bar in pixels.  0 or nil means no margin.
-     If value is `internal-border-width' or `border-width',
-     the corresponding frame parameter is used.  */
-  Lisp_Object f_Vtool_bar_border;
-
-  /* Margin around tool bar buttons in pixels.  */
-  Lisp_Object f_Vtool_bar_button_margin;
-
-  /* Thickness of shadow to draw around tool bar buttons.  */
-  EMACS_INT f_tool_bar_button_relief;
-
-  /* Non-nil means automatically resize tool-bars so that all tool-bar
-     items are visible, and no blank lines remain.
-
-     If value is `grow-only', only make tool-bar bigger.  */
-  Lisp_Object f_Vauto_resize_tool_bars;
-
-  /* Type of tool bar.  Can be symbols image, text, both or both-hroiz.  */
-  Lisp_Object f_Vtool_bar_style;
-
-  /* Maximum number of characters a label can have to be shown.  */
-  EMACS_INT f_tool_bar_max_label_size;
-
-  /* Non-zero means draw block and hollow cursor as wide as the glyph
-     under it.  For example, if a block cursor is over a tab, it will be
-     drawn as wide as that tab on the display.  */
-  int f_x_stretch_cursor_p;
-
-  Lisp_Object f_Vinhibit_redisplay;
-
-  /* Non-zero means Lisp evaluation during redisplay is inhibited.  */
-  int f_inhibit_eval_during_redisplay;
-
-  /* Symbols used in text property values.  */
-  Lisp_Object f_Vdisplay_pixels_per_inch;
-
-  /* Non-nil means highlight trailing whitespace.  */
-  Lisp_Object f_Vshow_trailing_whitespace;
-
-  /* Non-nil means escape non-break space and hyphens.  */
-  Lisp_Object f_Vnobreak_char_display;
-
-  /* Non-nil means show the text cursor in void text areas
-     i.e. in blank areas after eol and eob.  This used to be
-     the default in 21.3.  */
-  Lisp_Object f_Vvoid_text_area_pointer;
-
-  /* Nonzero means truncate lines in all windows less wide than the
-     frame.  */
-  Lisp_Object f_Vtruncate_partial_width_windows;
-
-  /* A flag to control how to display unibyte 8-bit character.  */
-  int f_unibyte_display_via_language_environment;
-
-  /* Nonzero means we have more than one non-mini-buffer-only frame.
-     Not guaranteed to be accurate except while parsing
-     frame-title-format.  */
-  int f_multiple_frames;
-
-  Lisp_Object f_Vglobal_mode_string;
-
-  /* List of variables (symbols) which hold markers for overlay arrows.
-     The symbols on this list are examined during redisplay to determine
-     where to display overlay arrows.  */
-  Lisp_Object f_Voverlay_arrow_variable_list;
-
-  /* Marker for where to display an arrow on top of the buffer text.  */
-  Lisp_Object f_Voverlay_arrow_position;
-
-  /* String to display for the arrow.  Only used on terminal frames.  */
-  Lisp_Object f_Voverlay_arrow_string;
-
-  /* Like mode-line-format, but for the title bar on a visible frame.  */
-  Lisp_Object f_Vframe_title_format;
-
-  /* Like mode-line-format, but for the title bar on an iconified frame.  */
-  Lisp_Object f_Vicon_title_format;
-
-  /* List of functions to call when a window's size changes.  These
-     functions get one arg, a frame on which one or more windows' sizes
-     have changed.  */
-  Lisp_Object f_Vwindow_size_change_functions;
-
-  Lisp_Object f_Vmenu_bar_update_hook;
-
-  /* Nonzero means highlight the region even in nonselected windows.  */
-  int f_highlight_nonselected_windows;
-
-  /* If cursor motion alone moves point off frame, try scrolling this
-     many lines up or down if that will bring it back.  */
-  EMACS_INT f_emacs_scroll_step;
-
-  /* Nonzero means scroll just far enough to bring point back on the
-     screen, when appropriate.  */
-  EMACS_INT f_scroll_conservatively;
-
-  /* Recenter the window whenever point gets within this many lines of
-     the top or bottom of the window.  This value is translated into a
-     pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
-     that there is really a fixed pixel height scroll margin.  */
-  EMACS_INT f_scroll_margin;
-
-  /* Zero means display the mode-line/header-line/menu-bar in the default face
-     (this slightly odd definition is for compatibility with previous versions
-     of emacs), non-zero means display them using their respective faces.
-
-     This variable is deprecated.  */
-  int f_mode_line_inverse_video;
-
-  /* Maximum buffer size for which to display line numbers.  */
-  Lisp_Object f_Vline_number_display_limit;
-
-  /* Line width to consider when repositioning for line number display.  */
-  EMACS_INT f_line_number_display_limit_width;
-
-  /* Number of lines to keep in the message log buffer.  t means
-     infinite.  nil means don't log at all.  */
-  Lisp_Object f_Vmessage_log_max;
-
-  int f_inhibit_menubar_update;
-
-  /* When evaluating expressions from menu bar items (enable conditions,
-     for instance), this is the frame they are being processed for.  */
-  Lisp_Object f_Vmenu_updating_frame;
-
-  /* Maximum height for resizing mini-windows.  Either a float
-     specifying a fraction of the available height, or an integer
-     specifying a number of lines.  */
-  Lisp_Object f_Vmax_mini_window_height;
-
-  /* Non-zero means messages should be displayed with truncated
-     lines instead of being continued.  */
-  int f_message_truncate_lines;
-
-  /* How to blink the default frame cursor off.  */
-  Lisp_Object f_Vblink_cursor_alist;
-
-  /* Variables to turn off display optimizations from Lisp.  */
-  int f_inhibit_try_window_id;
-  int f_inhibit_try_window_reusing;
-
-  int f_inhibit_try_cursor_movement;
-
-  /* Non-zero means automatically scroll windows horizontally to make
-     point visible.  */
-  int f_automatic_hscrolling_p;
-
-  /* How close to the margin can point get before the window is scrolled
-     horizontally.  */
-  EMACS_INT f_hscroll_margin;
-
-  /* How much to scroll horizontally when point is inside the above margin.  */
-  Lisp_Object f_Vhscroll_step;
-
-  /* The variable `resize-mini-windows'.  If nil, don't resize
-     mini-windows.  If t, always resize them to fit the text they
-     display.  If `grow-only', let mini-windows grow only until they
-     become empty.  */
-  Lisp_Object f_Vresize_mini_windows;
-
-  /* Space between overline and text. */
-  EMACS_INT f_overline_margin;
-
-  /* Require underline to be at least this many screen pixels below baseline
-     This to avoid underline "merging" with the base of letters at small
-     font sizes, particularly when x_use_underline_position_properties is on. */
-  EMACS_INT f_underline_minimum_offset;
-
-  /* Non-zero means don't free realized faces.  Bound while freeing
-     realized faces is dangerous because glyph matrices might still
-     reference them.  */
-  int f_inhibit_free_realized_faces;
-
-  /* Non-zero means we're allowed to display a hourglass pointer.  */
-  int f_display_hourglass_p;
-
-  /* Number of seconds to wait before displaying an hourglass cursor.  */
-  Lisp_Object f_Vhourglass_delay;
-
-  /* Char-table to control the display of glyphless characters.  */
-  Lisp_Object f_Vglyphless_char_display;
-
-  EMACS_INT f_debug_end_pos;
-
-  /* Default stipple pattern used on monochrome displays.  This stipple
-     pattern is used on monochrome displays instead of shades of gray
-     for a face background color.  See `set-face-stipple' for possible
-     values for this variable.  */
-  Lisp_Object f_Vface_default_stipple;
-
-  Lisp_Object f_Vscalable_fonts_allowed;
-
-  /* List of regular expressions that matches names of fonts to ignore. */
-  Lisp_Object f_Vface_ignored_fonts;
-
-  /* Alist of font name patterns vs the rescaling factor.  */
-  Lisp_Object f_Vface_font_rescale_alist;
-
-  /* Maximum number of fonts to consider in font_list.  If not an
-     integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead.  */
-  Lisp_Object f_Vfont_list_limit;
-
-  /* Alist of global face definitions.  Each element is of the form
-     (FACE . LFACE) where FACE is a symbol naming a face and LFACE
-     is a Lisp vector of face attributes.  These faces are used
-     to initialize faces for new frames.  */
-  Lisp_Object f_Vface_new_frame_defaults;
-
-  /* Alist of face remappings.  Each element is of the form:
-     (FACE REPLACEMENT...) which causes display of the face FACE to use
-     REPLACEMENT... instead.  REPLACEMENT... is interpreted the same way
-     the value of a `face' text property is: it may be (1) A face name,
-     (2) A list of face names, (3) A property-list of face attribute/value
-     pairs, or (4) A list of face names intermixed with lists containing
-     face attribute/value pairs.
-
-     Multiple entries in REPLACEMENT... are merged together to form the final
-     result, with faces or attributes earlier in the list taking precedence
-     over those that are later.
-
-     Face-name remapping cycles are suppressed; recursive references use
-     the underlying face instead of the remapped face.  */
-  Lisp_Object f_Vface_remapping_alist;
-
-  /* An alist of defined terminal colors and their RGB values.  */
-  Lisp_Object f_Vtty_defined_color_alist;
-
-  /* LessTif/Motif version info.  */
-  Lisp_Object f_Vmotif_version_string;
-
-  /* GTK+ version info */
-  Lisp_Object f_Vgtk_version_string;
-
-  /* Non-zero means prompt with the old GTK file selection dialog.  */
-  int f_x_gtk_use_old_file_dialog;
-
-  /* If non-zero, by default show hidden files in the GTK file chooser.  */
-  int f_x_gtk_show_hidden_files;
-
-  /* If non-zero, don't show additional help text in the GTK file chooser.  */
-  int f_x_gtk_file_dialog_help_text;
-
-  /* If non-zero, don't collapse to tool bar when it is detached.  */
-  int f_x_gtk_whole_detached_tool_bar;
-
-  /* If non-zero, use Gtk+ tooltips.  */
-  int f_x_gtk_use_system_tooltips;
-
-  /* The background and shape of the mouse pointer, and shape when not
-     over text or in the modeline.  */
-
-  /* The shape when over mouse-sensitive text.  */
-
-  /* If non-nil, the pointer shape to indicate that windows can be
-     dragged horizontally.  */
-
-  /* Color of chars displayed in cursor box.  */
-
-  /* Non nil if no window manager is in use.  */
-
-  /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
-
-  /* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
-
-  Lisp_Object f_Vx_lost_selection_functions;
-
-  Lisp_Object f_Vx_sent_selection_functions;
-
-  /* This is an alist whose CARs are selection-types (whose names are the same
-     as the names of X Atoms) and whose CDRs are the names of Lisp functions to
-     call to convert the given Emacs selection value to a string representing
-     the given selection type.  This is for Lisp-level extension of the emacs
-     selection handling.  */
-  Lisp_Object f_Vselection_converter_alist;
-
-  /* If the selection owner takes too long to reply to a selection request,
-     we give up on it.  This is in milliseconds (0 = no timeout.)  */
-  EMACS_INT f_x_selection_timeout;
-
-  int f_use_system_font;
-
-  Lisp_Object f_Vxft_settings;
-
-  /* The client session id for this session as a lisp object.  */
-  Lisp_Object f_Vx_session_id;
-
-  /* The id we had the previous session.  This is only available if we
-     have been started by the session manager with SMID_OPT.  */
-  Lisp_Object f_Vx_session_previous_id;
-
-  /* Non-nil means Emacs uses toolkit scroll bars.  */
-
-  /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
-
-  /* Non-zero means to draw the underline at the same place as the descent line.  */
-
-  /* Non-zero means to not move point as a result of clicking on a
-     frame to focus it (when focus-follows-mouse is nil).  */
-  int f_x_mouse_click_focus_ignore_position;
-
-  /* The keysyms to use for the various modifiers.  */
-  Lisp_Object f_Vx_alt_keysym;
-  Lisp_Object f_Vx_hyper_keysym;
-  Lisp_Object f_Vx_meta_keysym;
-  Lisp_Object f_Vx_super_keysym;
-
-  Lisp_Object f_Vx_keysym_table;
-
-  /* Lisp communications */
-  Lisp_Object f_ns_input_file, f_ns_input_font, f_ns_input_fontsize,
-    f_ns_input_line;
-  Lisp_Object f_ns_input_color, f_ns_input_text, f_ns_working_text;
-  Lisp_Object f_ns_input_spi_name, f_ns_input_spi_arg;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Alternate modifier.  May be Qnone or any of the modifier lisp symbols.
-  */
-  Lisp_Object f_ns_alternate_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the right Alternate modifier.  Has same values as ns_alternate_modifier
-     plus the value Qleft which means whatever value ns_alternate_modifier has.
-  */
-  Lisp_Object f_ns_right_alternate_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Command modifier.  May be any of the modifier lisp symbols. */
-  Lisp_Object f_ns_command_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the right Command modifier.  Has same values as ns_command_modifier plus
-     the value Qleft which means whatever value ns_command_modifier has.  */
-  Lisp_Object f_ns_right_command_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Control modifier.  May be any of the modifier lisp symbols. */
-  Lisp_Object f_ns_control_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the right Control modifier.  Has same values as ns_control_modifier plus
-     the value Qleft which means whatever value ns_control_modifier has.  */
-  Lisp_Object f_ns_right_control_modifier;
-
-  /* Specifies which emacs modifier should be generated when NS receives
-     the Function modifier (laptops).  May be any of the modifier lisp symbols.
-  */
-  Lisp_Object f_ns_function_modifier;
-
-  /* Control via default 'GSFontAntiAlias' on OS X and GNUstep. */
-  Lisp_Object f_ns_antialias_text;
-
-  /* Confirm on exit. */
-  Lisp_Object f_ns_confirm_quit;
-
-  /* Alist of elements (REGEXP . IMAGE) for images of icons associated
-     to frames.*/
-  Lisp_Object f_Vns_icon_type_alist;
-
-  /* Toolkit version support. */
-  Lisp_Object f_Vns_version_string;
-
-  Lisp_Object f_Vns_sent_selection_hooks;
-  Lisp_Object f_Vns_lost_selection_hooks;
-
-  /* This is an association list whose elements are of the form
-       ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
-     SELECTION-NAME is a lisp symbol, whose name is the name of an X Atom.
-     SELECTION-VALUE is the value that emacs owns for that selection.
-       It may be any kind of Lisp object.
-     SELECTION-TIMESTAMP is the time at which emacs began owning this
-       selection, as a cons of two 16-bit numbers (making a 32 bit time.)
-     FRAME is the frame for which we made the selection.
-     If there is an entry in this alist, then it can be assumed that Emacs owns
-      that selection.
-     The only (eq) parts of this list that are visible from Lisp are the
-      selection-values.  */
-  Lisp_Object f_Vselection_alist;
-
-  Lisp_Object f_Vns_reg_to_script;
-
-
-};
-
-extern struct emacs_globals globals;
-
-#define Vafter_change_functions \
-    globals.f_Vafter_change_functions
-#define Vafter_init_time \
-    globals.f_Vafter_init_time
-#define Vafter_insert_file_functions \
-    globals.f_Vafter_insert_file_functions
-#define Vafter_load_alist \
-    globals.f_Vafter_load_alist
-#define Valternate_fontname_alist \
-    globals.f_Valternate_fontname_alist
-#define Vauto_composition_function \
-    globals.f_Vauto_composition_function
-#define Vauto_composition_mode \
-    globals.f_Vauto_composition_mode
-#define Vauto_fill_chars \
-    globals.f_Vauto_fill_chars
-#define Vauto_resize_tool_bars \
-    globals.f_Vauto_resize_tool_bars
-#define Vauto_save_include_big_deletions \
-    globals.f_Vauto_save_include_big_deletions
-#define Vauto_save_list_file_name \
-    globals.f_Vauto_save_list_file_name
-#define Vauto_save_timeout \
-    globals.f_Vauto_save_timeout
-#define Vauto_save_visited_file_name \
-    globals.f_Vauto_save_visited_file_name
-#define Vbefore_change_functions \
-    globals.f_Vbefore_change_functions
-#define Vbefore_init_time \
-    globals.f_Vbefore_init_time
-#define Vblink_cursor_alist \
-    globals.f_Vblink_cursor_alist
-#define Vbuffer_access_fontified_property \
-    globals.f_Vbuffer_access_fontified_property
-#define Vbuffer_access_fontify_functions \
-    globals.f_Vbuffer_access_fontify_functions
-#define Vbuild_files \
-    globals.f_Vbuild_files
-#define Vbyte_boolean_vars \
-    globals.f_Vbyte_boolean_vars
-#define Vbyte_code_meter \
-    globals.f_Vbyte_code_meter
-#define Vbytecomp_version_regexp \
-    globals.f_Vbytecomp_version_regexp
-#define Vchange_major_mode_hook \
-    globals.f_Vchange_major_mode_hook
-#define Vchar_direction_table \
-    globals.f_Vchar_direction_table
-#define Vchar_property_alias_alist \
-    globals.f_Vchar_property_alias_alist
-#define Vchar_script_table \
-    globals.f_Vchar_script_table
-#define Vchar_width_table \
-    globals.f_Vchar_width_table
-#define Vcharset_list \
-    globals.f_Vcharset_list
-#define Vcharset_map_path \
-    globals.f_Vcharset_map_path
-#define Vcharset_revision_table \
-    globals.f_Vcharset_revision_table
-#define Vcode_conversion_map_vector \
-    globals.f_Vcode_conversion_map_vector
-#define Vcoding_category_list \
-    globals.f_Vcoding_category_list
-#define Vcoding_system_alist \
-    globals.f_Vcoding_system_alist
-#define Vcoding_system_for_read \
-    globals.f_Vcoding_system_for_read
-#define Vcoding_system_for_write \
-    globals.f_Vcoding_system_for_write
-#define Vcoding_system_list \
-    globals.f_Vcoding_system_list
-#define Vcombine_after_change_calls \
-    globals.f_Vcombine_after_change_calls
-#define Vcommand_debug_status \
-    globals.f_Vcommand_debug_status
-#define Vcommand_error_function \
-    globals.f_Vcommand_error_function
-#define Vcommand_history \
-    globals.f_Vcommand_history
-#define Vcommand_hook_internal \
-    globals.f_Vcommand_hook_internal
-#define Vcommand_line_args \
-    globals.f_Vcommand_line_args
-#define Vcompletion_ignored_extensions \
-    globals.f_Vcompletion_ignored_extensions
-#define Vcompletion_regexp_list \
-    globals.f_Vcompletion_regexp_list
-#define Vcompose_chars_after_function \
-    globals.f_Vcompose_chars_after_function
-#define Vcomposition_function_table \
-    globals.f_Vcomposition_function_table
-#define Vconfigure_info_directory \
-    globals.f_Vconfigure_info_directory
-#define Vcurrent_iso639_language \
-    globals.f_Vcurrent_iso639_language
-#define Vcurrent_load_list \
-    globals.f_Vcurrent_load_list
-#define Vcurrent_prefix_arg \
-    globals.f_Vcurrent_prefix_arg
-#define Vdata_directory \
-    globals.f_Vdata_directory
-#define Vdbus_debug \
-    globals.f_Vdbus_debug
-#define Vdbus_registered_buses \
-    globals.f_Vdbus_registered_buses
-#define Vdbus_registered_objects_table \
-    globals.f_Vdbus_registered_objects_table
-#define Vdeactivate_mark \
-    globals.f_Vdeactivate_mark
-#define Vdebug_ignored_errors \
-    globals.f_Vdebug_ignored_errors
-#define Vdebug_on_error \
-    globals.f_Vdebug_on_error
-#define Vdebug_on_signal \
-    globals.f_Vdebug_on_signal
-#define Vdebugger \
-    globals.f_Vdebugger
-#define Vdefault_file_name_coding_system \
-    globals.f_Vdefault_file_name_coding_system
-#define Vdefault_frame_alist \
-    globals.f_Vdefault_frame_alist
-#define Vdefault_frame_scroll_bars \
-    globals.f_Vdefault_frame_scroll_bars
-#define Vdefault_process_coding_system \
-    globals.f_Vdefault_process_coding_system
-#define Vdefault_text_properties \
-    globals.f_Vdefault_text_properties
-#define Vdeferred_action_function \
-    globals.f_Vdeferred_action_function
-#define Vdeferred_action_list \
-    globals.f_Vdeferred_action_list
-#define Vdefine_key_rebound_commands \
-    globals.f_Vdefine_key_rebound_commands
-#define Vdelete_frame_functions \
-    globals.f_Vdelete_frame_functions
-#define Vdelete_terminal_functions \
-    globals.f_Vdelete_terminal_functions
-#define Vdisable_point_adjustment \
-    globals.f_Vdisable_point_adjustment
-#define Vdisplay_pixels_per_inch \
-    globals.f_Vdisplay_pixels_per_inch
-#define Vdoc_directory \
-    globals.f_Vdoc_directory
-#define Vdoc_file_name \
-    globals.f_Vdoc_file_name
-#define Vdos_display_scancodes \
-    globals.f_Vdos_display_scancodes
-#define Vdos_unsupported_char_glyph \
-    globals.f_Vdos_unsupported_char_glyph
-#define Vdos_version \
-    globals.f_Vdos_version
-#define Vdos_windows_version \
-    globals.f_Vdos_windows_version
-#define Vdouble_click_time \
-    globals.f_Vdouble_click_time
-#define Vdynamic_library_alist \
-    globals.f_Vdynamic_library_alist
-#define Vecho_keystrokes \
-    globals.f_Vecho_keystrokes
-#define Vemacs_copyright \
-    globals.f_Vemacs_copyright
-#define Vemacs_version \
-    globals.f_Vemacs_version
-#define Vemulation_mode_map_alists \
-    globals.f_Vemulation_mode_map_alists
-#define Venable_character_translation \
-    globals.f_Venable_character_translation
-#define Venable_disabled_menus_and_buttons \
-    globals.f_Venable_disabled_menus_and_buttons
-#define Veval_buffer_list \
-    globals.f_Veval_buffer_list
-#define Vexec_directory \
-    globals.f_Vexec_directory
-#define Vexec_path \
-    globals.f_Vexec_path
-#define Vexec_suffixes \
-    globals.f_Vexec_suffixes
-#define Vkbd_macro_termination_hook \
-    globals.f_Vkbd_macro_termination_hook
-#define Vexecuting_kbd_macro \
-    globals.f_Vexecuting_kbd_macro
-#define Vface_default_stipple \
-    globals.f_Vface_default_stipple
-#define Vface_font_rescale_alist \
-    globals.f_Vface_font_rescale_alist
-#define Vface_ignored_fonts \
-    globals.f_Vface_ignored_fonts
-#define Vface_new_frame_defaults \
-    globals.f_Vface_new_frame_defaults
-#define Vface_remapping_alist \
-    globals.f_Vface_remapping_alist
-#define Vfeatures \
-    globals.f_Vfeatures
-#define Vfile_coding_system_alist \
-    globals.f_Vfile_coding_system_alist
-#define Vfile_name_coding_system \
-    globals.f_Vfile_name_coding_system
-#define Vfile_name_handler_alist \
-    globals.f_Vfile_name_handler_alist
-#define Vfind_word_boundary_function_table \
-    globals.f_Vfind_word_boundary_function_table
-#define Vfirst_change_hook \
-    globals.f_Vfirst_change_hook
-#define Vfloat_output_format \
-    globals.f_Vfloat_output_format
-#define Vfont_ccl_encoder_alist \
-    globals.f_Vfont_ccl_encoder_alist
-#define Vfont_encoding_alist \
-    globals.f_Vfont_encoding_alist
-#define Vfont_encoding_charset_alist \
-    globals.f_Vfont_encoding_charset_alist
-#define Vfont_list_limit \
-    globals.f_Vfont_list_limit
-#define Vfont_log \
-    globals.f_Vfont_log
-#define Vfont_slant_table \
-    globals.f_Vfont_slant_table
-#define Vfont_weight_table \
-    globals.f_Vfont_weight_table
-#define Vfont_width_table \
-    globals.f_Vfont_width_table
-#define Vfontification_functions \
-    globals.f_Vfontification_functions
-#define Vfontset_alias_alist \
-    globals.f_Vfontset_alias_alist
-#define Vframe_alpha_lower_limit \
-    globals.f_Vframe_alpha_lower_limit
-#define Vframe_title_format \
-    globals.f_Vframe_title_format
-#define Vfringe_bitmaps \
-    globals.f_Vfringe_bitmaps
-#define Vfunction_key_map \
-    globals.f_Vfunction_key_map
-#define Vgc_cons_percentage \
-    globals.f_Vgc_cons_percentage
-#define Vgc_elapsed \
-    globals.f_Vgc_elapsed
-#define Vglobal_disable_point_adjustment \
-    globals.f_Vglobal_disable_point_adjustment
-#define Vglobal_mode_string \
-    globals.f_Vglobal_mode_string
-#define Vglyph_table \
-    globals.f_Vglyph_table
-#define Vglyphless_char_display \
-    globals.f_Vglyphless_char_display
-#define Vgtk_version_string \
-    globals.f_Vgtk_version_string
-#define Vhelp_char \
-    globals.f_Vhelp_char
-#define Vhelp_event_list \
-    globals.f_Vhelp_event_list
-#define Vhelp_form \
-    globals.f_Vhelp_form
-#define Vhistory_add_new_input \
-    globals.f_Vhistory_add_new_input
-#define Vhistory_length \
-    globals.f_Vhistory_length
-#define Vhourglass_delay \
-    globals.f_Vhourglass_delay
-#define Vhscroll_step \
-    globals.f_Vhscroll_step
-#define Vicon_title_format \
-    globals.f_Vicon_title_format
-#define Vignore_relative_composition \
-    globals.f_Vignore_relative_composition
-#define Vimage_cache_eviction_delay \
-    globals.f_Vimage_cache_eviction_delay
-#define Vimage_types \
-    globals.f_Vimage_types
-#define Vimagemagick_render_type \
-    globals.f_Vimagemagick_render_type
-#define Vinhibit_changing_match_data \
-    globals.f_Vinhibit_changing_match_data
-#define Vinhibit_field_text_motion \
-    globals.f_Vinhibit_field_text_motion
-#define Vinhibit_file_name_handlers \
-    globals.f_Vinhibit_file_name_handlers
-#define Vinhibit_file_name_operation \
-    globals.f_Vinhibit_file_name_operation
-#define Vinhibit_point_motion_hooks \
-    globals.f_Vinhibit_point_motion_hooks
-#define Vinhibit_quit \
-    globals.f_Vinhibit_quit
-#define Vinhibit_read_only \
-    globals.f_Vinhibit_read_only
-#define Vinhibit_redisplay \
-    globals.f_Vinhibit_redisplay
-#define Vinitial_environment \
-    globals.f_Vinitial_environment
-#define Vinitial_window_system \
-    globals.f_Vinitial_window_system
-#define Vinput_method_function \
-    globals.f_Vinput_method_function
-#define Vinput_method_previous_message \
-    globals.f_Vinput_method_previous_message
-#define Vinstallation_directory \
-    globals.f_Vinstallation_directory
-#define Vinvocation_directory \
-    globals.f_Vinvocation_directory
-#define Vinvocation_name \
-    globals.f_Vinvocation_name
-#define Vkey_translation_map \
-    globals.f_Vkey_translation_map
-#define Vkill_buffer_query_functions \
-    globals.f_Vkill_buffer_query_functions
-#define Vkill_emacs_hook \
-    globals.f_Vkill_emacs_hook
-#define Vlast_code_conversion_error \
-    globals.f_Vlast_code_conversion_error
-#define Vlast_coding_system_used \
-    globals.f_Vlast_coding_system_used
-#define Vlast_event_frame \
-    globals.f_Vlast_event_frame
-#define Vlatin_extra_code_table \
-    globals.f_Vlatin_extra_code_table
-#define Vline_number_display_limit \
-    globals.f_Vline_number_display_limit
-#define Vline_prefix \
-    globals.f_Vline_prefix
-#define Vload_file_name \
-    globals.f_Vload_file_name
-#define Vload_file_rep_suffixes \
-    globals.f_Vload_file_rep_suffixes
-#define Vload_history \
-    globals.f_Vload_history
-#define Vload_path \
-    globals.f_Vload_path
-#define Vload_read_function \
-    globals.f_Vload_read_function
-#define Vload_source_file_function \
-    globals.f_Vload_source_file_function
-#define Vload_suffixes \
-    globals.f_Vload_suffixes
-#define Vlocale_coding_system \
-    globals.f_Vlocale_coding_system
-#define Vlucid_menu_bar_dirty_flag \
-    globals.f_Vlucid_menu_bar_dirty_flag
-#define Vmacro_declaration_function \
-    globals.f_Vmacro_declaration_function
-#define Vmake_pointer_invisible \
-    globals.f_Vmake_pointer_invisible
-#define Vmark_even_if_inactive \
-    globals.f_Vmark_even_if_inactive
-#define Vmax_image_size \
-    globals.f_Vmax_image_size
-#define Vmax_mini_window_height \
-    globals.f_Vmax_mini_window_height
-#define Vmemory_full \
-    globals.f_Vmemory_full
-#define Vmemory_signal_data \
-    globals.f_Vmemory_signal_data
-#define Vmenu_bar_final_items \
-    globals.f_Vmenu_bar_final_items
-#define Vmenu_bar_mode \
-    globals.f_Vmenu_bar_mode
-#define Vmenu_bar_update_hook \
-    globals.f_Vmenu_bar_update_hook
-#define Vmenu_updating_frame \
-    globals.f_Vmenu_updating_frame
-#define Vmessage_log_max \
-    globals.f_Vmessage_log_max
-#define Vminibuf_scroll_window \
-    globals.f_Vminibuf_scroll_window
-#define Vminibuffer_completing_file_name \
-    globals.f_Vminibuffer_completing_file_name
-#define Vminibuffer_completion_confirm \
-    globals.f_Vminibuffer_completion_confirm
-#define Vminibuffer_completion_predicate \
-    globals.f_Vminibuffer_completion_predicate
-#define Vminibuffer_completion_table \
-    globals.f_Vminibuffer_completion_table
-#define Vminibuffer_exit_hook \
-    globals.f_Vminibuffer_exit_hook
-#define Vminibuffer_help_form \
-    globals.f_Vminibuffer_help_form
-#define Vminibuffer_history_position \
-    globals.f_Vminibuffer_history_position
-#define Vminibuffer_history_variable \
-    globals.f_Vminibuffer_history_variable
-#define Vminibuffer_local_completion_map \
-    globals.f_Vminibuffer_local_completion_map
-#define Vminibuffer_local_filename_completion_map \
-    globals.f_Vminibuffer_local_filename_completion_map
-#define Vminibuffer_local_filename_must_match_map \
-    globals.f_Vminibuffer_local_filename_must_match_map
-#define Vminibuffer_local_map \
-    globals.f_Vminibuffer_local_map
-#define Vminibuffer_local_must_match_map \
-    globals.f_Vminibuffer_local_must_match_map
-#define Vminibuffer_local_ns_map \
-    globals.f_Vminibuffer_local_ns_map
-#define Vminibuffer_message_timeout \
-    globals.f_Vminibuffer_message_timeout
-#define Vminibuffer_prompt_properties \
-    globals.f_Vminibuffer_prompt_properties
-#define Vminibuffer_setup_hook \
-    globals.f_Vminibuffer_setup_hook
-#define Vminor_mode_map_alist \
-    globals.f_Vminor_mode_map_alist
-#define Vminor_mode_overriding_map_alist \
-    globals.f_Vminor_mode_overriding_map_alist
-#define Vmost_negative_fixnum \
-    globals.f_Vmost_negative_fixnum
-#define Vmost_positive_fixnum \
-    globals.f_Vmost_positive_fixnum
-#define Vmotif_version_string \
-    globals.f_Vmotif_version_string
-#define Vmouse_autoselect_window \
-    globals.f_Vmouse_autoselect_window
-#define Vmouse_highlight \
-    globals.f_Vmouse_highlight
-#define Vmouse_leave_buffer_hook \
-    globals.f_Vmouse_leave_buffer_hook
-#define Vmouse_position_function \
-    globals.f_Vmouse_position_function
-#define Vnetwork_coding_system_alist \
-    globals.f_Vnetwork_coding_system_alist
-#define Vnext_selection_coding_system \
-    globals.f_Vnext_selection_coding_system
-#define Vnobreak_char_display \
-    globals.f_Vnobreak_char_display
-#define Vobarray \
-    globals.f_Vobarray
-#define Vold_style_backquotes \
-    globals.f_Vold_style_backquotes
-#define Voperating_system_release \
-    globals.f_Voperating_system_release
-#define Votf_script_alist \
-    globals.f_Votf_script_alist
-#define Vother_window_scroll_buffer \
-    globals.f_Vother_window_scroll_buffer
-#define Voverflow_newline_into_fringe \
-    globals.f_Voverflow_newline_into_fringe
-#define Voverlay_arrow_position \
-    globals.f_Voverlay_arrow_position
-#define Voverlay_arrow_string \
-    globals.f_Voverlay_arrow_string
-#define Voverlay_arrow_variable_list \
-    globals.f_Voverlay_arrow_variable_list
-#define Voverriding_local_map \
-    globals.f_Voverriding_local_map
-#define Voverriding_local_map_menu_flag \
-    globals.f_Voverriding_local_map_menu_flag
-#define Vpath_separator \
-    globals.f_Vpath_separator
-#define Vpost_command_hook \
-    globals.f_Vpost_command_hook
-#define Vpost_gc_hook \
-    globals.f_Vpost_gc_hook
-#define Vpost_self_insert_hook \
-    globals.f_Vpost_self_insert_hook
-#define Vpre_command_hook \
-    globals.f_Vpre_command_hook
-#define Vprefix_help_command \
-    globals.f_Vprefix_help_command
-#define Vpreloaded_file_list \
-    globals.f_Vpreloaded_file_list
-#define Vprevious_system_messages_locale \
-    globals.f_Vprevious_system_messages_locale
-#define Vprevious_system_time_locale \
-    globals.f_Vprevious_system_time_locale
-#define Vprint_charset_text_property \
-    globals.f_Vprint_charset_text_property
-#define Vprint_circle \
-    globals.f_Vprint_circle
-#define Vprint_continuous_numbering \
-    globals.f_Vprint_continuous_numbering
-#define Vprint_gensym \
-    globals.f_Vprint_gensym
-#define Vprint_length \
-    globals.f_Vprint_length
-#define Vprint_level \
-    globals.f_Vprint_level
-#define Vprint_number_table \
-    globals.f_Vprint_number_table
-#define Vprintable_chars \
-    globals.f_Vprintable_chars
-#define Vprocess_adaptive_read_buffering \
-    globals.f_Vprocess_adaptive_read_buffering
-#define Vprocess_coding_system_alist \
-    globals.f_Vprocess_coding_system_alist
-#define Vprocess_connection_type \
-    globals.f_Vprocess_connection_type
-#define Vprocess_environment \
-    globals.f_Vprocess_environment
-#define Vpurify_flag \
-    globals.f_Vpurify_flag
-#define Vquit_flag \
-    globals.f_Vquit_flag
-#define Vread_buffer_function \
-    globals.f_Vread_buffer_function
-#define Vread_expression_history \
-    globals.f_Vread_expression_history
-#define Vread_circle \
-    globals.f_Vread_circle
-#define Vread_expression_map \
-    globals.f_Vread_expression_map
-#define Vread_symbol_positions_list \
-    globals.f_Vread_symbol_positions_list
-#define Vread_with_symbol_positions \
-    globals.f_Vread_with_symbol_positions
-#define Vrecenter_redisplay \
-    globals.f_Vrecenter_redisplay
-#define Vredisplay_end_trigger_functions \
-    globals.f_Vredisplay_end_trigger_functions
-#define Vredisplay_preemption_period \
-    globals.f_Vredisplay_preemption_period
-#define Vresize_mini_windows \
-    globals.f_Vresize_mini_windows
-#define Vresume_tty_functions \
-    globals.f_Vresume_tty_functions
-#define Vring_bell_function \
-    globals.f_Vring_bell_function
-#define Vsaved_region_selection \
-    globals.f_Vsaved_region_selection
-#define Vscalable_fonts_allowed \
-    globals.f_Vscalable_fonts_allowed
-#define Vscript_representative_chars \
-    globals.f_Vscript_representative_chars
-#define Vscroll_preserve_screen_position \
-    globals.f_Vscroll_preserve_screen_position
-#define Vsearch_spaces_regexp \
-    globals.f_Vsearch_spaces_regexp
-#define Vselect_active_regions \
-    globals.f_Vselect_active_regions
-#define Vselect_safe_coding_system_function \
-    globals.f_Vselect_safe_coding_system_function
-#define Vselection_coding_system \
-    globals.f_Vselection_coding_system
-#define Vselection_converter_alist \
-    globals.f_Vselection_converter_alist
-#define Vset_auto_coding_function \
-    globals.f_Vset_auto_coding_function
-#define Vshared_game_score_directory \
-    globals.f_Vshared_game_score_directory
-#define Vshell_file_name \
-    globals.f_Vshell_file_name
-#define Vshow_help_function \
-    globals.f_Vshow_help_function
-#define Vshow_trailing_whitespace \
-    globals.f_Vshow_trailing_whitespace
-#define Vsignal_hook_function \
-    globals.f_Vsignal_hook_function
-#define Vsource_directory \
-    globals.f_Vsource_directory
-#define Vspecial_event_map \
-    globals.f_Vspecial_event_map
-#define Vstandard_display_table \
-    globals.f_Vstandard_display_table
-#define Vstandard_input \
-    globals.f_Vstandard_input
-#define Vstandard_output \
-    globals.f_Vstandard_output
-#define Vstandard_translation_table_for_decode \
-    globals.f_Vstandard_translation_table_for_decode
-#define Vstandard_translation_table_for_encode \
-    globals.f_Vstandard_translation_table_for_encode
-#define Vsuggest_key_bindings \
-    globals.f_Vsuggest_key_bindings
-#define Vsuspend_tty_functions \
-    globals.f_Vsuspend_tty_functions
-#define Vsystem_configuration \
-    globals.f_Vsystem_configuration
-#define Vsystem_configuration_options \
-    globals.f_Vsystem_configuration_options
-#define Vsystem_messages_locale \
-    globals.f_Vsystem_messages_locale
-#define Vsystem_name \
-    globals.f_Vsystem_name
-#define Vsystem_time_locale \
-    globals.f_Vsystem_time_locale
-#define Vsystem_type \
-    globals.f_Vsystem_type
-#define Vtemp_buffer_show_function \
-    globals.f_Vtemp_buffer_show_function
-#define Vtemporary_file_directory \
-    globals.f_Vtemporary_file_directory
-#define Vterminal_frame \
-    globals.f_Vterminal_frame
-#define Vtext_property_default_nonsticky \
-    globals.f_Vtext_property_default_nonsticky
-#define Vthis_command \
-    globals.f_Vthis_command
-#define Vthis_command_keys_shift_translated \
-    globals.f_Vthis_command_keys_shift_translated
-#define Vthis_original_command \
-    globals.f_Vthis_original_command
-#define Vthrow_on_input \
-    globals.f_Vthrow_on_input
-#define Vtimer_idle_list \
-    globals.f_Vtimer_idle_list
-#define Vtimer_list \
-    globals.f_Vtimer_list
-#define Vtool_bar_border \
-    globals.f_Vtool_bar_border
-#define Vtool_bar_button_margin \
-    globals.f_Vtool_bar_button_margin
-#define Vtool_bar_mode \
-    globals.f_Vtool_bar_mode
-#define Vtool_bar_separator_image_expression \
-    globals.f_Vtool_bar_separator_image_expression
-#define Vtool_bar_style \
-    globals.f_Vtool_bar_style
-#define Vtop_level \
-    globals.f_Vtop_level
-#define Vtransient_mark_mode \
-    globals.f_Vtransient_mark_mode
-#define Vtranslation_hash_table_vector \
-    globals.f_Vtranslation_hash_table_vector
-#define Vtranslation_table_for_input \
-    globals.f_Vtranslation_table_for_input
-#define Vtranslation_table_vector \
-    globals.f_Vtranslation_table_vector
-#define Vtruncate_partial_width_windows \
-    globals.f_Vtruncate_partial_width_windows
-#define Vtty_defined_color_alist \
-    globals.f_Vtty_defined_color_alist
-#define Vtty_erase_char \
-    globals.f_Vtty_erase_char
-#define Vundo_outer_limit \
-    globals.f_Vundo_outer_limit
-#define Vundo_outer_limit_function \
-    globals.f_Vundo_outer_limit_function
-#define Vunicode_category_table \
-    globals.f_Vunicode_category_table
-#define Vunread_command_events \
-    globals.f_Vunread_command_events
-#define Vunread_input_method_events \
-    globals.f_Vunread_input_method_events
-#define Vunread_post_input_method_events \
-    globals.f_Vunread_post_input_method_events
-#define Vuse_default_ascent \
-    globals.f_Vuse_default_ascent
-#define Vuser_full_name \
-    globals.f_Vuser_full_name
-#define Vuser_init_file \
-    globals.f_Vuser_init_file
-#define Vuser_login_name \
-    globals.f_Vuser_login_name
-#define Vuser_real_login_name \
-    globals.f_Vuser_real_login_name
-#define Vvalues \
-    globals.f_Vvalues
-#define Vvertical_centering_font_regexp \
-    globals.f_Vvertical_centering_font_regexp
-#define Vvoid_text_area_pointer \
-    globals.f_Vvoid_text_area_pointer
-#define Vw32_alt_is_meta \
-    globals.f_Vw32_alt_is_meta
-#define Vw32_apps_modifier \
-    globals.f_Vw32_apps_modifier
-#define Vw32_bdf_filename_alist \
-    globals.f_Vw32_bdf_filename_alist
-#define Vw32_capslock_is_shiftlock \
-    globals.f_Vw32_capslock_is_shiftlock
-#define Vw32_charset_info_alist \
-    globals.f_Vw32_charset_info_alist
-#define Vw32_color_map \
-    globals.f_Vw32_color_map
-#define Vw32_downcase_file_names \
-    globals.f_Vw32_downcase_file_names
-#define Vw32_enable_caps_lock \
-    globals.f_Vw32_enable_caps_lock
-#define Vw32_enable_num_lock \
-    globals.f_Vw32_enable_num_lock
-#define Vw32_enable_palette \
-    globals.f_Vw32_enable_palette
-#define Vw32_generate_fake_inodes \
-    globals.f_Vw32_generate_fake_inodes
-#define Vw32_get_true_file_attributes \
-    globals.f_Vw32_get_true_file_attributes
-#define Vw32_grab_focus_on_raise \
-    globals.f_Vw32_grab_focus_on_raise
-#define Vw32_lwindow_modifier \
-    globals.f_Vw32_lwindow_modifier
-#define Vw32_pass_alt_to_system \
-    globals.f_Vw32_pass_alt_to_system
-#define Vw32_pass_lwindow_to_system \
-    globals.f_Vw32_pass_lwindow_to_system
-#define Vw32_pass_rwindow_to_system \
-    globals.f_Vw32_pass_rwindow_to_system
-#define Vw32_phantom_key_code \
-    globals.f_Vw32_phantom_key_code
-#define Vw32_quote_process_args \
-    globals.f_Vw32_quote_process_args
-#define Vw32_recognize_altgr \
-    globals.f_Vw32_recognize_altgr
-#define Vw32_rwindow_modifier \
-    globals.f_Vw32_rwindow_modifier
-#define Vw32_scroll_lock_modifier \
-    globals.f_Vw32_scroll_lock_modifier
-#define Vw32_start_process_inherit_error_mode \
-    globals.f_Vw32_start_process_inherit_error_mode
-#define Vw32_start_process_share_console \
-    globals.f_Vw32_start_process_share_console
-#define Vw32_start_process_show_window \
-    globals.f_Vw32_start_process_show_window
-#define Vw32_swap_mouse_buttons \
-    globals.f_Vw32_swap_mouse_buttons
-#define Vwhere_is_preferred_modifier \
-    globals.f_Vwhere_is_preferred_modifier
-#define Vwindow_configuration_change_hook \
-    globals.f_Vwindow_configuration_change_hook
-#define Vwindow_point_insertion_type \
-    globals.f_Vwindow_point_insertion_type
-#define Vwindow_scroll_functions \
-    globals.f_Vwindow_scroll_functions
-#define Vwindow_size_change_functions \
-    globals.f_Vwindow_size_change_functions
-#define Vwindow_system_version \
-    globals.f_Vwindow_system_version
-#define Vwindow_text_change_functions \
-    globals.f_Vwindow_text_change_functions
-#define Vword_combining_categories \
-    globals.f_Vword_combining_categories
-#define Vword_separating_categories \
-    globals.f_Vword_separating_categories
-#define Vwrap_prefix \
-    globals.f_Vwrap_prefix
-#define Vwrite_region_annotate_functions \
-    globals.f_Vwrite_region_annotate_functions
-#define Vwrite_region_annotations_so_far \
-    globals.f_Vwrite_region_annotations_so_far
-#define Vwrite_region_post_annotation_function \
-    globals.f_Vwrite_region_post_annotation_function
-#define Vx_alt_keysym \
-    globals.f_Vx_alt_keysym
-#define Vx_bitmap_file_path \
-    globals.f_Vx_bitmap_file_path
-#define Vx_cursor_fore_pixel \
-    globals.f_Vx_cursor_fore_pixel
-#define Vx_hourglass_pointer_shape \
-    globals.f_Vx_hourglass_pointer_shape
-#define Vx_hyper_keysym \
-    globals.f_Vx_hyper_keysym
-#define Vx_keysym_table \
-    globals.f_Vx_keysym_table
-#define Vx_lost_selection_functions \
-    globals.f_Vx_lost_selection_functions
-#define Vx_max_tooltip_size \
-    globals.f_Vx_max_tooltip_size
-#define Vx_meta_keysym \
-    globals.f_Vx_meta_keysym
-#define Vx_mode_pointer_shape \
-    globals.f_Vx_mode_pointer_shape
-#define Vx_no_window_manager \
-    globals.f_Vx_no_window_manager
-#define Vx_nontext_pointer_shape \
-    globals.f_Vx_nontext_pointer_shape
-#define Vx_pixel_size_width_font_regexp \
-    globals.f_Vx_pixel_size_width_font_regexp
-#define Vx_pointer_shape \
-    globals.f_Vx_pointer_shape
-#define Vx_resource_class \
-    globals.f_Vx_resource_class
-#define Vx_resource_name \
-    globals.f_Vx_resource_name
-#define Vx_sensitive_text_pointer_shape \
-    globals.f_Vx_sensitive_text_pointer_shape
-#define Vx_sent_selection_functions \
-    globals.f_Vx_sent_selection_functions
-#define Vx_session_id \
-    globals.f_Vx_session_id
-#define Vx_session_previous_id \
-    globals.f_Vx_session_previous_id
-#define Vx_super_keysym \
-    globals.f_Vx_super_keysym
-#define Vx_toolkit_scroll_bars \
-    globals.f_Vx_toolkit_scroll_bars
-#define Vx_window_horizontal_drag_shape \
-    globals.f_Vx_window_horizontal_drag_shape
-#define Vxft_settings \
-    globals.f_Vxft_settings
-#define auto_raise_tool_bar_buttons_p \
-    globals.f_auto_raise_tool_bar_buttons_p
-#define auto_save_interval \
-    globals.f_auto_save_interval
-#define auto_window_vscroll_p \
-    globals.f_auto_window_vscroll_p
-#define automatic_hscrolling_p \
-    globals.f_automatic_hscrolling_p
-#define baud_rate \
-    globals.f_baud_rate
-#define byte_debug_flag \
-    globals.f_byte_debug_flag
-#define byte_metering_on \
-    globals.f_byte_metering_on
-#define cannot_suspend \
-    globals.f_cannot_suspend
-#define check_markers_debug_flag \
-    globals.f_check_markers_debug_flag
-#define coding_system_require_warning \
-    globals.f_coding_system_require_warning
-#define completion_ignore_case \
-    globals.f_completion_ignore_case
-#define cons_cells_consed \
-    globals.f_cons_cells_consed
-#define cross_disabled_images \
-    globals.f_cross_disabled_images
-#define cursor_in_echo_area \
-    globals.f_cursor_in_echo_area
-#define debug_end_pos \
-    globals.f_debug_end_pos
-#define debug_on_next_call \
-    globals.f_debug_on_next_call
-#define debug_on_quit \
-    globals.f_debug_on_quit
-#define debugger_may_continue \
-    globals.f_debugger_may_continue
-#define delete_by_moving_to_trash \
-    globals.f_delete_by_moving_to_trash
-#define delete_exited_processes \
-    globals.f_delete_exited_processes
-#define display_hourglass_p \
-    globals.f_display_hourglass_p
-#define do_mouse_tracking \
-    globals.f_do_mouse_tracking
-#define dos_codepage \
-    globals.f_dos_codepage
-#define dos_country_code \
-    globals.f_dos_country_code
-#define dos_decimal_point \
-    globals.f_dos_decimal_point
-#define dos_hyper_key \
-    globals.f_dos_hyper_key
-#define dos_keyboard_layout \
-    globals.f_dos_keyboard_layout
-#define dos_keypad_mode \
-    globals.f_dos_keypad_mode
-#define dos_super_key \
-    globals.f_dos_super_key
-#define dos_timezone_offset \
-    globals.f_dos_timezone_offset
-#define double_click_fuzz \
-    globals.f_double_click_fuzz
-#define emacs_scroll_step \
-    globals.f_emacs_scroll_step
-#define enable_recursive_minibuffers \
-    globals.f_enable_recursive_minibuffers
-#define eol_mnemonic_dos \
-    globals.f_eol_mnemonic_dos
-#define eol_mnemonic_mac \
-    globals.f_eol_mnemonic_mac
-#define eol_mnemonic_undecided \
-    globals.f_eol_mnemonic_undecided
-#define eol_mnemonic_unix \
-    globals.f_eol_mnemonic_unix
-#define executing_kbd_macro_index \
-    globals.f_executing_kbd_macro_index
-#define extra_keyboard_modifiers \
-    globals.f_extra_keyboard_modifiers
-#define floats_consed \
-    globals.f_floats_consed
-#define focus_follows_mouse \
-    globals.f_focus_follows_mouse
-#define force_load_messages \
-    globals.f_force_load_messages
-#define garbage_collection_messages \
-    globals.f_garbage_collection_messages
-#define gc_cons_threshold \
-    globals.f_gc_cons_threshold
-#define gcs_done \
-    globals.f_gcs_done
-#define highlight_nonselected_windows \
-    globals.f_highlight_nonselected_windows
-#define history_delete_duplicates \
-    globals.f_history_delete_duplicates
-#define hscroll_margin \
-    globals.f_hscroll_margin
-#define indent_tabs_mode \
-    globals.f_indent_tabs_mode
-#define inherit_process_coding_system \
-    globals.f_inherit_process_coding_system
-#define inhibit_eol_conversion \
-    globals.f_inhibit_eol_conversion
-#define inhibit_eval_during_redisplay \
-    globals.f_inhibit_eval_during_redisplay
-#define inhibit_free_realized_faces \
-    globals.f_inhibit_free_realized_faces
-#define inhibit_iso_escape_detection \
-    globals.f_inhibit_iso_escape_detection
-#define inhibit_load_charset_map \
-    globals.f_inhibit_load_charset_map
-#define inhibit_local_menu_bar_menus \
-    globals.f_inhibit_local_menu_bar_menus
-#define inhibit_menubar_update \
-    globals.f_inhibit_menubar_update
-#define inhibit_modification_hooks \
-    globals.f_inhibit_modification_hooks
-#define inhibit_null_byte_detection \
-    globals.f_inhibit_null_byte_detection
-#define inhibit_try_cursor_movement \
-    globals.f_inhibit_try_cursor_movement
-#define inhibit_try_window_id \
-    globals.f_inhibit_try_window_id
-#define inhibit_try_window_reusing \
-    globals.f_inhibit_try_window_reusing
-#define inhibit_x_resources \
-    globals.f_inhibit_x_resources
-#define intervals_consed \
-    globals.f_intervals_consed
-#define inverse_video \
-    globals.f_inverse_video
-#define last_command_event \
-    globals.f_last_command_event
-#define last_input_event \
-    globals.f_last_input_event
-#define last_nonmenu_event \
-    globals.f_last_nonmenu_event
-#define line_number_display_limit_width \
-    globals.f_line_number_display_limit_width
-#define load_convert_to_unibyte \
-    globals.f_load_convert_to_unibyte
-#define load_dangerous_libraries \
-    globals.f_load_dangerous_libraries
-#define load_force_doc_strings \
-    globals.f_load_force_doc_strings
-#define load_in_progress \
-    globals.f_load_in_progress
-#define make_cursor_line_fully_visible_p \
-    globals.f_make_cursor_line_fully_visible_p
-#define max_lisp_eval_depth \
-    globals.f_max_lisp_eval_depth
-#define max_specpdl_size \
-    globals.f_max_specpdl_size
-#define menu_prompt_more_char \
-    globals.f_menu_prompt_more_char
-#define menu_prompting \
-    globals.f_menu_prompting
-#define message_truncate_lines \
-    globals.f_message_truncate_lines
-#define meta_prefix_char \
-    globals.f_meta_prefix_char
-#define minibuffer_allow_text_properties \
-    globals.f_minibuffer_allow_text_properties
-#define minibuffer_auto_raise \
-    globals.f_minibuffer_auto_raise
-#define misc_objects_consed \
-    globals.f_misc_objects_consed
-#define mode_line_in_non_selected_windows \
-    globals.f_mode_line_in_non_selected_windows
-#define mode_line_inverse_video \
-    globals.f_mode_line_inverse_video
-#define multibyte_syntax_as_symbol \
-    globals.f_multibyte_syntax_as_symbol
-#define multiple_frames \
-    globals.f_multiple_frames
-#define next_screen_context_lines \
-    globals.f_next_screen_context_lines
-#define no_redraw_on_reenter \
-    globals.f_no_redraw_on_reenter
-#define noninteractive1 \
-    globals.f_noninteractive1
-#define num_input_keys \
-    globals.f_num_input_keys
-#define num_nonmacro_input_events \
-    globals.f_num_nonmacro_input_events
-#define open_paren_in_column_0_is_defun_start \
-    globals.f_open_paren_in_column_0_is_defun_start
-#define overline_margin \
-    globals.f_overline_margin
-#define parse_sexp_ignore_comments \
-    globals.f_parse_sexp_ignore_comments
-#define parse_sexp_lookup_properties \
-    globals.f_parse_sexp_lookup_properties
-#define polling_period \
-    globals.f_polling_period
-#define print_escape_multibyte \
-    globals.f_print_escape_multibyte
-#define print_escape_newlines \
-    globals.f_print_escape_newlines
-#define print_escape_nonascii \
-    globals.f_print_escape_nonascii
-#define print_quoted \
-    globals.f_print_quoted
-#define pure_bytes_used \
-    globals.f_pure_bytes_used
-#define read_buffer_completion_ignore_case \
-    globals.f_read_buffer_completion_ignore_case
-#define redisplay_dont_pause \
-    globals.f_redisplay_dont_pause
-#define scroll_conservatively \
-    globals.f_scroll_conservatively
-#define scroll_margin \
-    globals.f_scroll_margin
-#define string_chars_consed \
-    globals.f_string_chars_consed
-#define strings_consed \
-    globals.f_strings_consed
-#define symbols_consed \
-    globals.f_symbols_consed
-#define system_uses_terminfo \
-    globals.f_system_uses_terminfo
-#define tool_bar_button_relief \
-    globals.f_tool_bar_button_relief
-#define tool_bar_max_label_size \
-    globals.f_tool_bar_max_label_size
-#define underline_minimum_offset \
-    globals.f_underline_minimum_offset
-#define undo_inhibit_record_point \
-    globals.f_undo_inhibit_record_point
-#define undo_limit \
-    globals.f_undo_limit
-#define undo_strong_limit \
-    globals.f_undo_strong_limit
-#define unibyte_display_via_language_environment \
-    globals.f_unibyte_display_via_language_environment
-#define unread_command_char \
-    globals.f_unread_command_char
-#define use_dialog_box \
-    globals.f_use_dialog_box
-#define use_file_dialog \
-    globals.f_use_file_dialog
-#define use_system_font \
-    globals.f_use_system_font
-#define vector_cells_consed \
-    globals.f_vector_cells_consed
-#define visible_bell \
-    globals.f_visible_bell
-#define visible_cursor \
-    globals.f_visible_cursor
-#define w32_ansi_code_page \
-    globals.f_w32_ansi_code_page
-#define w32_enable_synthesized_fonts \
-    globals.f_w32_enable_synthesized_fonts
-#define w32_mouse_button_tolerance \
-    globals.f_w32_mouse_button_tolerance
-#define w32_mouse_move_interval \
-    globals.f_w32_mouse_move_interval
-#define w32_num_mouse_buttons \
-    globals.f_w32_num_mouse_buttons
-#define w32_pass_extra_mouse_buttons_to_system \
-    globals.f_w32_pass_extra_mouse_buttons_to_system
-#define w32_pass_multimedia_buttons_to_system \
-    globals.f_w32_pass_multimedia_buttons_to_system
-#define w32_pipe_read_delay \
-    globals.f_w32_pipe_read_delay
-#define w32_quit_key \
-    globals.f_w32_quit_key
-#define w32_strict_fontnames \
-    globals.f_w32_strict_fontnames
-#define w32_strict_painting \
-    globals.f_w32_strict_painting
-#define w32_use_full_screen_buffer \
-    globals.f_w32_use_full_screen_buffer
-#define w32_use_visible_system_caret \
-    globals.f_w32_use_visible_system_caret
-#define window_min_height \
-    globals.f_window_min_height
-#define window_min_width \
-    globals.f_window_min_width
-#define words_include_escapes \
-    globals.f_words_include_escapes
-#define write_region_inhibit_fsync \
-    globals.f_write_region_inhibit_fsync
-#define x_gtk_file_dialog_help_text \
-    globals.f_x_gtk_file_dialog_help_text
-#define x_gtk_show_hidden_files \
-    globals.f_x_gtk_show_hidden_files
-#define x_gtk_use_old_file_dialog \
-    globals.f_x_gtk_use_old_file_dialog
-#define x_gtk_use_system_tooltips \
-    globals.f_x_gtk_use_system_tooltips
-#define x_gtk_whole_detached_tool_bar \
-    globals.f_x_gtk_whole_detached_tool_bar
-#define x_mouse_click_focus_ignore_position \
-    globals.f_x_mouse_click_focus_ignore_position
-#define x_selection_timeout \
-    globals.f_x_selection_timeout
-#define x_stretch_cursor_p \
-    globals.f_x_stretch_cursor_p
-#define x_underline_at_descent_line \
-    globals.f_x_underline_at_descent_line
-#define x_use_underline_position_properties \
-    globals.f_x_use_underline_position_properties
-#define ns_input_file \
-    globals.f_ns_input_file
-#define ns_input_font \
-    globals.f_ns_input_font
-#define ns_input_fontsize \
-    globals.f_ns_input_fontsize
-#define ns_input_line \
-    globals.f_ns_input_line
-#define ns_input_color \
-    globals.f_ns_input_color
-#define ns_input_text \
-    globals.f_ns_input_text
-#define ns_working_text \
-    globals.f_ns_working_text
-#define ns_input_spi_name \
-    globals.f_ns_input_spi_name
-#define ns_input_spi_arg \
-    globals.f_ns_input_spi_arg
-#define ns_alternate_modifier \
-    globals.f_ns_alternate_modifier
-#define ns_right_alternate_modifier \
-    globals.f_ns_right_alternate_modifier
-#define ns_command_modifier \
-    globals.f_ns_command_modifier
-#define ns_right_command_modifier \
-    globals.f_ns_right_command_modifier
-#define ns_control_modifier \
-    globals.f_ns_control_modifier
-#define ns_right_control_modifier \
-    globals.f_ns_right_control_modifier
-#define ns_function_modifier \
-    globals.f_ns_function_modifier
-#define ns_antialias_text \
-    globals.f_ns_antialias_text
-#define ns_confirm_quit \
-    globals.f_ns_confirm_quit
-#define Vns_icon_type_alist \
-    globals.f_Vns_icon_type_alist
-#define Vns_version_string \
-    globals.f_Vns_version_string
-#define Vns_sent_selection_hooks \
-    globals.f_Vns_sent_selection_hooks
-#define Vns_lost_selection_hooks \
-    globals.f_Vns_lost_selection_hooks
-#define Vselection_alist \
-    globals.f_Vselection_alist
-#define Vns_reg_to_script \
-    globals.f_Vns_reg_to_script

=== modified file 'src/nsselect.m'
--- src/nsselect.m	2011-01-29 11:30:11 +0000
+++ src/nsselect.m	2011-02-08 14:40:02 +0000
@@ -39,6 +39,8 @@
 
 Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME;
 
+static Lisp_Object Vselection_alist;
+
 static Lisp_Object Qforeign_selection;
 
 /* NSGeneralPboard is pretty much analogous to X11 CLIPBOARD */

=== modified file 'src/xselect.c'
--- src/xselect.c	2011-01-30 22:17:44 +0000
+++ src/xselect.c	2011-02-07 21:57:57 +0000
@@ -126,6 +126,20 @@
 /* Defined in keyboard.c.  */
 extern unsigned long last_event_timestamp;
 
+/* This is an association list whose elements are of the form
+     ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
+   SELECTION-NAME is a lisp symbol, whose name is the name of an X Atom.
+   SELECTION-VALUE is the value that emacs owns for that selection.
+     It may be any kind of Lisp object.
+   SELECTION-TIMESTAMP is the time at which emacs began owning this selection,
+     as a cons of two 16-bit numbers (making a 32 bit time.)
+   FRAME is the frame for which we made the selection.
+   If there is an entry in this alist, then it can be assumed that Emacs owns
+    that selection.
+   The only (eq) parts of this list that are visible from Lisp are the
+    selection-values.  */
+static Lisp_Object Vselection_alist;
+
 
 \f
 /* Define a queue to save up SELECTION_REQUEST_EVENT events for later




^ permalink raw reply	[flat|nested] 123+ messages in thread

* bloom filters (was: concurrency suggestions for Gnus)
  2011-02-08 14:41                     ` bloom filters (was: concurrency suggestions for Gnus) Ted Zlatanov
@ 2011-02-08 15:15                       ` Stephen J. Turnbull
  0 siblings, 0 replies; 123+ messages in thread
From: Stephen J. Turnbull @ 2011-02-08 15:15 UTC (permalink / raw)
  To: Ted Zlatanov; +Cc: emacs-devel

Ted Zlatanov writes:

 > false positive rate correlated to the number of bits per element.  It
 > would actually be a nice addition to the Emacs core to have a C
 > implementation.

The SXEmacs people certainly think so.  Maybe you could get an
assignment from the author.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-07  8:05                 ` Helmut Eller
  2011-02-07 19:23                   ` Richard Stallman
@ 2011-02-08 16:26                   ` Tom Tromey
  2011-02-08 17:57                     ` Helmut Eller
  2011-02-08 21:10                     ` Stefan Monnier
  1 sibling, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-08 16:26 UTC (permalink / raw)
  To: Helmut Eller; +Cc: emacs-devel

>>>>> "Helmut" == Helmut Eller <eller.helmut@gmail.com> writes:

Helmut> Well, no mutable objects could be shared, which is quite different from
Helmut> a lock; especially the case when somebody forgets to use the lock.

Tom> I am interested in reasoned arguments, grounded in real Emacs code, to
Tom> the contrary for either STM or CSP.

Helmut> With some hand-waving, the current way to deal with external processes
Helmut> can be seen as form of CSP.  Otherwise I'd say current Emacs code
Helmut> neither uses STM nor CSP nor locks, which makes it hard to meet your
Helmut> request.

What I meant by this is that any proposed change has to come with a plan
to upgrade the existing body of Emacs Lisp code, not all of which is
included in Emacs.

With locks it is probably possible to do this piecemeal.

I don't know how to do it for CSP, and for STM the C side seems much too
hard to contemplate.

Likewise, I think sharing mutable objects is inevitable given the way
Emacs Lisp is already written.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-07 19:23                   ` Richard Stallman
@ 2011-02-08 16:30                     ` Tom Tromey
  0 siblings, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-08 16:30 UTC (permalink / raw)
  To: rms; +Cc: Helmut Eller, emacs-devel

RMS> It would be easy enough to stop one buffer from being current in more
RMS> than one thread.  Just make set-buffer do the interlocking.  That
RMS> would be an easy change, and it would block threads less often than
RMS> the above idea.

RMS> But even that could be too much blocking of threads.  If a thread
RMS> is sitting idle with a certain buffer current, that would block
RMS> all other threads from operating on it.  That would be a big problem.

I actually tried to put a buffer lock in set-buffer and in the end
concluded that it was too much trouble.

One problem comes up immediately: what is the current buffer of a new
thread?  It can't be the parent's thread buffer, since that means new
threads won't run until the parent thread changes buffers.  And, there
is no guarantee that there is more than one buffer.

Making Emacs safe for preemptive threads is, as you say, quite hard.  It
is even hard at the micro level -- ensuring that operations like XCAR
are atomic.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 22:21           ` Stefan Monnier
@ 2011-02-08 16:38             ` Tom Tromey
  2011-02-11 21:48             ` Tom Tromey
  1 sibling, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-08 16:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>>>>> "Stefan" == Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

Stefan> Note that this auto-generation of globals.h might trigger some
Stefan> related neurons and bring up related desires.
Stefan> E.g. auto-generate the `defsubr' calls and all the
Stefan> intern_c_string+staticpro for Q<foo> vars ;-)

Auto-generating the `defsubr' calls looks reasonably easy.  Well -- it
looks very easy given sed, I have no clue about the Windows build.  I
guess I could write a C program in lib-src.

I actually did the Q* vars once for another hare-brained hack of mine.
I could probably reproduce that.  What I did there is have a file that
was just a list of Lisp symbols.  Then, I generated all the declarations
and initialization of the Q* constants from that.

I could look into this again, but IIRC it was quite a bit of work.
But maybe it would be amenable to automated rewriting now.


Really we should just go the extra mile and write Emacs in Lisp ;-)
That would solve a lot of problems.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 16:26                   ` Tom Tromey
@ 2011-02-08 17:57                     ` Helmut Eller
  2011-02-11 21:59                       ` Tom Tromey
  2011-02-08 21:10                     ` Stefan Monnier
  1 sibling, 1 reply; 123+ messages in thread
From: Helmut Eller @ 2011-02-08 17:57 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

* Tom Tromey [2011-02-08 16:26] writes:

>>>>>> "Helmut" == Helmut Eller <eller.helmut@gmail.com> writes:
>
> Helmut> Well, no mutable objects could be shared, which is quite different from
> Helmut> a lock; especially the case when somebody forgets to use the lock.
>
> Tom> I am interested in reasoned arguments, grounded in real Emacs code, to
> Tom> the contrary for either STM or CSP.
>
> Helmut> With some hand-waving, the current way to deal with external processes
> Helmut> can be seen as form of CSP.  Otherwise I'd say current Emacs code
> Helmut> neither uses STM nor CSP nor locks, which makes it hard to meet your
> Helmut> request.
>
> What I meant by this is that any proposed change has to come with a plan
> to upgrade the existing body of Emacs Lisp code, not all of which is
> included in Emacs.

I think threads are a new feature and it wouldn't surprise me that new
code must be written to use that feature.

> With locks it is probably possible to do this piecemeal.

I think explicit locks put the burden on the programmers.  They must
debug/update/fix their programs for a multi-threaded world even if they
don't use threads.  Not a pay-as-you-go kind of plan, is it?

> I don't know how to do it for CSP, and for STM the C side seems much too
> hard to contemplate.
>
> Likewise, I think sharing mutable objects is inevitable given the way
> Emacs Lisp is already written.

HTML5 Web Workers avoid shared mutable objects.  Instead
of creating a thread with (spawn (lambda () ...)) 
we would have something like (worker "task.el").

Where "task.el" is a file containing the program that does all the
work. A worker starts with an (almost) empty environment and must
initialize all needed state from zero.  In particular if some library is
needed it must be loaded explicitly (that's not visible in the parent
thread).  A worker can only communicate with other threads via pipes (I
think workers exchange Javascript objects in JSON format in HTML5; maybe
we would use sexps for Emacs).

This is certainly more heavy weight and probably has its own set of
problems but it obviously works without shared mutable state.

Helmut



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 15:07               ` Tom Tromey
@ 2011-02-08 21:02                 ` Stefan Monnier
  2011-02-08 21:08                   ` Tom Tromey
  2011-02-08 21:21                   ` Tom Tromey
  2011-02-08 21:58                 ` Andreas Schwab
  1 sibling, 2 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-08 21:02 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> === modified file 'configure'
> --- configure	2011-02-05 22:30:14 +0000
> +++ configure	2011-02-08 14:54:38 +0000

It's generally better to skip "configure" (and other generated files) when
you pose a patch for review.  Luckily in this case, the changes in
"configure" were small.

> +/* A single global.  */
> +struct global
> +{
> +  char type;
> +  char *name;
> +};

Please use an enum type rather than a char for the "type" field.

> +static void
> +add_global (char type, char *name)
> +{
> +  /* Ignore the one non-symbol that can occur.  */
> +  if (strcmp (name, "..."))
> +    {
> +      ++num_globals;
> +      globals = xrealloc (globals, num_globals * sizeof (struct global));
> +      globals[num_globals - 1].type = type;
> +      globals[num_globals - 1].name = name;
> +    }
> +}

I'd have used a singly-linked list or a "xrealloc (twice the size)"
scheme, to avoid allocating N^2 amount of memory.  But I guess it
doesn't matter for make-docfile.

> +  qsort (globals, num_globals, sizeof (struct global), compare_globals);

Good.

> +      if (globals[i].type == 'I')
> +	type = "EMACS_INT";
> +      else if (globals[i].type == 'B')
> +	type = "int";
> +      else if (globals[i].type == 'L')
> +	type = "Lisp_Object";
> +      else
> +	fatal ("not a recognized DEFVAR_", 0);

Better use `switch'.

> +      if (generate_globals && (!defvarflag || defvarperbufferflag
> +			       || (type != 'I' && type != 'B'
> +				   && type != 'L')))
> +	continue;

Why test (type != 'I' && type != 'B' && type != 'L')?

The rest looks good, thank you.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 21:02                 ` Stefan Monnier
@ 2011-02-08 21:08                   ` Tom Tromey
  2011-02-08 21:21                   ` Tom Tromey
  1 sibling, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-08 21:08 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>>>>> "Stefan" == Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

>> +      if (generate_globals && (!defvarflag || defvarperbufferflag
>> +			       || (type != 'I' && type != 'B'
>> +				   && type != 'L')))
>> +	continue;

Stefan> Why test (type != 'I' && type != 'B' && type != 'L')?

This filters out things like DEFVAR_PER_BUFFER.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 16:26                   ` Tom Tromey
  2011-02-08 17:57                     ` Helmut Eller
@ 2011-02-08 21:10                     ` Stefan Monnier
  1 sibling, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-08 21:10 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Helmut Eller, emacs-devel

> What I meant by this is that any proposed change has to come with a plan
> to upgrade the existing body of Emacs Lisp code, not all of which is
> included in Emacs.

> With locks it is probably possible to do this piecemeal.

Indeed.

> I don't know how to do it for CSP, and for STM the C side seems much too
> hard to contemplate.

The difficult part of STM is that in all likelihood, we wouldn't be able
to use a non-blocking implementation of transactions, since that
requires the code to be re-runnable, which boils down to being
something like "side-effect free" and we can't easily check/enforce it.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 21:02                 ` Stefan Monnier
  2011-02-08 21:08                   ` Tom Tromey
@ 2011-02-08 21:21                   ` Tom Tromey
  2011-02-09 21:32                     ` Stefan Monnier
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-08 21:21 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan> Please use an enum type rather than a char for the "type" field.

Done.

Stefan> I'd have used a singly-linked list or a "xrealloc (twice the size)"
Stefan> scheme, to avoid allocating N^2 amount of memory.  But I guess it
Stefan> doesn't matter for make-docfile.

I did the size-doubling thing.

Stefan> Better use `switch'.

Done.

Stefan> The rest looks good, thank you.

I am going to commit it once my bootstrap finishes successfully.
This may break the Windows build, or other builds.  I have no way to
test that.  I can provide some support for fixing problems, though.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 15:07               ` Tom Tromey
  2011-02-08 21:02                 ` Stefan Monnier
@ 2011-02-08 21:58                 ` Andreas Schwab
  1 sibling, 0 replies; 123+ messages in thread
From: Andreas Schwab @ 2011-02-08 21:58 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Stefan Monnier, emacs-devel

Tom Tromey <tromey@redhat.com> writes:

> @@ -645,6 +647,18 @@
>  buildobj.h: Makefile
>  	echo "#define BUILDOBJ \"$(obj) $(otherobj) " "\"" > buildobj.h
>  
> +globals.h: gl-stamp
> +	cp gl-stamp globals.h
> +
> +GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m)
> +
> +gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES)
> +	@rm -f gl-tmp
> +	$(libsrc)/make-docfile -d $(srcdir) -g $(SOME_MACHINE_OBJECTS) $(obj) > gl-tmp
> +	$(srcdir)/../move-if-change gl-tmp gl-stamp

That should move directly to globals.h, and the globals.h rule should
only have a dummy command.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 19:42             ` Tom Tromey
@ 2011-02-09 10:16               ` Jim Meyering
  2011-02-10  4:42                 ` Miles Bader
  0 siblings, 1 reply; 123+ messages in thread
From: Jim Meyering @ 2011-02-09 10:16 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Paul Eggert, emacs-devel

Tom Tromey wrote:

>>>>>> "Paul" == Paul Eggert <eggert@cs.ucla.edu> writes:
>
> Tom> It is rather slow.  On my laptop it takes 10 seconds to scan src/*.c.
> Tom> This would have to be done with every change to a .c file.
>
> Paul> Prepending "/DEFVAR_/!d" to the script sped it up
> Paul> by a factor of 8 on my server; it then ran in
> Paul> 0.142 seconds real-time.
>
> Thanks.
>
> Can I use 'sort -u' or 'uniq' in GNU Makefiles these days?
> Testing my script revealed that some things are DEFVAR'd twice.

Yes, but you may want to ensure use of the C locale so the result is
the same for everyone.  We have this in coreutils, but I don't
particularly like the variable name:

    # Sort in traditional ASCII order, regardless of the current locale;
    # otherwise we may get into trouble with distinct strings that the
    # current locale considers to be equal.
    ASSORT = LC_ALL=C sort



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 21:21                   ` Tom Tromey
@ 2011-02-09 21:32                     ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-09 21:32 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> I am going to commit it once my bootstrap finishes successfully.
> This may break the Windows build, or other builds.  I have no way to
> test that.  I can provide some support for fixing problems, though.

Can you try and see where the corresponding makefile changes need to be
made in the w32 makefile?


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-09 10:16               ` Jim Meyering
@ 2011-02-10  4:42                 ` Miles Bader
  0 siblings, 0 replies; 123+ messages in thread
From: Miles Bader @ 2011-02-10  4:42 UTC (permalink / raw)
  To: Jim Meyering; +Cc: Tom Tromey, Paul Eggert, emacs-devel

Jim Meyering <jim@meyering.net> writes:
> Yes, but you may want to ensure use of the C locale so the result is
> the same for everyone.  We have this in coreutils, but I don't
> particularly like the variable name:
>
>     # Sort in traditional ASCII order, regardless of the current locale;
>     # otherwise we may get into trouble with distinct strings that the
>     # current locale considers to be equal.
>     ASSORT = LC_ALL=C sort

"CSORT" would be nicer :]

-miles

-- 
On a bad day, I see brewers still talking as though all beer were
consumed in the pub, by the pint -- by insatiably thirsty Yorkshire
steelworkers who have in reality long ago sought work as striptease
artists.  [Michael Jackson]



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: concurrency suggestions for Gnus
  2011-02-07 19:48                 ` concurrency suggestions for Gnus (was: Patch for fields of `struct buffer') Ted Zlatanov
  2011-02-08  4:31                   ` concurrency suggestions for Gnus Miles Bader
@ 2011-02-10  8:17                   ` Lars Ingebrigtsen
  1 sibling, 0 replies; 123+ messages in thread
From: Lars Ingebrigtsen @ 2011-02-10  8:17 UTC (permalink / raw)
  To: emacs-devel

Ted Zlatanov <tzz@lifelogs.com> writes:

> On Sun, 06 Feb 2011 19:34:51 -0700 Tom Tromey <tromey@redhat.com> wrote: 
>
> Tom> If we went the "lock anything" route, I would suggest a weak hash table
> Tom> for locks, instead of putting the lock into the object.
>
> A bloom filter would guarantee no false negatives, which as you noted is
> the vast majority of the cases, requires very little space per element
> (about 16 bytes to ensure max 0.1% false positives), and runs in
> constant time.

I don't really see the problem with using traditional explicit locks in
Emacs Lisp.  That's what we do over in Common Lisp World, and I think it
fits the olde-fashioney stylee of our Emacs Lisp programs well.  (What
with all our global variables and very mutable objects.)

> Here are some Gnus ideas:
>
> Rebuilding the thread tree in the summary buffer can probably be
> parallelized.  For large summaries (over 5000 articles) it can be a long
> wait.

It certainly feels like Gnus summary generation isn't linear, so I think
one should look into what Gnus is actually doing when generating the
summary buffers.  I have a feeling that there's a big exponential bug
hiding in there somewhere.

But, yes, summary generation would be a nice thing to parallelise, and
it could be segmented on thread boundaries.  Possibly.

-- 
(domestic pets only, the antidote for overdose, milk.)
  larsi@gnus.org * Lars Magne Ingebrigtsen




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-01 22:21           ` Stefan Monnier
  2011-02-08 16:38             ` Tom Tromey
@ 2011-02-11 21:48             ` Tom Tromey
  2011-02-12  2:25               ` Stefan Monnier
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-11 21:48 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>>>>> "Stefan" == Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

Stefan> Note that this auto-generation of globals.h might trigger some related
Stefan> neurons and bring up related desires.  E.g. auto-generate the `defsubr'
Stefan> calls and all the intern_c_string+staticpro for Q<foo> vars ;-)

I looked at the defsubr thing a bit.

It could be done either with a new program or with some modifications to
make-docfile.  It is a little different than the globals.h problem since
there are DEFUNs that are protected by #if.

My implementation idea is to track #if/#else/#endif, and then for a
source file foo.c, emit a `foo.inc' that has a single function that
contains calls to defsubr, with each defsubr bracketed by the same #if
logic as the DEFUN.

I don't know how to easily solve the Makefile part of this problem.
Overuse of GNU make has probably corrupted me.  In particular, each .o
must depend on just the corresponding .inc.  I didn't see how to do that
without a bunch of `foo.o: foo.inc' lines.

GCC has required GNU make for a number of years now.  It really
simplifies things and it is widely available.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-02  2:42             ` Richard Stallman
  2011-02-02  4:16               ` Tom Tromey
@ 2011-02-11 21:51               ` Tom Tromey
  2011-02-12 23:28                 ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-11 21:51 UTC (permalink / raw)
  To: rms; +Cc: dan.colascione, emacs-devel

>>>>> "RMS" == Richard Stallman <rms@gnu.org> writes:

RMS> That goal seems unobjectionable, but why do you need to change these
RMS> calls in the trunk to be able to work on your branch?

I replied to this but never got a reply in return.

Do you still object to me installing the `struct buffer' macro change on
the trunk?  I think I have responded to all of your objections; the most
important thing (IMO) is that the change is much more easily backed out
than put in.  This means it has very little risk.  (I also don't find it
very ugly, at least in its original BUF_NAME form -- more like in
keeping with much of Emacs, GCC, and GDB.)

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-08 17:57                     ` Helmut Eller
@ 2011-02-11 21:59                       ` Tom Tromey
  2011-02-12  9:16                         ` Helmut Eller
  0 siblings, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-11 21:59 UTC (permalink / raw)
  To: Helmut Eller; +Cc: emacs-devel

Tom> What I meant by this is that any proposed change has to come with a plan
Tom> to upgrade the existing body of Emacs Lisp code, not all of which is
Tom> included in Emacs.

Helmut> I think threads are a new feature and it wouldn't surprise me that new
Helmut> code must be written to use that feature.

Yes, I agree, but such code will want to reuse much of the existing
library of Emacs Lisp.

Tom> With locks it is probably possible to do this piecemeal.

Helmut> I think explicit locks put the burden on the programmers.  They must
Helmut> debug/update/fix their programs for a multi-threaded world even if they
Helmut> don't use threads.  Not a pay-as-you-go kind of plan, is it?

No, it is not ideal, but (1) it can work and (2) many important locks
can effectively be hidden, at least on a "you usually do not need to
thhink about it" basis.

Helmut> HTML5 Web Workers avoid shared mutable objects.  Instead
Helmut> of creating a thread with (spawn (lambda () ...)) 
Helmut> we would have something like (worker "task.el").

Helmut> Where "task.el" is a file containing the program that does all the
Helmut> work. A worker starts with an (almost) empty environment and must
Helmut> initialize all needed state from zero.

This seems very impractical to me.

Helmut> In particular if some library is
Helmut> needed it must be loaded explicitly (that's not visible in the parent
Helmut> thread).  A worker can only communicate with other threads via pipes (I
Helmut> think workers exchange Javascript objects in JSON format in HTML5; maybe
Helmut> we would use sexps for Emacs).

A variant of this idea is either to add a `fork' primitive to Emacs (not
portable, more's the pity) or just spawn a headless Emacs with
bidirectional communication.  With the fork approach you could even do
fancy things like let the child inherit and take over some network
connections.

This approach is somewhat heavy, as you say.  Also, I think initializing
the new environment (in the spawn model) is non-trivial.  All those
globals do matter...

I'm actually not sure why this idea isn't more popular.  I think at
least the basic spawn approach could be implemented immediately in lisp.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-11 21:48             ` Tom Tromey
@ 2011-02-12  2:25               ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-12  2:25 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

> I looked at the defsubr thing a bit.

> It could be done either with a new program or with some modifications to
> make-docfile.  It is a little different than the globals.h problem since
> there are DEFUNs that are protected by #if.

That would be nice.

> My implementation idea is to track #if/#else/#endif, and then for a
> source file foo.c, emit a `foo.inc' that has a single function that
> contains calls to defsubr, with each defsubr bracketed by the same #if
> logic as the DEFUN.

Sounds like a good approach, yes.  Tho I think it'd be simpler to create
a single init_subrs.c file.


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-11 21:59                       ` Tom Tromey
@ 2011-02-12  9:16                         ` Helmut Eller
  0 siblings, 0 replies; 123+ messages in thread
From: Helmut Eller @ 2011-02-12  9:16 UTC (permalink / raw)
  To: emacs-devel

* Tom Tromey [2011-02-11 21:59] writes:

> Helmut> Where "task.el" is a file containing the program that does all the
> Helmut> work. A worker starts with an (almost) empty environment and must
> Helmut> initialize all needed state from zero.
>
> This seems very impractical to me.

Why?

> Helmut> In particular if some library is
> Helmut> needed it must be loaded explicitly (that's not visible in the parent
> Helmut> thread).  A worker can only communicate with other threads via pipes (I
> Helmut> think workers exchange Javascript objects in JSON format in HTML5; maybe
> Helmut> we would use sexps for Emacs).
>
> A variant of this idea is either to add a `fork' primitive to Emacs (not
> portable, more's the pity) or just spawn a headless Emacs with
> bidirectional communication.  With the fork approach you could even do
> fancy things like let the child inherit and take over some network
> connections.

Inheritance is not strictly needed.  File descriptors could be passed
over Unix sockets.

> This approach is somewhat heavy, as you say.  Also, I think initializing
> the new environment (in the spawn model) is non-trivial.  All those
> globals do matter...

A copy-on-write scheme is difficult; starting from zero seems much simpler.

Helmut




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-11 21:51               ` Tom Tromey
@ 2011-02-12 23:28                 ` Richard Stallman
  2011-02-13 20:26                   ` Installing `struct buffer' patch (Was: Patch for fields of `struct buffer') Tom Tromey
  0 siblings, 1 reply; 123+ messages in thread
From: Richard Stallman @ 2011-02-12 23:28 UTC (permalink / raw)
  To: Tom Tromey; +Cc: dan.colascione, emacs-devel

    Do you still object to me installing the `struct buffer' macro change on
    the trunk?

I don't object.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-01-31 21:54           ` Stefan Monnier
@ 2011-02-13 19:01             ` Richard Stallman
  2011-02-14 17:47               ` Stefan Monnier
  0 siblings, 1 reply; 123+ messages in thread
From: Richard Stallman @ 2011-02-13 19:01 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: tromey, emacs-devel

    I also expect some really nasty cases showing up when you try to rewind
    a thread's bindings.  E.g. if a let-binding that was originally applied
    to a global variable has to be rewound (i.e. re-applied) to a variable
    that has become buffer-local in the mean time.

This issue arises now within the single Emacs thread, and we already
handle it.  I don't recall just how we do, but we hardly ever get
a complaint about it.

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Installing `struct buffer' patch (Was: Patch for fields of `struct buffer')
  2011-02-12 23:28                 ` Richard Stallman
@ 2011-02-13 20:26                   ` Tom Tromey
  2011-02-14 16:42                     ` Installing `struct buffer' patch Chong Yidong
  2011-02-15  4:07                     ` Glenn Morris
  0 siblings, 2 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-13 20:26 UTC (permalink / raw)
  To: emacs-devel

Tom>     Do you still object to me installing the `struct buffer' macro
Tom>     change on the trunk?

RMS> I don't object.

I am going to check my patch in tomorrow.

It may break some builds that I cannot test.  However, in all cases, the
fix is simple.  The patch renames the fields of `struct buffer', so when
you see an error arising from `something->field', you can simply change
that to read `B_ (something, field)'.  Please do not change any code to
use `BUFFER_INTERNAL_FIELD'.

thanks,
Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-13 20:26                   ` Installing `struct buffer' patch (Was: Patch for fields of `struct buffer') Tom Tromey
@ 2011-02-14 16:42                     ` Chong Yidong
  2011-02-14 16:48                       ` Tom Tromey
  2011-02-15 15:57                       ` Richard Stallman
  2011-02-15  4:07                     ` Glenn Morris
  1 sibling, 2 replies; 123+ messages in thread
From: Chong Yidong @ 2011-02-14 16:42 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

Tom Tromey <tromey@redhat.com> writes:

> It may break some builds that I cannot test.  However, in all cases, the
> fix is simple.  The patch renames the fields of `struct buffer', so when
> you see an error arising from `something->field', you can simply change
> that to read `B_ (something, field)'.  Please do not change any code to
> use `BUFFER_INTERNAL_FIELD'.

Hmm, I just realized that the B_ macro doesn't make for very
understandable code.  The name is too cryptic.

What do you think about replacing B_ with lots of individual macros,
like BUF_UNDO_LIST, BUF_NAME, etc.?  This might be ugly in buffer.h, but
the rest of the code would be more understandable.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-14 16:42                     ` Installing `struct buffer' patch Chong Yidong
@ 2011-02-14 16:48                       ` Tom Tromey
  2011-02-14 16:52                         ` Chong Yidong
  2011-02-15 15:57                       ` Richard Stallman
  1 sibling, 1 reply; 123+ messages in thread
From: Tom Tromey @ 2011-02-14 16:48 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

>>>>> "Chong" == Chong Yidong <cyd@stupidchicken.com> writes:

Chong> Hmm, I just realized that the B_ macro doesn't make for very
Chong> understandable code.  The name is too cryptic.

Chong> What do you think about replacing B_ with lots of individual macros,
Chong> like BUF_UNDO_LIST, BUF_NAME, etc.?  This might be ugly in buffer.h, but
Chong> the rest of the code would be more understandable.

This is exactly what I did originally, but Stefan asked me to change it
to B_.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-14 16:48                       ` Tom Tromey
@ 2011-02-14 16:52                         ` Chong Yidong
  2011-02-14 16:58                           ` Tom Tromey
  2011-02-14 17:36                           ` Stefan Monnier
  0 siblings, 2 replies; 123+ messages in thread
From: Chong Yidong @ 2011-02-14 16:52 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel

Tom Tromey <tromey@redhat.com> writes:

> Chong> What do you think about replacing B_ with lots of individual macros,
> Chong> like BUF_UNDO_LIST, BUF_NAME, etc.?  This might be ugly in buffer.h, but
> Chong> the rest of the code would be more understandable.
>
> This is exactly what I did originally, but Stefan asked me to change it
> to B_.

Oh, right, I skimmed that discussion.

How bout replacing B_ with something like BUFFER_VAR?



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-14 16:52                         ` Chong Yidong
@ 2011-02-14 16:58                           ` Tom Tromey
  2011-02-14 17:36                           ` Stefan Monnier
  1 sibling, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-14 16:58 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

Chong> How bout replacing B_ with something like BUFFER_VAR?

It is fine by me.  (Actually, FWIW, I preferred the first approach :-)

The only drawback I can think of is that BUFFER_VAR is longer.

Could you and Stefan talk and agree on an approach before I implement it?  

I have the corresponding keyboard-local patch ready to go.  I was
holding off on that until the breakage from the buffer patch was all
fixed; but I'll also wait for a naming decision and change the keyboard
patch to suit.

The good news is that the keyboard patch is the last one.

Tom



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-14 16:52                         ` Chong Yidong
  2011-02-14 16:58                           ` Tom Tromey
@ 2011-02-14 17:36                           ` Stefan Monnier
  2011-02-15 15:50                             ` Chong Yidong
  1 sibling, 1 reply; 123+ messages in thread
From: Stefan Monnier @ 2011-02-14 17:36 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Tom Tromey, emacs-devel

Chong> What do you think about replacing B_ with lots of individual macros,
Chong> like BUF_UNDO_LIST, BUF_NAME, etc.?  This might be ugly in buffer.h, but
Chong> the rest of the code would be more understandable.
>> This is exactly what I did originally, but Stefan asked me to change it
>> to B_.

Yes, I like having a single macro and seeing the field name "as-is"
rather than "as part of a macro name, capitalized".
But I agree that B_ is not very satisfactory.

> How bout replacing B_ with something like BUFFER_VAR?

Sounds good.  Or if we want something shorted, we can shorten BUFFER_VAR
to just BVAR (like we do for SDATA, ASIZE, ...).


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-13 19:01             ` Richard Stallman
@ 2011-02-14 17:47               ` Stefan Monnier
  2011-02-14 19:34                 ` Lennart Borgman
  2011-02-15 15:58                 ` Richard Stallman
  0 siblings, 2 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-14 17:47 UTC (permalink / raw)
  To: rms; +Cc: tromey, emacs-devel

>     I also expect some really nasty cases showing up when you try to rewind
>     a thread's bindings.  E.g. if a let-binding that was originally applied
>     to a global variable has to be rewound (i.e. re-applied) to a variable
>     that has become buffer-local in the mean time.

> This issue arises now within the single Emacs thread, and we already
> handle it.

Not really, because we never rewind, we only unwind.  We do have to
solve related problems when unwinding, and indeed it is tricky and has
suffered from very long standing bugs.

> I don't recall just how we do, but we hardly ever get a complaint
> about it.

Gerd fixed in Emacs-21 a bug that was known for a long time (when you
sometimes had to do (let (blbla) (save-current-buffer ...)) to make sure
that the unwinding would take place in the same buffer as when the vars
were bound).  Since then I've fixed another related bug in some less
common case, and someone else (can't remember who right now, Lennart
maybe?) found a third one (between Emacs-22 and 23).
For this last bug, I tried to do a "thorough code review" to try and
convince myself that we really did get it right this time, but
I wouldn't bet my life on it.

AFAIK, none of those 3 bugs were related to new features, so getting
dynamic let-bindings to work right in the presence of buffer-local
variables has taken in the order of what ... 20 years?


        Stefan



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-14 17:47               ` Stefan Monnier
@ 2011-02-14 19:34                 ` Lennart Borgman
  2011-02-15 15:58                 ` Richard Stallman
  1 sibling, 0 replies; 123+ messages in thread
From: Lennart Borgman @ 2011-02-14 19:34 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: tromey, rms, emacs-devel

On Mon, Feb 14, 2011 at 6:47 PM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
>>     I also expect some really nasty cases showing up when you try to rewind
>>     a thread's bindings.  E.g. if a let-binding that was originally applied
>>     to a global variable has to be rewound (i.e. re-applied) to a variable
>>     that has become buffer-local in the mean time.
>
>> This issue arises now within the single Emacs thread, and we already
>> handle it.
>
> Not really, because we never rewind, we only unwind.  We do have to
> solve related problems when unwinding, and indeed it is tricky and has
> suffered from very long standing bugs.
>
>> I don't recall just how we do, but we hardly ever get a complaint
>> about it.
>
> Gerd fixed in Emacs-21 a bug that was known for a long time (when you
> sometimes had to do (let (blbla) (save-current-buffer ...)) to make sure
> that the unwinding would take place in the same buffer as when the vars
> were bound).  Since then I've fixed another related bug in some less
> common case, and someone else (can't remember who right now, Lennart
> maybe?) found a third one (between Emacs-22 and 23).
> For this last bug, I tried to do a "thorough code review" to try and
> convince myself that we really did get it right this time, but
> I wouldn't bet my life on it.
>
> AFAIK, none of those 3 bugs were related to new features, so getting
> dynamic let-bindings to work right in the presence of buffer-local
> variables has taken in the order of what ... 20 years?

;-)

Is maybe a reason that those bugs that shows up in complicated
relations are easily missed because you may believe that the bug is
somewhere else - and that is "confirmed" when you fix something else.

A problem is that those bugs tends to be more likely to show up the
more complicated elisp code Emacs have to handle.

I guess this make unit tests very important.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-13 20:26                   ` Installing `struct buffer' patch (Was: Patch for fields of `struct buffer') Tom Tromey
  2011-02-14 16:42                     ` Installing `struct buffer' patch Chong Yidong
@ 2011-02-15  4:07                     ` Glenn Morris
  2011-02-15 14:28                       ` Tom Tromey
  1 sibling, 1 reply; 123+ messages in thread
From: Glenn Morris @ 2011-02-15  4:07 UTC (permalink / raw)
  To: Tom Tromey; +Cc: emacs-devel


Your commit hasn't appeared on

http://lists.gnu.org/archive/html/emacs-diffs/2011-02/index.html

which I'm pretty sure is due to some Savannah/lists.gnu.org bug;
previously reported as

http://savannah.gnu.org/support/?func=detailitem&item_id=107470

To help diagnose this, can you say if you got any kind of bounce message
from gnu.org about the emacs-diffs mail corresponding to your commit?



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-15  4:07                     ` Glenn Morris
@ 2011-02-15 14:28                       ` Tom Tromey
  0 siblings, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-15 14:28 UTC (permalink / raw)
  To: Glenn Morris; +Cc: emacs-devel

GM> Your commit hasn't appeared on
GM> http://lists.gnu.org/archive/html/emacs-diffs/2011-02/index.html
GM> which I'm pretty sure is due to some Savannah/lists.gnu.org bug;
GM> previously reported as
GM> http://savannah.gnu.org/support/?func=detailitem&item_id=107470
GM> To help diagnose this, can you say if you got any kind of bounce message
GM> from gnu.org about the emacs-diffs mail corresponding to your commit?

Yes, I got a bounce.
I've appended the initial part of the message.
The rest is not very interesting, but I can forward the whole thing if
you want it.

Tom

This message was created automatically by mail delivery software.

A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:

  emacs-diffs@gnu.org

------ This is a copy of the message, including all the headers. ------
------ The body of the message is 336434 characters long; only the first
------ 106496 or so are included here.

Return-path: <tromey@redhat.com>
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
	(envelope-from <tromey@redhat.com>)
	id 1Pp17v-0004Hg-LC
	for emacs-diffs@gnu.org; Mon, 14 Feb 2011 11:18:29 -0500
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org
X-Spam-Level: 
X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00,RDNS_NONE,
	T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.1
Received: from colonialone.fsf.org ([140.186.70.51]:43366 helo=internal.in.savannah.gnu.org)
	by eggs.gnu.org with esmtp (Exim 4.71)
	(envelope-from <tromey@redhat.com>)
	id 1Pp17v-0004HQ-39
	for emacs-diffs@gnu.org; Mon, 14 Feb 2011 11:18:15 -0500
Received: from [10.1.0.108] (helo=vcs-noshell.in.savannah.gnu.org)
	by internal.in.savannah.gnu.org with esmtp (Exim 4.69)
	(envelope-from <tromey@redhat.com>)
	id 1Pp17u-0004RJ-UL
	for emacs-diffs@gnu.org; Mon, 14 Feb 2011 16:18:15 +0000
Content-Type: multipart/mixed; boundary="===============0553871771=="
MIME-Version: 1.0
Date: Mon, 14 Feb 2011 08:39:19 -0700
From: Tom Tromey <tromey@redhat.com>
Subject: /srv/bzr/emacs/trunk r103273: Hide implementation of `struct buffer'
To: emacs-diffs@gnu.org
User-Agent: Bazaar (2.0.3)
Message-Id: <E1Pp17u-0004RJ-UL@internal.in.savannah.gnu.org>
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2)
X-Received-From: 140.186.70.51

--===============0553871771==
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline




^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-14 17:36                           ` Stefan Monnier
@ 2011-02-15 15:50                             ` Chong Yidong
  2011-02-16 14:55                               ` Tom Tromey
  0 siblings, 1 reply; 123+ messages in thread
From: Chong Yidong @ 2011-02-15 15:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Tom Tromey, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> How bout replacing B_ with something like BUFFER_VAR?
>
> Sounds good.  Or if we want something shorted, we can shorten
> BUFFER_VAR to just BVAR (like we do for SDATA, ASIZE, ...).

I am fine with BVAR.



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-14 16:42                     ` Installing `struct buffer' patch Chong Yidong
  2011-02-14 16:48                       ` Tom Tromey
@ 2011-02-15 15:57                       ` Richard Stallman
  1 sibling, 0 replies; 123+ messages in thread
From: Richard Stallman @ 2011-02-15 15:57 UTC (permalink / raw)
  To: Chong Yidong; +Cc: tromey, emacs-devel

    What do you think about replacing B_ with lots of individual macros,
    like BUF_UNDO_LIST, BUF_NAME, etc.?  This might be ugly in buffer.h, but
    the rest of the code would be more understandable.

I agree this is better, because it follows our usual practices.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-14 17:47               ` Stefan Monnier
  2011-02-14 19:34                 ` Lennart Borgman
@ 2011-02-15 15:58                 ` Richard Stallman
  2011-02-15 20:41                   ` Stefan Monnier
  1 sibling, 1 reply; 123+ messages in thread
From: Richard Stallman @ 2011-02-15 15:58 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: tromey, emacs-devel

    > This issue arises now within the single Emacs thread, and we already
    > handle it.

    Not really, because we never rewind, we only unwind.

Isn't rewinding the reverse of unwinding?
If we have got unwinding right (or close enough),
I'd expect that makes it easy to do the rewinding right.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Patch for fields of `struct buffer'
  2011-02-15 15:58                 ` Richard Stallman
@ 2011-02-15 20:41                   ` Stefan Monnier
  0 siblings, 0 replies; 123+ messages in thread
From: Stefan Monnier @ 2011-02-15 20:41 UTC (permalink / raw)
  To: rms; +Cc: tromey, emacs-devel

>> This issue arises now within the single Emacs thread, and we already
>> handle it.
>     Not really, because we never rewind, we only unwind.

> Isn't rewinding the reverse of unwinding?
> If we have got unwinding right (or close enough),
> I'd expect that makes it easy to do the rewinding right.

I don't share your optimism, although it is true that with the advantage
of the 20 years experience getting unwinding to work right, we may be
able to get the rewinding to work right in less time.


        Stefan


PS: BTW, talking about concurrency, I was recently reminded of an
article I read not that long ago which advocated the use of yield-points
instead of transactions (or rather, to define transactions as "what
happens between two yields").  Part of the argument was that the usual
syntactic nesting traditionally imposed by transactions can make some
things really cumbersome, but another aspect was that it is safer since
a missing yield only incurs a performance loss rather than
a race-condition.
It sounds like that might be a good approach for Elisp, but I can't find
this article again and my memory of it is rather vague, so I may be
imagining some of the benefits, and I definitely do not remember what
were the pitfalls.  If that rings a bell for anyone...



^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: Installing `struct buffer' patch
  2011-02-15 15:50                             ` Chong Yidong
@ 2011-02-16 14:55                               ` Tom Tromey
  0 siblings, 0 replies; 123+ messages in thread
From: Tom Tromey @ 2011-02-16 14:55 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Stefan Monnier, emacs-devel

>> Sounds good.  Or if we want something shorted, we can shorten
>> BUFFER_VAR to just BVAR (like we do for SDATA, ASIZE, ...).

Chong> I am fine with BVAR.

I am going to check in a patch to implement this.

Richard wanted the other form, but I will let the three of you work that
out.  It is easy to change again at any time.

I wrote the patch using the appended script.

Tom

(setq add-log-keep-changes-together t)

(defvar last-file-name nil)
(defvar last-function-name nil)

(defun edit-add-cl-entry ()
  (unless (equal buffer-file-name last-file-name)
    (setq last-file-name buffer-file-name)
    (setq last-function-name nil))

  (let ((function (add-log-current-defun)))
    (unless (equal function last-function-name)
      (setq last-function-name function)
      (save-current-buffer
	(add-change-log-entry))
      t)))

(defun insert-cl-entry (text)
  (save-current-buffer
    (find-file "ChangeLog")
    (insert text)
    (fill-paragraph)))

(defun update-files ()
  (dolist (file (directory-files "." t "[ch]$"))
    (find-file file)
    (goto-char (point-min))
    (while (re-search-forward "\\_<B_\\_>" nil t)
      (replace-match "BVAR" t t)
      (edit-add-cl-entry))
    (if (buffer-modified-p)
	(insert-cl-entry "Replace B_ with BVAR."))
    (save-buffer)))

(update-files)

(find-file "ChangeLog")
(save-buffer)



^ permalink raw reply	[flat|nested] 123+ messages in thread

end of thread, other threads:[~2011-02-16 14:55 UTC | newest]

Thread overview: 123+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-27 20:18 Patch for fields of `struct buffer' Tom Tromey
2011-01-28  7:37 ` Eli Zaretskii
2011-01-28  8:58   ` Tom Tromey
2011-01-28  9:29     ` Eli Zaretskii
2011-01-29 12:50       ` Eli Zaretskii
2011-01-29 13:33         ` Juanma Barranquero
2011-01-29 13:42           ` Eli Zaretskii
2011-02-02 18:17             ` Juanma Barranquero
2011-02-02 19:51               ` Eli Zaretskii
2011-01-28 14:55 ` Stefan Monnier
2011-01-28 17:38   ` Tom Tromey
2011-01-28 18:27     ` Stefan Monnier
2011-01-28 18:42       ` Tom Tromey
2011-01-28 20:04         ` Stefan Monnier
2011-01-28 17:23 ` Kim F. Storm
2011-01-28 17:36   ` Tom Tromey
2011-01-28 18:29   ` Stefan Monnier
2011-01-29  2:34     ` Miles Bader
2011-01-29  3:58       ` Stefan Monnier
2011-01-29 16:18 ` Richard Stallman
2011-01-30 20:23   ` Tom Tromey
2011-01-31  4:04     ` Stefan Monnier
2011-01-31 14:29       ` Tom Tromey
2011-01-31 15:22         ` Stefan Monnier
2011-01-31 15:30           ` Tom Tromey
2011-01-31 17:02             ` Stefan Monnier
2011-01-31 18:38               ` Tom Tromey
2011-01-31 20:03                 ` Stefan Monnier
2011-01-31 20:00             ` Stefan Monnier
2011-01-31 20:05               ` Tom Tromey
2011-01-31 20:40                 ` Stefan Monnier
2011-01-31 16:46         ` David De La Harpe Golden
2011-01-31 19:04           ` Tom Tromey
2011-01-31 22:08             ` David De La Harpe Golden
2011-02-01 10:54             ` Daniel Colascione
2011-02-07  2:34               ` Tom Tromey
2011-02-07 19:48                 ` concurrency suggestions for Gnus (was: Patch for fields of `struct buffer') Ted Zlatanov
2011-02-08  4:31                   ` concurrency suggestions for Gnus Miles Bader
2011-02-08 12:55                     ` Andy Moreton
2011-02-08 12:55                     ` Justin Lilly
2011-02-08 14:41                     ` bloom filters (was: concurrency suggestions for Gnus) Ted Zlatanov
2011-02-08 15:15                       ` Stephen J. Turnbull
2011-02-10  8:17                   ` concurrency suggestions for Gnus Lars Ingebrigtsen
2011-02-01 15:43             ` Patch for fields of `struct buffer' Stefan Monnier
2011-02-01 16:28               ` Helmut Eller
2011-02-07  2:47                 ` Tom Tromey
2011-02-07  2:44               ` Tom Tromey
2011-02-07  8:05                 ` Helmut Eller
2011-02-07 19:23                   ` Richard Stallman
2011-02-08 16:30                     ` Tom Tromey
2011-02-08 16:26                   ` Tom Tromey
2011-02-08 17:57                     ` Helmut Eller
2011-02-11 21:59                       ` Tom Tromey
2011-02-12  9:16                         ` Helmut Eller
2011-02-08 21:10                     ` Stefan Monnier
2011-01-31 19:38         ` Richard Stallman
2011-02-01 18:26         ` Tom Tromey
2011-02-01 19:28           ` Paul Eggert
2011-02-01 19:42             ` Tom Tromey
2011-02-09 10:16               ` Jim Meyering
2011-02-10  4:42                 ` Miles Bader
2011-02-01 20:34           ` Andreas Schwab
2011-02-01 21:56             ` Tom Tromey
2011-02-01 21:59           ` Tom Tromey
2011-02-02  0:44             ` Paul Eggert
2011-02-02  3:49             ` Stefan Monnier
2011-02-02 16:26               ` Tom Tromey
2011-02-02 16:37                 ` Stefan Monnier
2011-02-08 15:07               ` Tom Tromey
2011-02-08 21:02                 ` Stefan Monnier
2011-02-08 21:08                   ` Tom Tromey
2011-02-08 21:21                   ` Tom Tromey
2011-02-09 21:32                     ` Stefan Monnier
2011-02-08 21:58                 ` Andreas Schwab
2011-02-01 22:21           ` Stefan Monnier
2011-02-08 16:38             ` Tom Tromey
2011-02-11 21:48             ` Tom Tromey
2011-02-12  2:25               ` Stefan Monnier
2011-01-31 19:37     ` Richard Stallman
2011-01-31 19:57       ` Tom Tromey
2011-02-01  2:42         ` Tom Tromey
2011-02-01  4:09           ` Eli Zaretskii
2011-02-01 16:40         ` Richard Stallman
2011-02-01 16:44           ` Tom Tromey
2011-02-02  2:42             ` Richard Stallman
2011-01-31 20:30       ` Stefan Monnier
2011-01-31 20:49         ` Tom Tromey
2011-01-31 21:54           ` Stefan Monnier
2011-02-13 19:01             ` Richard Stallman
2011-02-14 17:47               ` Stefan Monnier
2011-02-14 19:34                 ` Lennart Borgman
2011-02-15 15:58                 ` Richard Stallman
2011-02-15 20:41                   ` Stefan Monnier
2011-02-01 16:39           ` Richard Stallman
2011-02-01 12:09         ` Stephen J. Turnbull
2011-02-02  2:41           ` Richard Stallman
2011-02-01 10:26       ` Daniel Colascione
2011-02-01 12:10         ` Stephen J. Turnbull
2011-02-01 14:23           ` Lennart Borgman
2011-02-01 16:19             ` Stephen J. Turnbull
2011-02-01 17:08               ` Lennart Borgman
2011-02-01 19:57               ` Daniel Colascione
2011-02-01 20:06                 ` Daniel Colascione
2011-02-01 16:41         ` Richard Stallman
2011-02-01 16:51           ` Tom Tromey
2011-02-02  2:42             ` Richard Stallman
2011-02-02  4:16               ` Tom Tromey
2011-02-02  5:04                 ` Stefan Monnier
2011-02-11 21:51               ` Tom Tromey
2011-02-12 23:28                 ` Richard Stallman
2011-02-13 20:26                   ` Installing `struct buffer' patch (Was: Patch for fields of `struct buffer') Tom Tromey
2011-02-14 16:42                     ` Installing `struct buffer' patch Chong Yidong
2011-02-14 16:48                       ` Tom Tromey
2011-02-14 16:52                         ` Chong Yidong
2011-02-14 16:58                           ` Tom Tromey
2011-02-14 17:36                           ` Stefan Monnier
2011-02-15 15:50                             ` Chong Yidong
2011-02-16 14:55                               ` Tom Tromey
2011-02-15 15:57                       ` Richard Stallman
2011-02-15  4:07                     ` Glenn Morris
2011-02-15 14:28                       ` Tom Tromey
2011-02-01 20:04           ` Patch for fields of `struct buffer' Daniel Colascione
2011-02-02  2:43             ` Richard Stallman

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).