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 <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_create (sys_thread_t
*t
, const char *name
,
79 thread_creation_function
*func
, void *datum
)
85 sys_thread_yield (void)
89 #elif defined (HAVE_PTHREAD)
93 #ifdef HAVE_SYS_PRCTL_H
94 #include <sys/prctl.h>
98 sys_mutex_init (sys_mutex_t
*mutex
)
100 pthread_mutex_init (mutex
, NULL
);
104 sys_mutex_lock (sys_mutex_t
*mutex
)
106 pthread_mutex_lock (mutex
);
110 sys_mutex_unlock (sys_mutex_t
*mutex
)
112 pthread_mutex_unlock (mutex
);
116 sys_cond_init (sys_cond_t
*cond
)
118 pthread_cond_init (cond
, NULL
);
122 sys_cond_wait (sys_cond_t
*cond
, sys_mutex_t
*mutex
)
124 pthread_cond_wait (cond
, mutex
);
128 sys_cond_signal (sys_cond_t
*cond
)
130 pthread_cond_signal (cond
);
134 sys_cond_broadcast (sys_cond_t
*cond
)
136 pthread_cond_broadcast (cond
);
138 /* Send an app defined event to break out of the NS run loop.
139 It seems that if ns_select is running the NS run loop, this
140 broadcast has no effect until the loop is done, breaking a couple
141 of tests in thread-tests.el. */
142 ns_run_loop_break ();
147 sys_cond_destroy (sys_cond_t
*cond
)
149 pthread_cond_destroy (cond
);
153 sys_thread_self (void)
155 return pthread_self ();
159 sys_thread_create (sys_thread_t
*thread_ptr
, const char *name
,
160 thread_creation_function
*func
, void *arg
)
165 if (pthread_attr_init (&attr
))
168 if (!pthread_attr_setdetachstate (&attr
, PTHREAD_CREATE_DETACHED
))
170 result
= pthread_create (thread_ptr
, &attr
, func
, arg
) == 0;
171 #if defined (HAVE_SYS_PRCTL_H) && defined (HAVE_PRCTL) && defined (PR_SET_NAME)
172 if (result
&& name
!= NULL
)
173 prctl (PR_SET_NAME
, name
);
177 pthread_attr_destroy (&attr
);
183 sys_thread_yield (void)
188 #elif defined (WINDOWSNT)
192 /* Cannot include <process.h> because of the local header by the same
194 uintptr_t _beginthread (void (__cdecl
*)(void *), unsigned, void *);
196 /* Mutexes are implemented as critical sections, because they are
197 faster than Windows mutex objects (implemented in userspace), and
198 satisfy the requirements, since we only need to synchronize within a
201 sys_mutex_init (sys_mutex_t
*mutex
)
203 InitializeCriticalSection ((LPCRITICAL_SECTION
)mutex
);
207 sys_mutex_lock (sys_mutex_t
*mutex
)
209 /* FIXME: What happens if the owning thread exits without releasing
210 the mutex? According to MSDN, the result is undefined behavior. */
211 EnterCriticalSection ((LPCRITICAL_SECTION
)mutex
);
215 sys_mutex_unlock (sys_mutex_t
*mutex
)
217 LeaveCriticalSection ((LPCRITICAL_SECTION
)mutex
);
221 sys_cond_init (sys_cond_t
*cond
)
223 cond
->initialized
= false;
224 cond
->wait_count
= 0;
225 /* Auto-reset event for signal. */
226 cond
->events
[CONDV_SIGNAL
] = CreateEvent (NULL
, FALSE
, FALSE
, NULL
);
227 /* Manual-reset event for broadcast. */
228 cond
->events
[CONDV_BROADCAST
] = CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
229 if (!cond
->events
[CONDV_SIGNAL
] || !cond
->events
[CONDV_BROADCAST
])
231 InitializeCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
232 cond
->initialized
= true;
236 sys_cond_wait (sys_cond_t
*cond
, sys_mutex_t
*mutex
)
239 bool last_thread_waiting
;
241 if (!cond
->initialized
)
244 /* Increment the wait count avoiding race conditions. */
245 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
247 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
249 /* Release the mutex and wait for either the signal or the broadcast
251 LeaveCriticalSection ((LPCRITICAL_SECTION
)mutex
);
252 wait_result
= WaitForMultipleObjects (2, cond
->events
, FALSE
, INFINITE
);
254 /* Decrement the wait count and see if we are the last thread
255 waiting on the condition variable. */
256 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
258 last_thread_waiting
=
259 wait_result
== WAIT_OBJECT_0
+ CONDV_BROADCAST
260 && cond
->wait_count
== 0;
261 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
263 /* Broadcast uses a manual-reset event, so when the last thread is
264 released, we must manually reset that event. */
265 if (last_thread_waiting
)
266 ResetEvent (cond
->events
[CONDV_BROADCAST
]);
268 /* Per the API, re-acquire the mutex. */
269 EnterCriticalSection ((LPCRITICAL_SECTION
)mutex
);
273 sys_cond_signal (sys_cond_t
*cond
)
275 bool threads_waiting
;
277 if (!cond
->initialized
)
280 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
281 threads_waiting
= cond
->wait_count
> 0;
282 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
285 SetEvent (cond
->events
[CONDV_SIGNAL
]);
289 sys_cond_broadcast (sys_cond_t
*cond
)
291 bool threads_waiting
;
293 if (!cond
->initialized
)
296 EnterCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
297 threads_waiting
= cond
->wait_count
> 0;
298 LeaveCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
301 SetEvent (cond
->events
[CONDV_BROADCAST
]);
305 sys_cond_destroy (sys_cond_t
*cond
)
307 if (cond
->events
[CONDV_SIGNAL
])
308 CloseHandle (cond
->events
[CONDV_SIGNAL
]);
309 if (cond
->events
[CONDV_BROADCAST
])
310 CloseHandle (cond
->events
[CONDV_BROADCAST
]);
312 if (!cond
->initialized
)
315 /* FIXME: What if wait_count is non-zero, i.e. there are still
316 threads waiting on this condition variable? */
317 DeleteCriticalSection ((LPCRITICAL_SECTION
)&cond
->wait_count_lock
);
321 sys_thread_self (void)
323 return (sys_thread_t
) GetCurrentThreadId ();
326 static thread_creation_function
*thread_start_address
;
328 /* _beginthread wants a void function, while we are passed a function
329 that returns a pointer. So we use a wrapper. See the command in
330 w32term.h about the need for ALIGN_STACK attribute. */
331 static void ALIGN_STACK
332 w32_beginthread_wrapper (void *arg
)
334 (void)thread_start_address (arg
);
338 sys_thread_create (sys_thread_t
*thread_ptr
, const char *name
,
339 thread_creation_function
*func
, void *arg
)
341 /* FIXME: Do threads that run Lisp require some minimum amount of
342 stack? Zero here means each thread will get the same amount as
343 the main program. On GNU/Linux, it seems like the stack is 2MB
344 by default, overridden by RLIMIT_STACK at program start time.
345 Not sure what to do with this. See also the comment in
346 w32proc.c:new_child. */
347 const unsigned stack_size
= 0;
350 thread_start_address
= func
;
352 /* We use _beginthread rather than CreateThread because the former
353 arranges for the thread handle to be automatically closed when
354 the thread exits, thus preventing handle leaks and/or the need to
355 track all the threads and close their handles when they exit.
356 Also, MSDN seems to imply that code which uses CRT _must_ call
357 _beginthread, although if that is true, we already violate that
358 rule in many places... */
359 thandle
= _beginthread (w32_beginthread_wrapper
, stack_size
, arg
);
360 if (thandle
== (uintptr_t)-1L)
363 /* Kludge alert! We use the Windows thread ID, an unsigned 32-bit
364 number, as the sys_thread_t type, because that ID is the only
365 unique identifier of a thread on Windows. But _beginthread
366 returns a handle of the thread, and there's no easy way of
367 getting the thread ID given a handle (GetThreadId is available
368 only since Vista, so we cannot use it portably). Fortunately,
369 the value returned by sys_thread_create is not used by its
370 callers; instead, run_thread, which runs in the context of the
371 new thread, calls sys_thread_self and uses its return value;
372 sys_thread_self in this implementation calls GetCurrentThreadId.
373 Therefore, we return some more or less arbitrary value of the
374 thread ID from this function. */
375 *thread_ptr
= thandle
& 0xFFFFFFFF;
380 sys_thread_yield (void)