* lisp/ecomplete.el: Add completion-table; use lexical-binding and cl-lib
[emacs.git] / src / systhread.c
blob3f162a2bcbfde5942d33eb09ca671507bb52845f
1 /* System thread definitions
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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.
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.
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/>. */
19 #include <config.h>
20 #include <setjmp.h>
21 #include "lisp.h"
23 #ifdef HAVE_NS
24 #include "nsterm.h"
25 #endif
27 #ifndef THREADS_ENABLED
29 void
30 sys_mutex_init (sys_mutex_t *m)
32 *m = 0;
35 void
36 sys_mutex_lock (sys_mutex_t *m)
40 void
41 sys_mutex_unlock (sys_mutex_t *m)
45 void
46 sys_cond_init (sys_cond_t *c)
48 *c = 0;
51 void
52 sys_cond_wait (sys_cond_t *c, sys_mutex_t *m)
56 void
57 sys_cond_signal (sys_cond_t *c)
61 void
62 sys_cond_broadcast (sys_cond_t *c)
66 void
67 sys_cond_destroy (sys_cond_t *c)
71 sys_thread_t
72 sys_thread_self (void)
74 return 0;
77 bool
78 sys_thread_equal (sys_thread_t t, sys_thread_t u)
80 return t == u;
83 int
84 sys_thread_create (sys_thread_t *t, const char *name,
85 thread_creation_function *func, void *datum)
87 return 0;
90 void
91 sys_thread_yield (void)
95 #elif defined (HAVE_PTHREAD)
97 #include <sched.h>
99 #ifdef HAVE_SYS_PRCTL_H
100 #include <sys/prctl.h>
101 #endif
103 void
104 sys_mutex_init (sys_mutex_t *mutex)
106 pthread_mutex_init (mutex, NULL);
109 void
110 sys_mutex_lock (sys_mutex_t *mutex)
112 pthread_mutex_lock (mutex);
115 void
116 sys_mutex_unlock (sys_mutex_t *mutex)
118 pthread_mutex_unlock (mutex);
121 void
122 sys_cond_init (sys_cond_t *cond)
124 pthread_cond_init (cond, NULL);
127 void
128 sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex)
130 pthread_cond_wait (cond, mutex);
133 void
134 sys_cond_signal (sys_cond_t *cond)
136 pthread_cond_signal (cond);
139 void
140 sys_cond_broadcast (sys_cond_t *cond)
142 pthread_cond_broadcast (cond);
143 #ifdef HAVE_NS
144 /* Send an app defined event to break out of the NS run loop.
145 It seems that if ns_select is running the NS run loop, this
146 broadcast has no effect until the loop is done, breaking a couple
147 of tests in thread-tests.el. */
148 ns_run_loop_break ();
149 #endif
152 void
153 sys_cond_destroy (sys_cond_t *cond)
155 pthread_cond_destroy (cond);
158 sys_thread_t
159 sys_thread_self (void)
161 return pthread_self ();
164 bool
165 sys_thread_equal (sys_thread_t t, sys_thread_t u)
167 return pthread_equal (t, u);
171 sys_thread_create (sys_thread_t *thread_ptr, const char *name,
172 thread_creation_function *func, void *arg)
174 pthread_attr_t attr;
175 int result = 0;
177 if (pthread_attr_init (&attr))
178 return 0;
180 if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED))
182 result = pthread_create (thread_ptr, &attr, func, arg) == 0;
183 #if defined (HAVE_SYS_PRCTL_H) && defined (HAVE_PRCTL) && defined (PR_SET_NAME)
184 if (result && name != NULL)
185 prctl (PR_SET_NAME, name);
186 #endif
189 pthread_attr_destroy (&attr);
191 return result;
194 void
195 sys_thread_yield (void)
197 sched_yield ();
200 #elif defined (WINDOWSNT)
202 #include <w32term.h>
204 /* Cannot include <process.h> because of the local header by the same
205 name, sigh. */
206 uintptr_t _beginthread (void (__cdecl *)(void *), unsigned, void *);
208 /* Mutexes are implemented as critical sections, because they are
209 faster than Windows mutex objects (implemented in userspace), and
210 satisfy the requirements, since we only need to synchronize within a
211 single process. */
212 void
213 sys_mutex_init (sys_mutex_t *mutex)
215 InitializeCriticalSection ((LPCRITICAL_SECTION)mutex);
218 void
219 sys_mutex_lock (sys_mutex_t *mutex)
221 /* FIXME: What happens if the owning thread exits without releasing
222 the mutex? According to MSDN, the result is undefined behavior. */
223 EnterCriticalSection ((LPCRITICAL_SECTION)mutex);
226 void
227 sys_mutex_unlock (sys_mutex_t *mutex)
229 LeaveCriticalSection ((LPCRITICAL_SECTION)mutex);
232 void
233 sys_cond_init (sys_cond_t *cond)
235 cond->initialized = false;
236 cond->wait_count = 0;
237 /* Auto-reset event for signal. */
238 cond->events[CONDV_SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL);
239 /* Manual-reset event for broadcast. */
240 cond->events[CONDV_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL);
241 if (!cond->events[CONDV_SIGNAL] || !cond->events[CONDV_BROADCAST])
242 return;
243 InitializeCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
244 cond->initialized = true;
247 void
248 sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex)
250 DWORD wait_result;
251 bool last_thread_waiting;
253 if (!cond->initialized)
254 return;
256 /* Increment the wait count avoiding race conditions. */
257 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
258 cond->wait_count++;
259 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
261 /* Release the mutex and wait for either the signal or the broadcast
262 event. */
263 LeaveCriticalSection ((LPCRITICAL_SECTION)mutex);
264 wait_result = WaitForMultipleObjects (2, cond->events, FALSE, INFINITE);
266 /* Decrement the wait count and see if we are the last thread
267 waiting on the condition variable. */
268 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
269 cond->wait_count--;
270 last_thread_waiting =
271 wait_result == WAIT_OBJECT_0 + CONDV_BROADCAST
272 && cond->wait_count == 0;
273 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
275 /* Broadcast uses a manual-reset event, so when the last thread is
276 released, we must manually reset that event. */
277 if (last_thread_waiting)
278 ResetEvent (cond->events[CONDV_BROADCAST]);
280 /* Per the API, re-acquire the mutex. */
281 EnterCriticalSection ((LPCRITICAL_SECTION)mutex);
284 void
285 sys_cond_signal (sys_cond_t *cond)
287 bool threads_waiting;
289 if (!cond->initialized)
290 return;
292 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
293 threads_waiting = cond->wait_count > 0;
294 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
296 if (threads_waiting)
297 SetEvent (cond->events[CONDV_SIGNAL]);
300 void
301 sys_cond_broadcast (sys_cond_t *cond)
303 bool threads_waiting;
305 if (!cond->initialized)
306 return;
308 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
309 threads_waiting = cond->wait_count > 0;
310 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
312 if (threads_waiting)
313 SetEvent (cond->events[CONDV_BROADCAST]);
316 void
317 sys_cond_destroy (sys_cond_t *cond)
319 if (cond->events[CONDV_SIGNAL])
320 CloseHandle (cond->events[CONDV_SIGNAL]);
321 if (cond->events[CONDV_BROADCAST])
322 CloseHandle (cond->events[CONDV_BROADCAST]);
324 if (!cond->initialized)
325 return;
327 /* FIXME: What if wait_count is non-zero, i.e. there are still
328 threads waiting on this condition variable? */
329 DeleteCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
332 sys_thread_t
333 sys_thread_self (void)
335 return (sys_thread_t) GetCurrentThreadId ();
338 bool
339 sys_thread_equal (sys_thread_t t, sys_thread_t u)
341 return t == u;
344 static thread_creation_function *thread_start_address;
346 /* _beginthread wants a void function, while we are passed a function
347 that returns a pointer. So we use a wrapper. See the command in
348 w32term.h about the need for ALIGN_STACK attribute. */
349 static void ALIGN_STACK
350 w32_beginthread_wrapper (void *arg)
352 (void)thread_start_address (arg);
356 sys_thread_create (sys_thread_t *thread_ptr, const char *name,
357 thread_creation_function *func, void *arg)
359 /* FIXME: Do threads that run Lisp require some minimum amount of
360 stack? Zero here means each thread will get the same amount as
361 the main program. On GNU/Linux, it seems like the stack is 2MB
362 by default, overridden by RLIMIT_STACK at program start time.
363 Not sure what to do with this. See also the comment in
364 w32proc.c:new_child. */
365 const unsigned stack_size = 0;
366 uintptr_t thandle;
368 thread_start_address = func;
370 /* We use _beginthread rather than CreateThread because the former
371 arranges for the thread handle to be automatically closed when
372 the thread exits, thus preventing handle leaks and/or the need to
373 track all the threads and close their handles when they exit.
374 Also, MSDN seems to imply that code which uses CRT _must_ call
375 _beginthread, although if that is true, we already violate that
376 rule in many places... */
377 thandle = _beginthread (w32_beginthread_wrapper, stack_size, arg);
378 if (thandle == (uintptr_t)-1L)
379 return 0;
381 /* Kludge alert! We use the Windows thread ID, an unsigned 32-bit
382 number, as the sys_thread_t type, because that ID is the only
383 unique identifier of a thread on Windows. But _beginthread
384 returns a handle of the thread, and there's no easy way of
385 getting the thread ID given a handle (GetThreadId is available
386 only since Vista, so we cannot use it portably). Fortunately,
387 the value returned by sys_thread_create is not used by its
388 callers; instead, run_thread, which runs in the context of the
389 new thread, calls sys_thread_self and uses its return value;
390 sys_thread_self in this implementation calls GetCurrentThreadId.
391 Therefore, we return some more or less arbitrary value of the
392 thread ID from this function. */
393 *thread_ptr = thandle & 0xFFFFFFFF;
394 return 1;
397 void
398 sys_thread_yield (void)
400 Sleep (0);
403 #else
405 #error port me
407 #endif