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/>. */
27 #ifndef THREADS_ENABLED
30 sys_mutex_init (sys_mutex_t
*m
)
36 sys_mutex_lock (sys_mutex_t
*m
)
41 sys_mutex_unlock (sys_mutex_t
*m
)
46 sys_cond_init (sys_cond_t
*c
)
52 sys_cond_wait (sys_cond_t
*c
, sys_mutex_t
*m
)
57 sys_cond_signal (sys_cond_t
*c
)
62 sys_cond_broadcast (sys_cond_t
*c
)
67 sys_cond_destroy (sys_cond_t
*c
)
72 sys_thread_self (void)
78 sys_thread_equal (sys_thread_t t
, sys_thread_t u
)
84 sys_thread_create (sys_thread_t
*t
, const char *name
,
85 thread_creation_function
*func
, void *datum
)
91 sys_thread_yield (void)
95 #elif defined (HAVE_PTHREAD)
99 #ifdef HAVE_SYS_PRCTL_H
100 #include <sys/prctl.h>
104 sys_mutex_init (sys_mutex_t
*mutex
)
106 pthread_mutex_init (mutex
, NULL
);
110 sys_mutex_lock (sys_mutex_t
*mutex
)
112 pthread_mutex_lock (mutex
);
116 sys_mutex_unlock (sys_mutex_t
*mutex
)
118 pthread_mutex_unlock (mutex
);
122 sys_cond_init (sys_cond_t
*cond
)
124 pthread_cond_init (cond
, NULL
);
128 sys_cond_wait (sys_cond_t
*cond
, sys_mutex_t
*mutex
)
130 pthread_cond_wait (cond
, mutex
);
134 sys_cond_signal (sys_cond_t
*cond
)
136 pthread_cond_signal (cond
);
140 sys_cond_broadcast (sys_cond_t
*cond
)
142 pthread_cond_broadcast (cond
);
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 ();
153 sys_cond_destroy (sys_cond_t
*cond
)
155 pthread_cond_destroy (cond
);
159 sys_thread_self (void)
161 return pthread_self ();
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
)
177 if (pthread_attr_init (&attr
))
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
);
189 pthread_attr_destroy (&attr
);
195 sys_thread_yield (void)
200 #elif defined (WINDOWSNT)
204 /* Cannot include <process.h> because of the local header by the same
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
213 sys_mutex_init (sys_mutex_t
*mutex
)
215 InitializeCriticalSection ((LPCRITICAL_SECTION
)mutex
);
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
);
227 sys_mutex_unlock (sys_mutex_t
*mutex
)
229 LeaveCriticalSection ((LPCRITICAL_SECTION
)mutex
);
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
])
243 InitializeCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
244 cond
->initialized
= true;
248 sys_cond_wait (sys_cond_t
*cond
, sys_mutex_t
*mutex
)
251 bool last_thread_waiting
;
253 if (!cond
->initialized
)
256 /* Increment the wait count avoiding race conditions. */
257 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
259 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
261 /* Release the mutex and wait for either the signal or the broadcast
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
);
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
);
285 sys_cond_signal (sys_cond_t
*cond
)
287 bool threads_waiting
;
289 if (!cond
->initialized
)
292 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
293 threads_waiting
= cond
->wait_count
> 0;
294 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
297 SetEvent (cond
->events
[CONDV_SIGNAL
]);
301 sys_cond_broadcast (sys_cond_t
*cond
)
303 bool threads_waiting
;
305 if (!cond
->initialized
)
308 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
309 threads_waiting
= cond
->wait_count
> 0;
310 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
313 SetEvent (cond
->events
[CONDV_BROADCAST
]);
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
)
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
);
333 sys_thread_self (void)
335 return (sys_thread_t
) GetCurrentThreadId ();
339 sys_thread_equal (sys_thread_t t
, sys_thread_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;
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)
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;
398 sys_thread_yield (void)