1 /* System thread definitions
2 Copyright (C) 2012-2021 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 SYSTHREAD_H
20 #define SYSTHREAD_H
21 
22 #include <stdbool.h>
23 
24 #if __has_attribute (warn_unused_result)
25 # define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
26 #else
27 # define ATTRIBUTE_WARN_UNUSED_RESULT
28 #endif
29 
30 #ifdef THREADS_ENABLED
31 
32 #ifdef HAVE_PTHREAD
33 
34 #include <pthread.h>
35 
36 /* A system mutex is just a pthread mutex.  This is only used for the
37    GIL.  */
38 typedef pthread_mutex_t sys_mutex_t;
39 
40 typedef pthread_cond_t sys_cond_t;
41 
42 /* A system thread.  */
43 typedef pthread_t sys_thread_t;
44 
45 #else /* HAVE_PTHREAD */
46 
47 #ifdef WINDOWSNT
48 
49 /* This header is indirectly included in every source file.  We don't
50    want to include windows.h in every source file, so we repeat
51    declarations of the few necessary data types here (under different
52    names, to avoid conflicts with files that do include
53    windows.h).  */
54 
55 typedef struct {
56   struct _CRITICAL_SECTION_DEBUG *DebugInfo;
57   long LockCount;
58   long RecursionCount;
59   void *OwningThread;
60   void *LockSemaphore;
61   unsigned long SpinCount;
62 } w32thread_critsect;
63 
64 enum { CONDV_SIGNAL = 0, CONDV_BROADCAST = 1, CONDV_MAX = 2 };
65 
66 typedef struct {
67   /* Count of threads that are waiting for this condition variable.  */
68   unsigned wait_count;
69   /* Critical section to protect changes to the count above.  */
70   w32thread_critsect wait_count_lock;
71   /* Handles of events used for signal and broadcast.  */
72   void *events[CONDV_MAX];
73   bool initialized;
74 } w32thread_cond_t;
75 
76 typedef w32thread_critsect sys_mutex_t;
77 
78 typedef w32thread_cond_t sys_cond_t;
79 
80 typedef unsigned long sys_thread_t;
81 
82 #else  /* !WINDOWSNT */
83 
84 #error port me
85 
86 #endif	/* WINDOWSNT */
87 #endif /* HAVE_PTHREAD */
88 
89 #else /* THREADS_ENABLED */
90 
91 /* For the no-threads case we can simply use dummy definitions.  */
92 typedef int sys_mutex_t;
93 typedef int sys_cond_t;
94 typedef int sys_thread_t;
95 
96 #endif /* THREADS_ENABLED */
97 
98 typedef void *(thread_creation_function) (void *);
99 
100 extern void sys_mutex_init (sys_mutex_t *);
101 extern void sys_mutex_lock (sys_mutex_t *);
102 extern void sys_mutex_unlock (sys_mutex_t *);
103 
104 extern void sys_cond_init (sys_cond_t *);
105 extern void sys_cond_wait (sys_cond_t *, sys_mutex_t *);
106 extern void sys_cond_signal (sys_cond_t *);
107 extern void sys_cond_broadcast (sys_cond_t *);
108 extern void sys_cond_destroy (sys_cond_t *);
109 
110 extern sys_thread_t sys_thread_self (void)
111   ATTRIBUTE_WARN_UNUSED_RESULT;
112 extern bool sys_thread_equal (sys_thread_t, sys_thread_t)
113   ATTRIBUTE_WARN_UNUSED_RESULT;
114 
115 extern bool sys_thread_create (sys_thread_t *, thread_creation_function *,
116                                void *)
117   ATTRIBUTE_WARN_UNUSED_RESULT;
118 
119 extern void sys_thread_yield (void);
120 extern void sys_thread_set_name (const char *);
121 
122 #endif /* SYSTHREAD_H */
123