root/src/thread.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. THREADP
  2. CHECK_THREAD
  3. XTHREAD
  4. MUTEXP
  5. CHECK_MUTEX
  6. XMUTEX
  7. CONDVARP
  8. CHECK_CONDVAR
  9. XCONDVAR

     1 /* Thread definitions
     2 Copyright (C) 2012-2023 Free Software Foundation, Inc.
     3 
     4 This file is part of GNU Emacs.
     5 
     6 GNU Emacs is free software: you can redistribute it and/or modify
     7 it under the terms of the GNU General Public License as published by
     8 the Free Software Foundation, either version 3 of the License, or
     9 (at your option) any later version.
    10 
    11 GNU Emacs is distributed in the hope that it will be useful,
    12 but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 GNU General Public License for more details.
    15 
    16 You should have received a copy of the GNU General Public License
    17 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    18 
    19 #ifndef THREAD_H
    20 #define THREAD_H
    21 
    22 #include "regex-emacs.h"
    23 
    24 #ifdef WINDOWSNT
    25 #include <sys/socket.h>
    26 #endif
    27 
    28 #ifdef MSDOS
    29 #include <time.h>               /* struct rpl_timespec */
    30 #include <signal.h>             /* sigset_t */
    31 #endif
    32 
    33 #include "sysselect.h"          /* FIXME */
    34 #include "systhread.h"
    35 
    36 INLINE_HEADER_BEGIN
    37 
    38 /* Byte-code interpreter thread state.  */
    39 struct bc_thread_state {
    40   struct bc_frame *fp;   /* current frame pointer */
    41 
    42   /* start and end of allocated bytecode stack */
    43   char *stack;
    44   char *stack_end;
    45 };
    46 
    47 struct thread_state
    48 {
    49   union vectorlike_header header;
    50 
    51   /* The buffer in which the last search was performed, or
    52      Qt if the last search was done in a string;
    53      Qnil if no searching has been done yet.  */
    54   Lisp_Object m_last_thing_searched;
    55 #define last_thing_searched (current_thread->m_last_thing_searched)
    56 
    57   Lisp_Object m_saved_last_thing_searched;
    58 #define saved_last_thing_searched (current_thread->m_saved_last_thing_searched)
    59 
    60   /* The thread's name.  */
    61   Lisp_Object name;
    62 
    63   /* The thread's function.  */
    64   Lisp_Object function;
    65 
    66   /* The thread's result, if function has finished.  */
    67   Lisp_Object result;
    68 
    69   /* If non-nil, this thread has been signaled.  */
    70   Lisp_Object error_symbol;
    71   Lisp_Object error_data;
    72 
    73   /* If we are waiting for some event, this holds the object we are
    74      waiting on.  */
    75   Lisp_Object event_object;
    76   /* event_object must be the last Lisp field.  */
    77 
    78   /* An address near the bottom of the stack.
    79      Tells GC how to save a copy of the stack.  */
    80   char const *m_stack_bottom;
    81 #define stack_bottom (current_thread->m_stack_bottom)
    82 
    83   /* The address of an object near the C stack top, used to determine
    84      which words need to be scanned by the garbage collector.  This is
    85      also used to detect heuristically whether segmentation violation
    86      address indicates stack overflow, as opposed to some internal
    87      error in Emacs.  If the C function F calls G which calls H which
    88      calls ... F, then at least one of the functions in the chain
    89      should set this to the address of a local variable.  */
    90   void const *stack_top;
    91 
    92   struct catchtag *m_catchlist;
    93 #define catchlist (current_thread->m_catchlist)
    94 
    95   /* Chain of condition handlers currently in effect.
    96      The elements of this chain are contained in the stack frames
    97      of Fcondition_case and internal_condition_case.
    98      When an error is signaled (by calling Fsignal),
    99      this chain is searched for an element that applies.  */
   100   struct handler *m_handlerlist;
   101 #define handlerlist (current_thread->m_handlerlist)
   102 
   103   struct handler *m_handlerlist_sentinel;
   104 #define handlerlist_sentinel (current_thread->m_handlerlist_sentinel)
   105 
   106   /* Pointer to beginning of specpdl.  */
   107   union specbinding *m_specpdl;
   108 #define specpdl (current_thread->m_specpdl)
   109 
   110   /* End of specpld (just beyond the last element).  */
   111   union specbinding *m_specpdl_end;
   112 #define specpdl_end (current_thread->m_specpdl_end)
   113 
   114   /* Pointer to first unused element in specpdl.  */
   115   union specbinding *m_specpdl_ptr;
   116 #define specpdl_ptr (current_thread->m_specpdl_ptr)
   117 
   118   /* Depth in Lisp evaluations and function calls.  */
   119   intmax_t m_lisp_eval_depth;
   120 #define lisp_eval_depth (current_thread->m_lisp_eval_depth)
   121 
   122   /* This points to the current buffer.  */
   123   struct buffer *m_current_buffer;
   124 #define current_buffer (current_thread->m_current_buffer)
   125 
   126   /* Every call to re_search, etc., must pass &search_regs as the regs
   127      argument unless you can show it is unnecessary (i.e., if re_search
   128      is certainly going to be called again before region-around-match
   129      can be called).
   130 
   131      Since the registers are now dynamically allocated, we need to make
   132      sure not to refer to the Nth register before checking that it has
   133      been allocated by checking search_regs.num_regs.
   134 
   135      The regex code keeps track of whether it has allocated the search
   136      buffer using bits in the re_pattern_buffer.  This means that whenever
   137      you compile a new pattern, it completely forgets whether it has
   138      allocated any registers, and will allocate new registers the next
   139      time you call a searching or matching function.  Therefore, we need
   140      to call re_set_registers after compiling a new pattern or after
   141      setting the match registers, so that the regex functions will be
   142      able to free or re-allocate it properly.  */
   143   struct re_registers m_search_regs;
   144 #define search_regs (current_thread->m_search_regs)
   145 
   146   struct re_registers m_saved_search_regs;
   147 #define saved_search_regs (current_thread->m_saved_search_regs)
   148 
   149   /* This member is different from waiting_for_input.
   150      It is used to communicate to a lisp process-filter/sentinel (via the
   151      function Fwaiting_for_user_input_p) whether Emacs was waiting
   152      for user-input when that process-filter was called.
   153      waiting_for_input cannot be used as that is by definition 0 when
   154      lisp code is being evalled.
   155      For that purpose, this must be 0
   156      when not inside wait_reading_process_output.  */
   157   int m_waiting_for_user_input_p;
   158 #define waiting_for_user_input_p (current_thread->m_waiting_for_user_input_p)
   159 
   160   /* True while doing kbd input.  */
   161   bool m_waiting_for_input;
   162 #define waiting_for_input (current_thread->m_waiting_for_input)
   163 
   164   /* For longjmp to where kbd input is being done.  This is per-thread
   165      so that if more than one thread calls read_char, they don't
   166      clobber each other's getcjmp, which will cause
   167      quit_throw_to_read_char crash due to using a wrong stack.  */
   168   sys_jmp_buf m_getcjmp;
   169 #define getcjmp (current_thread->m_getcjmp)
   170 
   171   /* The OS identifier for this thread.  */
   172   sys_thread_t thread_id;
   173 
   174   /* The condition variable for this thread.  This is associated with
   175      the global lock.  This thread broadcasts to it when it exits.  */
   176   sys_cond_t thread_condvar;
   177 
   178   /* This thread might be waiting for some condition.  If so, this
   179      points to the condition.  If the thread is interrupted, the
   180      interrupter should broadcast to this condition.  */
   181   sys_cond_t *wait_condvar;
   182 
   183   /* Thread's name in the locale encoding.  */
   184   char *thread_name;
   185 
   186   /* This thread might have released the global lock.  If so, this is
   187      non-zero.  When a thread runs outside thread_select with this
   188      flag non-zero, it means it has been interrupted by SIGINT while
   189      in thread_select, and didn't have a chance of acquiring the lock.
   190      It must do so ASAP.  */
   191   int not_holding_lock;
   192 
   193   /* Threads are kept on a linked list.  */
   194   struct thread_state *next_thread;
   195 
   196   struct bc_thread_state bc;
   197 } GCALIGNED_STRUCT;
   198 
   199 INLINE bool
   200 THREADP (Lisp_Object a)
   201 {
   202   return PSEUDOVECTORP (a, PVEC_THREAD);
   203 }
   204 
   205 INLINE void
   206 CHECK_THREAD (Lisp_Object x)
   207 {
   208   CHECK_TYPE (THREADP (x), Qthreadp, x);
   209 }
   210 
   211 INLINE struct thread_state *
   212 XTHREAD (Lisp_Object a)
   213 {
   214   eassert (THREADP (a));
   215   return XUNTAG (a, Lisp_Vectorlike, struct thread_state);
   216 }
   217 
   218 /* A mutex in lisp is represented by a system condition variable.
   219    The system mutex associated with this condition variable is the
   220    global lock.
   221 
   222    Using a condition variable lets us implement interruptibility for
   223    lisp mutexes.  */
   224 typedef struct
   225 {
   226   /* The owning thread, or NULL if unlocked.  */
   227   struct thread_state *owner;
   228   /* The lock count.  */
   229   unsigned int count;
   230   /* The underlying system condition variable.  */
   231   sys_cond_t condition;
   232 } lisp_mutex_t;
   233 
   234 /* A mutex as a lisp object.  */
   235 struct Lisp_Mutex
   236 {
   237   union vectorlike_header header;
   238 
   239   /* The name of the mutex, or nil.  */
   240   Lisp_Object name;
   241 
   242   /* The lower-level mutex object.  */
   243   lisp_mutex_t mutex;
   244 } GCALIGNED_STRUCT;
   245 
   246 INLINE bool
   247 MUTEXP (Lisp_Object a)
   248 {
   249   return PSEUDOVECTORP (a, PVEC_MUTEX);
   250 }
   251 
   252 INLINE void
   253 CHECK_MUTEX (Lisp_Object x)
   254 {
   255   CHECK_TYPE (MUTEXP (x), Qmutexp, x);
   256 }
   257 
   258 INLINE struct Lisp_Mutex *
   259 XMUTEX (Lisp_Object a)
   260 {
   261   eassert (MUTEXP (a));
   262   return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Mutex);
   263 }
   264 
   265 /* A condition variable as a lisp object.  */
   266 struct Lisp_CondVar
   267 {
   268   union vectorlike_header header;
   269 
   270   /* The associated mutex.  */
   271   Lisp_Object mutex;
   272 
   273   /* The name of the condition variable, or nil.  */
   274   Lisp_Object name;
   275 
   276   /* The lower-level condition variable object.  */
   277   sys_cond_t cond;
   278 } GCALIGNED_STRUCT;
   279 
   280 INLINE bool
   281 CONDVARP (Lisp_Object a)
   282 {
   283   return PSEUDOVECTORP (a, PVEC_CONDVAR);
   284 }
   285 
   286 INLINE void
   287 CHECK_CONDVAR (Lisp_Object x)
   288 {
   289   CHECK_TYPE (CONDVARP (x), Qcondition_variable_p, x);
   290 }
   291 
   292 INLINE struct Lisp_CondVar *
   293 XCONDVAR (Lisp_Object a)
   294 {
   295   eassert (CONDVARP (a));
   296   return XUNTAG (a, Lisp_Vectorlike, struct Lisp_CondVar);
   297 }
   298 
   299 extern struct thread_state *current_thread;
   300 
   301 extern void finalize_one_thread (struct thread_state *state);
   302 extern void finalize_one_mutex (struct Lisp_Mutex *);
   303 extern void finalize_one_condvar (struct Lisp_CondVar *);
   304 extern void maybe_reacquire_global_lock (void);
   305 
   306 extern void init_threads (void);
   307 extern void syms_of_threads (void);
   308 extern bool main_thread_p (const void *);
   309 extern bool in_current_thread (void);
   310 
   311 typedef int select_func (int, fd_set *, fd_set *, fd_set *,
   312                          const struct timespec *, const sigset_t *);
   313 
   314 int thread_select  (select_func *func, int max_fds, fd_set *rfds,
   315                     fd_set *wfds, fd_set *efds, struct timespec *timeout,
   316                     sigset_t *sigmask);
   317 
   318 bool thread_check_current_buffer (struct buffer *);
   319 
   320 INLINE_HEADER_END
   321 
   322 #endif /* THREAD_H */

/* [<][>][^][v][top][bottom][index][help] */