mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-05 07:01:11 -08:00
Add a new portable dumper as an alternative to unexec. Use it by default. * src/dmpstruct.awk: New file. * src/doc.c (get_doc_string): use will_dump_p(). * src/editfns.c (styled_format): silence compiler warning with UNINIT. * src/emacs-module.c (syms_of_module): staticpro ltv_mark. * src/emacs.c (gflags): new variable. (init_cmdargs): unwrap (string_starts_with_p, find_argument, dump_error_to_string) (load_pdump): new functions. (main): detect pdumper and --temacs invocation; actually load portable dump when detected; set gflags as appropriate; changes to init functions throughout to avoid passing explicit 'initialized' argument. * src/eval.c (inhibit_lisp_code): remove unused variable. (init_eval_once_for_pdumper): new function. (init_eval_once): call it. * src/filelock.c: CANNOT_DUMP -> will_dump_p() * src/fingerprint-dummy.c: new file * src/fingerprint.h: new file * src/fns.c: CANNOT_DUMP -> will_dump_p(), etc. (weak_hash_tables): remove (hashfn_equal, hashfn_eql): un-staticify (make_hash_table): set new 'next_weak' hash table field; drop global weak_hash_tables logic. (copy_hash_table): drop global weak_hash_tables logic. (hash_table_rehash): new function. (hash_lookup, hash_put, hash_remove_from_table, hash_clear): rehash if needed. (sweep_weak_table): un-staticify; explain logic; bool-ify. (sweep_weak_hash_tables): remove function. * src/font.c (syms_of_font): remember pdumper stuff. * src/fontset.c (syms_of_fontset): remember pdumper stuff. * src/frame.c (make_initial_frame): don't reset Vframe_list. (init_frame_once_for_pdumper, init_frame_once): new functions. (syms_of_frame): remove redundant staticpro. * src/fringe.c (init_fringe_once_for_pdumper): new functin. (init_fringe_once): call it. * src/ftcrfont.c (syms_of_ftcrfont_for_pdumper): new function. (syms_of_ftcrfont): call it. * src/ftfont.c (syms_of_ftfont_for_pdumper): new function. (syms_of_ftfont): call it. * src/ftxont.c (syms_of_ftxfont_for_pdumper): new function. (syms_of_ftxfont): call it. * src/gmalloc.c: adjust for pdumper througout (DUMPED): remove weird custom dumped indicator. * src/gnutls.c (syms_of_gnutls): pdumper note for gnutls_global_initialized. * src/image.c (syms_of_image): add pdumper comment, initializer note. * src/insdel.c (prepare_to_modify_buffer_1): account for buffer contents possibly being in dump image. * src/keyboard.c (syms_of_keyboard_for_pdumper): new function. (syms_of_keyboard): staticpro more; call pdumper syms function. * src/lisp.h: add comments throughout (gflags): declare. (will_dump_p, will_bootstrap_p, will_dump_with_pdumper_p) (dumped_with_pdumper_p, will_dump_with_unexec_p) (dumped_with_unexec_p, definitely_will_not_unexec_p): new functions. (POWER_OF_2, ROUNDUP): move macros. (PSEUDOVECTOR_TYPE, PSEUDOVECTOR_TYPEP): take vectorlike header pointer instead of vector; constify. (Lisp_Hash_Table): add comment about need to rehash on access; add comment for next_weak. (HASH_KEY, HASH_VALUE, HASH_HASH, HASH_TABLE_SIZE): const-ify. (hash_table_rehash): declare. (hash_rehash_needed_p, hash_rehash_if_needed): new functions. (finalizers, doomed_finalizers): declare extern. (SUBR_SECTION_ATTRIBUTE): new macro. (staticvec, staticidx): un-static-ify. (sweep_weak_hash_tables): remove declaration. (sweep_weak_table): declare. (hashfn_eql, hashfn_equal): declare. (number_finalizers_run): new variable. (Vdead): externify when ENABLE_CHECKING. (gc_root_type): new enumeration. (gc_root_visitor): new struct. (visit_static_gc_roots): declare. (vectorlike_nbytes): declare. (vector_nbytes): define as trivial inline function wrapper for vectorlike_nbytes. (init_obarray_once): change signature. (primary_thread): extern-ify. (init_buffer): change signature. (init_frame_once): declare. * src/lread.c (readevalloop): adjust for new dumped predicates. (init_obarray_once): new function. (ndefsubr): new variable. (defsubr): increment it. (load_path_check): adjust for pdumper. (load_path_default): use pdumper functions; adjust for dump search. * src/macfont.m (macfont_init_font_change_handler): avoid shadowing global. (syms_of_macfont_for_pdumper): new function. (syms_of_macfont): call it. * src/menu.c (syms_of_menu): staticpro more stuff. * src/minibuf.c (Ftry_completion): rehash if needed. (init_minibuf_once_for_pdumper): new function. (init_minibuf_once): call it. * src/nsfont.m (syms_of_nsfns): staticpro more. * src/nsfont.m (syms_of_nsfont_for_pdumper): new function. (syms_of_nsfont): call it. * src/nsterm.m (syms_of_nsfont): remember pdumper stuff. * src/pdumper.c: new file. * src/pdumper.h: new file. * src/process.c (init_process_emacs): use new pdumper functions instead of CANNOT_DUMP. * src/profiler.c (syms_of_profiler_for_pdumper): new function. (syms_of_profiler_for_pdumper): call it. * src/search.c (syms_of_search_for_pdumper): new function. (syms_of_search_for_pdumper): call it. * src/sheap.c (bss_sbrk_did_unexec): remove. * src/sheap.h (bss_sbrk_did_unexec): remove. * src/syntax.c (syms_of_syntax): don't redundantly staticpro re_match_object. * src/sysdep.c: use will_dump_with_unexec_p() instead of bss hack thing. * src/syssignals.h (init_sigsegv): declare. * src/systime.h (init_timefns): remove bool from signature. * src/textprop.c (syms_of_textprop): move staticpro. * src/thread.c (main_thread_p): constify. * src/thread.h (main_thread_p): constify. * src/timefns.c (init_timefns): remove bool from signature. (syms_of_timefns_for_pdumper): new function. (syms_of_timefns): call it. * src/w32.c: rearrange code. * src/w32.h (w32_relocate): declare. * src/w32fns.c (syms_of_w32fns): add pdumper note. * src/w32font.c (syms_of_w32font_for_pdumper): new function. (syms_of_w32font): call it. * src/w32heap.c (using_dynamic_heap): new variable. (init_heap): use it. * src/w32menu.c (syms_of_w32menu): add pdumper note. * src/w32proc.c (ctrl_c_handler, mainCRTStartup, _start, open_input_file) (rva_to_section, close_file_data): move here. * src/w32uniscribe.c (syms_of_w32uniscribe_for_pdumper): new function. (syms_of_w32uniscribe): call it. * src/window.c (init_window_once_for_pdumper): new function. (init_window_once): call it; staticpro more stuff. * src/xfont.c (syms_of_xfont_for_pdumper): new function. (syms_of_xfont): call it. * src/xftfont.c (syms_of_xftfont_for_pdumper): new function. (syms_of_xftfont): call it. * src/xmenu.c (syms_of_xmenu_for_pdumper): new function. (syms_of_xmenu): call it. * src/xselect.c (syms_of_xselect_for_pdumper): new function. (syms_of_xselect): call it. * src/xsettings.c (syms_of_xsettings): add more pdumper notes. * src/term.c (syms_of_xterm): add pdumper note. * src/dispnew.c (init_faces_initial): new function. (init_display_interactive): rename from init_display; use will_dump_p instead of !initialized. Initialize faces early for pdumper if needed. (init_display): new function. (syms_of_display_for_pdumper): new function. (syms_of_display): call it. * src/dbusbind.c (syms_of_dbusbind): Add TODO for bus reset on pdumper load. * src/data.c (Fdefalias): Use will_dump_p instead of Vpurify_flag. (Fmake_variable_buffer_local): silence compiler warning with -Og by making valcontents UNINIT. (arith_driver): silence compiler warning with UNINIT. * src/conf_post.h (ATTRIBUTE_SECTION): new macro. * src/composite.c (composition_gstring_put_cache): rehash hash table if needed. * src/coding.c (init_coding_once, syms_of_coding): remember pdumper stuff. * src/charset.h (charset_table_size, charset_table_user): declare. * src/charset.c (charset_table_used, charset_table_size): un-static. (init_charset_oncem, syms_of_charset): remember pdumper stuff. * src/category.c (category_table_version): remove obsolete variable. * src/callint.c (syms_of_callint): staticpro 'preserved_fns' (init_callproc): use will_dump_p instead of !CANNOT_DUMP. * src/bytecode.c (exec_byte_code): rehash table tables if needed * src/buffer.c (alloc_buffer_text, free_buffer_text): account for pdumper (init_buffer_once): add TODO; remember stuff for pdumper. (init_buffer): don't take initialized argument; adjust for pdumper. * src/atimer.c (init_atimer): initialize subr only if !initialized. * src/alloc.c: (vector_marked_p, set_vector_marked) (vectorlike_marked_p, set_vectorlike_marked, cons_marked_p) (set_cons_marked, string_marked_p, set_string_marked) (symbol_marked_p, set_symbol_marked, interval_marked_p) (set_interval_marked): new accessor routines. Use them instead of raw GC access throughout. (Vdead): make non-static when ENABLE_CHECKING. (vectorlike_nbytes): rename of 'vector_nbytes'; take a vectorlike header as input instead of a vector. (number_finalizers_run): new internal C variable. (mark_maybe_object): check for pdumper objects. (valid_pointer_p): don't be gratuitously inefficient under rr(1). (make_pure_c_string): add support for size_byte = -2 mode indicating that string data points into Emacs image rodata. (visit_vectorlike_root): visits GC roots embedded in vectorlike objects. (visit_buffer_root): visits GC roots embedded in our totally-not-a-buffer buffer global objects. (visit_static_gc_roots): visit GC roots in the Emacs data section. (mark_object_root_visitor): root callback used for conventional GC marking (weak_hash_tables): new internal variable for tracking found weak hash tables during GC. (mark_and_sweep_weak_table_contents): new weak hash table marking. (garbage_collect_1): use new GC root visitor machinery. (mark_vectorlike): accept a vectorlike_header instead of a Lisp_Vector. (mark_frame, mark_window, mark_hash_table): new functions. (mark_object): initialize 'm'; check for pdumper objects and use new mark-bit accessors throughout. Remove some object-specific marking code and move to helper functions above. (survives_gc_p): check for pdumper objects. (gc-sweep): clear pdumper mark bits. (init_alloc_once_for_pdumper): new helper function for early init called both during normal init and pdumper load. (init_alloc_once): pdumper integration. * src/Makefile.in: Rewrite dumping for pdumper; add pdumper.o; invoke temacs with --temacs command line option; build dmpstruct.h from dmpstruct.awk; stop relying on CANNOT_DUMP; clean up pdumper intermediate files during build. * nextstep/Makefile.in: build emacs.pdmp into NS packages * lisp/startup.el: account for new '--temacs' and '--dump-file' command line option. * lisp/loadup.el: rewrite early init to account for pdumper; use injected 'dump-mode' variable (set via the new '--temacs' option) instead of parsing command line. * lisp/cus-start.el: Check 'dump-mode' instead of 'purify-flag', since the new 'dump-mode' * lib-src/make-fingerprint.c: new program * lib-src/Makefile.in: built make-fingerprint utility program * configure.ac: Add --with-pdumper toggle to control pdumper support; add --with-unexec toggle to control unexec support. Add --with-dumping option to control which dumping strategy we use by default. Adjust for pdumper throughout. Check for posix_madvise. * Makefile.in: Add @DUMPING@ substitution; add pdumper mode. * .gitignore: Add make-fingerprint, temacs.in, fingerprint.c, dmpstruct.h, and pdumper dump files.
310 lines
9.7 KiB
C
310 lines
9.7 KiB
C
/* Thread definitions
|
|
Copyright (C) 2012-2019 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 <https://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef THREAD_H
|
|
#define THREAD_H
|
|
|
|
#include "regex-emacs.h"
|
|
|
|
#ifdef WINDOWSNT
|
|
#include <sys/socket.h>
|
|
#endif
|
|
|
|
#ifdef MSDOS
|
|
#include <signal.h> /* sigset_t */
|
|
#endif
|
|
|
|
#include "sysselect.h" /* FIXME */
|
|
#include "systhread.h"
|
|
|
|
struct thread_state
|
|
{
|
|
union vectorlike_header header;
|
|
|
|
/* The buffer in which the last search was performed, or
|
|
Qt if the last search was done in a string;
|
|
Qnil if no searching has been done yet. */
|
|
Lisp_Object m_last_thing_searched;
|
|
#define last_thing_searched (current_thread->m_last_thing_searched)
|
|
|
|
Lisp_Object m_saved_last_thing_searched;
|
|
#define saved_last_thing_searched (current_thread->m_saved_last_thing_searched)
|
|
|
|
/* The thread's name. */
|
|
Lisp_Object name;
|
|
|
|
/* The thread's function. */
|
|
Lisp_Object function;
|
|
|
|
/* The thread's result, if function has finished. */
|
|
Lisp_Object result;
|
|
|
|
/* If non-nil, this thread has been signaled. */
|
|
Lisp_Object error_symbol;
|
|
Lisp_Object error_data;
|
|
|
|
/* If we are waiting for some event, this holds the object we are
|
|
waiting on. */
|
|
Lisp_Object event_object;
|
|
|
|
/* m_stack_bottom must be the first non-Lisp field. */
|
|
/* An address near the bottom of the stack.
|
|
Tells GC how to save a copy of the stack. */
|
|
char *m_stack_bottom;
|
|
#define stack_bottom (current_thread->m_stack_bottom)
|
|
|
|
/* The address of an object near the C stack top, used to determine
|
|
which words need to be scanned by the garbage collector. This is
|
|
also used to detect heuristically whether segmentation violation
|
|
address indicates stack overflow, as opposed to some internal
|
|
error in Emacs. If the C function F calls G which calls H which
|
|
calls ... F, then at least one of the functions in the chain
|
|
should set this to the address of a local variable. */
|
|
void *stack_top;
|
|
|
|
struct catchtag *m_catchlist;
|
|
#define catchlist (current_thread->m_catchlist)
|
|
|
|
/* Chain of condition handlers currently in effect.
|
|
The elements of this chain are contained in the stack frames
|
|
of Fcondition_case and internal_condition_case.
|
|
When an error is signaled (by calling Fsignal),
|
|
this chain is searched for an element that applies. */
|
|
struct handler *m_handlerlist;
|
|
#define handlerlist (current_thread->m_handlerlist)
|
|
|
|
struct handler *m_handlerlist_sentinel;
|
|
#define handlerlist_sentinel (current_thread->m_handlerlist_sentinel)
|
|
|
|
/* Current number of specbindings allocated in specpdl. */
|
|
ptrdiff_t m_specpdl_size;
|
|
#define specpdl_size (current_thread->m_specpdl_size)
|
|
|
|
/* Pointer to beginning of specpdl. */
|
|
union specbinding *m_specpdl;
|
|
#define specpdl (current_thread->m_specpdl)
|
|
|
|
/* Pointer to first unused element in specpdl. */
|
|
union specbinding *m_specpdl_ptr;
|
|
#define specpdl_ptr (current_thread->m_specpdl_ptr)
|
|
|
|
/* Depth in Lisp evaluations and function calls. */
|
|
EMACS_INT m_lisp_eval_depth;
|
|
#define lisp_eval_depth (current_thread->m_lisp_eval_depth)
|
|
|
|
/* This points to the current buffer. */
|
|
struct buffer *m_current_buffer;
|
|
#define current_buffer (current_thread->m_current_buffer)
|
|
|
|
/* Every call to re_match_2, etc., must pass &search_regs as the regs
|
|
argument unless you can show it is unnecessary (i.e., if re_match_2
|
|
is certainly going to be called again before region-around-match
|
|
can be called).
|
|
|
|
Since the registers are now dynamically allocated, we need to make
|
|
sure not to refer to the Nth register before checking that it has
|
|
been allocated by checking search_regs.num_regs.
|
|
|
|
The regex code keeps track of whether it has allocated the search
|
|
buffer using bits in the re_pattern_buffer. This means that whenever
|
|
you compile a new pattern, it completely forgets whether it has
|
|
allocated any registers, and will allocate new registers the next
|
|
time you call a searching or matching function. Therefore, we need
|
|
to call re_set_registers after compiling a new pattern or after
|
|
setting the match registers, so that the regex functions will be
|
|
able to free or re-allocate it properly. */
|
|
struct re_registers m_search_regs;
|
|
#define search_regs (current_thread->m_search_regs)
|
|
|
|
/* If non-zero the match data have been saved in saved_search_regs
|
|
during the execution of a sentinel or filter. */
|
|
bool m_search_regs_saved;
|
|
#define search_regs_saved (current_thread->m_search_regs_saved)
|
|
|
|
struct re_registers m_saved_search_regs;
|
|
#define saved_search_regs (current_thread->m_saved_search_regs)
|
|
|
|
/* This member is different from waiting_for_input.
|
|
It is used to communicate to a lisp process-filter/sentinel (via the
|
|
function Fwaiting_for_user_input_p) whether Emacs was waiting
|
|
for user-input when that process-filter was called.
|
|
waiting_for_input cannot be used as that is by definition 0 when
|
|
lisp code is being evalled.
|
|
This is also used in record_asynch_buffer_change.
|
|
For that purpose, this must be 0
|
|
when not inside wait_reading_process_output. */
|
|
int m_waiting_for_user_input_p;
|
|
#define waiting_for_user_input_p (current_thread->m_waiting_for_user_input_p)
|
|
|
|
/* True while doing kbd input. */
|
|
bool m_waiting_for_input;
|
|
#define waiting_for_input (current_thread->m_waiting_for_input)
|
|
|
|
/* For longjmp to where kbd input is being done. This is per-thread
|
|
so that if more than one thread calls read_char, they don't
|
|
clobber each other's getcjmp, which will cause
|
|
quit_throw_to_read_char crash due to using a wrong stack. */
|
|
sys_jmp_buf m_getcjmp;
|
|
#define getcjmp (current_thread->m_getcjmp)
|
|
|
|
/* The OS identifier for this thread. */
|
|
sys_thread_t thread_id;
|
|
|
|
/* The condition variable for this thread. This is associated with
|
|
the global lock. This thread broadcasts to it when it exits. */
|
|
sys_cond_t thread_condvar;
|
|
|
|
/* This thread might be waiting for some condition. If so, this
|
|
points to the condition. If the thread is interrupted, the
|
|
interrupter should broadcast to this condition. */
|
|
sys_cond_t *wait_condvar;
|
|
|
|
/* This thread might have released the global lock. If so, this is
|
|
non-zero. When a thread runs outside thread_select with this
|
|
flag non-zero, it means it has been interrupted by SIGINT while
|
|
in thread_select, and didn't have a chance of acquiring the lock.
|
|
It must do so ASAP. */
|
|
int not_holding_lock;
|
|
|
|
/* Threads are kept on a linked list. */
|
|
struct thread_state *next_thread;
|
|
} GCALIGNED_STRUCT;
|
|
|
|
INLINE bool
|
|
THREADP (Lisp_Object a)
|
|
{
|
|
return PSEUDOVECTORP (a, PVEC_THREAD);
|
|
}
|
|
|
|
INLINE void
|
|
CHECK_THREAD (Lisp_Object x)
|
|
{
|
|
CHECK_TYPE (THREADP (x), Qthreadp, x);
|
|
}
|
|
|
|
INLINE struct thread_state *
|
|
XTHREAD (Lisp_Object a)
|
|
{
|
|
eassert (THREADP (a));
|
|
return XUNTAG (a, Lisp_Vectorlike, struct thread_state);
|
|
}
|
|
|
|
/* A mutex in lisp is represented by a system condition variable.
|
|
The system mutex associated with this condition variable is the
|
|
global lock.
|
|
|
|
Using a condition variable lets us implement interruptibility for
|
|
lisp mutexes. */
|
|
typedef struct
|
|
{
|
|
/* The owning thread, or NULL if unlocked. */
|
|
struct thread_state *owner;
|
|
/* The lock count. */
|
|
unsigned int count;
|
|
/* The underlying system condition variable. */
|
|
sys_cond_t condition;
|
|
} lisp_mutex_t;
|
|
|
|
/* A mutex as a lisp object. */
|
|
struct Lisp_Mutex
|
|
{
|
|
union vectorlike_header header;
|
|
|
|
/* The name of the mutex, or nil. */
|
|
Lisp_Object name;
|
|
|
|
/* The lower-level mutex object. */
|
|
lisp_mutex_t mutex;
|
|
} GCALIGNED_STRUCT;
|
|
|
|
INLINE bool
|
|
MUTEXP (Lisp_Object a)
|
|
{
|
|
return PSEUDOVECTORP (a, PVEC_MUTEX);
|
|
}
|
|
|
|
INLINE void
|
|
CHECK_MUTEX (Lisp_Object x)
|
|
{
|
|
CHECK_TYPE (MUTEXP (x), Qmutexp, x);
|
|
}
|
|
|
|
INLINE struct Lisp_Mutex *
|
|
XMUTEX (Lisp_Object a)
|
|
{
|
|
eassert (MUTEXP (a));
|
|
return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Mutex);
|
|
}
|
|
|
|
/* A condition variable as a lisp object. */
|
|
struct Lisp_CondVar
|
|
{
|
|
union vectorlike_header header;
|
|
|
|
/* The associated mutex. */
|
|
Lisp_Object mutex;
|
|
|
|
/* The name of the condition variable, or nil. */
|
|
Lisp_Object name;
|
|
|
|
/* The lower-level condition variable object. */
|
|
sys_cond_t cond;
|
|
} GCALIGNED_STRUCT;
|
|
|
|
INLINE bool
|
|
CONDVARP (Lisp_Object a)
|
|
{
|
|
return PSEUDOVECTORP (a, PVEC_CONDVAR);
|
|
}
|
|
|
|
INLINE void
|
|
CHECK_CONDVAR (Lisp_Object x)
|
|
{
|
|
CHECK_TYPE (CONDVARP (x), Qcondition_variable_p, x);
|
|
}
|
|
|
|
INLINE struct Lisp_CondVar *
|
|
XCONDVAR (Lisp_Object a)
|
|
{
|
|
eassert (CONDVARP (a));
|
|
return XUNTAG (a, Lisp_Vectorlike, struct Lisp_CondVar);
|
|
}
|
|
|
|
extern struct thread_state *current_thread;
|
|
|
|
extern void finalize_one_thread (struct thread_state *state);
|
|
extern void finalize_one_mutex (struct Lisp_Mutex *);
|
|
extern void finalize_one_condvar (struct Lisp_CondVar *);
|
|
extern void maybe_reacquire_global_lock (void);
|
|
|
|
extern void init_threads_once (void);
|
|
extern void init_threads (void);
|
|
extern void syms_of_threads (void);
|
|
extern bool main_thread_p (const void *);
|
|
extern bool in_current_thread (void);
|
|
|
|
typedef int select_func (int, fd_set *, fd_set *, fd_set *,
|
|
const struct timespec *, const sigset_t *);
|
|
|
|
int thread_select (select_func *func, int max_fds, fd_set *rfds,
|
|
fd_set *wfds, fd_set *efds, struct timespec *timeout,
|
|
sigset_t *sigmask);
|
|
|
|
bool thread_check_current_buffer (struct buffer *);
|
|
|
|
#endif /* THREAD_H */
|