Fix minor problems with loaddefs autogeneration
[emacs.git] / src / systhread.c
bloba84060c18f051fba24fd2de635de3895df6f9c06
1 /* System thread definitions
2 Copyright (C) 2012-2017 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 <http://www.gnu.org/licenses/>. */
19 #include <config.h>
20 #include <setjmp.h>
21 #include "lisp.h"
23 #ifndef THREADS_ENABLED
25 void
26 sys_mutex_init (sys_mutex_t *m)
28 *m = 0;
31 void
32 sys_mutex_lock (sys_mutex_t *m)
36 void
37 sys_mutex_unlock (sys_mutex_t *m)
41 void
42 sys_cond_init (sys_cond_t *c)
44 *c = 0;
47 void
48 sys_cond_wait (sys_cond_t *c, sys_mutex_t *m)
52 void
53 sys_cond_signal (sys_cond_t *c)
57 void
58 sys_cond_broadcast (sys_cond_t *c)
62 void
63 sys_cond_destroy (sys_cond_t *c)
67 sys_thread_t
68 sys_thread_self (void)
70 return 0;
73 int
74 sys_thread_create (sys_thread_t *t, const char *name,
75 thread_creation_function *func, void *datum)
77 return 0;
80 void
81 sys_thread_yield (void)
85 #elif defined (HAVE_PTHREAD)
87 #include <sched.h>
89 #ifdef HAVE_SYS_PRCTL_H
90 #include <sys/prctl.h>
91 #endif
93 void
94 sys_mutex_init (sys_mutex_t *mutex)
96 pthread_mutex_init (mutex, NULL);
99 void
100 sys_mutex_lock (sys_mutex_t *mutex)
102 pthread_mutex_lock (mutex);
105 void
106 sys_mutex_unlock (sys_mutex_t *mutex)
108 pthread_mutex_unlock (mutex);
111 void
112 sys_cond_init (sys_cond_t *cond)
114 pthread_cond_init (cond, NULL);
117 void
118 sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex)
120 pthread_cond_wait (cond, mutex);
123 void
124 sys_cond_signal (sys_cond_t *cond)
126 pthread_cond_signal (cond);
129 void
130 sys_cond_broadcast (sys_cond_t *cond)
132 pthread_cond_broadcast (cond);
135 void
136 sys_cond_destroy (sys_cond_t *cond)
138 pthread_cond_destroy (cond);
141 sys_thread_t
142 sys_thread_self (void)
144 return pthread_self ();
148 sys_thread_create (sys_thread_t *thread_ptr, const char *name,
149 thread_creation_function *func, void *arg)
151 pthread_attr_t attr;
152 int result = 0;
154 if (pthread_attr_init (&attr))
155 return 0;
157 if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED))
159 result = pthread_create (thread_ptr, &attr, func, arg) == 0;
160 #if defined (HAVE_SYS_PRCTL_H) && defined (HAVE_PRCTL) && defined (PR_SET_NAME)
161 if (result && name != NULL)
162 prctl (PR_SET_NAME, name);
163 #endif
166 pthread_attr_destroy (&attr);
168 return result;
171 void
172 sys_thread_yield (void)
174 sched_yield ();
177 #elif defined (WINDOWSNT)
179 #include <windows.h>
181 /* Cannot include <process.h> because of the local header by the same
182 name, sigh. */
183 uintptr_t _beginthread (void (__cdecl *)(void *), unsigned, void *);
185 /* Mutexes are implemented as critical sections, because they are
186 faster than Windows mutex objects (implemented in userspace), and
187 satisfy the requirements, since we only need to synchronize within a
188 single process. */
189 void
190 sys_mutex_init (sys_mutex_t *mutex)
192 InitializeCriticalSection ((LPCRITICAL_SECTION)mutex);
195 void
196 sys_mutex_lock (sys_mutex_t *mutex)
198 /* FIXME: What happens if the owning thread exits without releasing
199 the mutex? According to MSDN, the result is undefined behavior. */
200 EnterCriticalSection ((LPCRITICAL_SECTION)mutex);
203 void
204 sys_mutex_unlock (sys_mutex_t *mutex)
206 LeaveCriticalSection ((LPCRITICAL_SECTION)mutex);
209 void
210 sys_cond_init (sys_cond_t *cond)
212 cond->initialized = false;
213 cond->wait_count = 0;
214 /* Auto-reset event for signal. */
215 cond->events[CONDV_SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL);
216 /* Manual-reset event for broadcast. */
217 cond->events[CONDV_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL);
218 if (!cond->events[CONDV_SIGNAL] || !cond->events[CONDV_BROADCAST])
219 return;
220 InitializeCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
221 cond->initialized = true;
224 void
225 sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex)
227 DWORD wait_result;
228 bool last_thread_waiting;
230 if (!cond->initialized)
231 return;
233 /* Increment the wait count avoiding race conditions. */
234 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
235 cond->wait_count++;
236 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
238 /* Release the mutex and wait for either the signal or the broadcast
239 event. */
240 LeaveCriticalSection ((LPCRITICAL_SECTION)mutex);
241 wait_result = WaitForMultipleObjects (2, cond->events, FALSE, INFINITE);
243 /* Decrement the wait count and see if we are the last thread
244 waiting on the condition variable. */
245 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
246 cond->wait_count--;
247 last_thread_waiting =
248 wait_result == WAIT_OBJECT_0 + CONDV_BROADCAST
249 && cond->wait_count == 0;
250 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
252 /* Broadcast uses a manual-reset event, so when the last thread is
253 released, we must manually reset that event. */
254 if (last_thread_waiting)
255 ResetEvent (cond->events[CONDV_BROADCAST]);
257 /* Per the API, re-acquire the mutex. */
258 EnterCriticalSection ((LPCRITICAL_SECTION)mutex);
261 void
262 sys_cond_signal (sys_cond_t *cond)
264 bool threads_waiting;
266 if (!cond->initialized)
267 return;
269 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
270 threads_waiting = cond->wait_count > 0;
271 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
273 if (threads_waiting)
274 SetEvent (cond->events[CONDV_SIGNAL]);
277 void
278 sys_cond_broadcast (sys_cond_t *cond)
280 bool threads_waiting;
282 if (!cond->initialized)
283 return;
285 EnterCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
286 threads_waiting = cond->wait_count > 0;
287 LeaveCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
289 if (threads_waiting)
290 SetEvent (cond->events[CONDV_BROADCAST]);
293 void
294 sys_cond_destroy (sys_cond_t *cond)
296 if (cond->events[CONDV_SIGNAL])
297 CloseHandle (cond->events[CONDV_SIGNAL]);
298 if (cond->events[CONDV_BROADCAST])
299 CloseHandle (cond->events[CONDV_BROADCAST]);
301 if (!cond->initialized)
302 return;
304 /* FIXME: What if wait_count is non-zero, i.e. there are still
305 threads waiting on this condition variable? */
306 DeleteCriticalSection ((LPCRITICAL_SECTION)&cond->wait_count_lock);
309 sys_thread_t
310 sys_thread_self (void)
312 return (sys_thread_t) GetCurrentThreadId ();
315 static thread_creation_function *thread_start_address;
317 /* _beginthread wants a void function, while we are passed a function
318 that returns a pointer. So we use a wrapper. */
319 static void
320 w32_beginthread_wrapper (void *arg)
322 (void)thread_start_address (arg);
326 sys_thread_create (sys_thread_t *thread_ptr, const char *name,
327 thread_creation_function *func, void *arg)
329 /* FIXME: Do threads that run Lisp require some minimum amount of
330 stack? Zero here means each thread will get the same amount as
331 the main program. On GNU/Linux, it seems like the stack is 2MB
332 by default, overridden by RLIMIT_STACK at program start time.
333 Not sure what to do with this. See also the comment in
334 w32proc.c:new_child. */
335 const unsigned stack_size = 0;
336 uintptr_t thandle;
338 thread_start_address = func;
340 /* We use _beginthread rather than CreateThread because the former
341 arranges for the thread handle to be automatically closed when
342 the thread exits, thus preventing handle leaks and/or the need to
343 track all the threads and close their handles when they exit.
344 Also, MSDN seems to imply that code which uses CRT _must_ call
345 _beginthread, although if that is true, we already violate that
346 rule in many places... */
347 thandle = _beginthread (w32_beginthread_wrapper, stack_size, arg);
348 if (thandle == (uintptr_t)-1L)
349 return 0;
351 /* Kludge alert! We use the Windows thread ID, an unsigned 32-bit
352 number, as the sys_thread_t type, because that ID is the only
353 unique identifier of a thread on Windows. But _beginthread
354 returns a handle of the thread, and there's no easy way of
355 getting the thread ID given a handle (GetThreadId is available
356 only since Vista, so we cannot use it portably). Fortunately,
357 the value returned by sys_thread_create is not used by its
358 callers; instead, run_thread, which runs in the context of the
359 new thread, calls sys_thread_self and uses its return value;
360 sys_thread_self in this implementation calls GetCurrentThreadId.
361 Therefore, we return some more or less arbitrary value of the
362 thread ID from this function. */
363 *thread_ptr = thandle & 0xFFFFFFFF;
364 return 1;
367 void
368 sys_thread_yield (void)
370 Sleep (0);
373 #else
375 #error port me
377 #endif