diff options
| author | Mattias EngdegÄrd | 2020-01-07 17:08:25 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2020-01-07 17:57:31 +0100 |
| commit | 73fd8a4b535928990f24702cdfaeeeceb6d33d3d (patch) | |
| tree | 56cd425a191c863f87cd4d2b0742464fea8b540a /src/systhread.c | |
| parent | f54b24304decc52defbf12576993d746e02a80ee (diff) | |
| download | emacs-73fd8a4b535928990f24702cdfaeeeceb6d33d3d.tar.gz emacs-73fd8a4b535928990f24702cdfaeeeceb6d33d3d.zip | |
Fix BSD and macOS builds w.r.t. pthread_setname_np (bug#38632)
pthread_setname_np takes only a single argument on BSD and macOS,
and affects the current thread only.
* configure.ac: Add check for single-argument pthread_setname_np
* src/systhread.c (sys_thread_set_name): New (w32 and pthread versions).
(sys_thread_create): Remove name argument and name-setting.
(w32_beginthread_wrapper): Remove name-setting.
* src/systhread.h (sys_thread_create, sys_thread_set_name):
Update prototypes.
* src/thread.c (run_thread): Call sys_thread_set_name.
(Fmake_thread): Adapt call to sys_thread_create.
* src/thread.h (struct thread_state): Adjust comment.
Diffstat (limited to 'src/systhread.c')
| -rw-r--r-- | src/systhread.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/src/systhread.c b/src/systhread.c index 1dda036cc2f..2c3a060a17e 100644 --- a/src/systhread.c +++ b/src/systhread.c | |||
| @@ -200,9 +200,28 @@ sys_thread_equal (sys_thread_t t, sys_thread_t u) | |||
| 200 | return pthread_equal (t, u); | 200 | return pthread_equal (t, u); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | void | ||
| 204 | sys_thread_set_name (const char *name) | ||
| 205 | { | ||
| 206 | #ifdef HAVE_PTHREAD_SETNAME_NP | ||
| 207 | /* We need to truncate here otherwise pthread_setname_np | ||
| 208 | fails to set the name. TASK_COMM_LEN is what the length | ||
| 209 | is called in the Linux kernel headers (Bug#38632). */ | ||
| 210 | #define TASK_COMM_LEN 16 | ||
| 211 | char p_name[TASK_COMM_LEN]; | ||
| 212 | strncpy (p_name, name, TASK_COMM_LEN - 1); | ||
| 213 | p_name[TASK_COMM_LEN - 1] = '\0'; | ||
| 214 | #ifdef HAVE_PTHREAD_SETNAME_NP_1ARG | ||
| 215 | pthread_setname_np (p_name); | ||
| 216 | #else | ||
| 217 | pthread_setname_np (pthread_self (), p_name); | ||
| 218 | #endif | ||
| 219 | #endif | ||
| 220 | } | ||
| 221 | |||
| 203 | bool | 222 | bool |
| 204 | sys_thread_create (sys_thread_t *thread_ptr, const char *name, | 223 | sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func, |
| 205 | thread_creation_function *func, void *arg) | 224 | void *arg) |
| 206 | { | 225 | { |
| 207 | pthread_attr_t attr; | 226 | pthread_attr_t attr; |
| 208 | bool result = false; | 227 | bool result = false; |
| @@ -221,22 +240,7 @@ sys_thread_create (sys_thread_t *thread_ptr, const char *name, | |||
| 221 | } | 240 | } |
| 222 | 241 | ||
| 223 | if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED)) | 242 | if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED)) |
| 224 | { | 243 | result = pthread_create (thread_ptr, &attr, func, arg) == 0; |
| 225 | result = pthread_create (thread_ptr, &attr, func, arg) == 0; | ||
| 226 | #ifdef HAVE_PTHREAD_SETNAME_NP | ||
| 227 | if (result && name != NULL) | ||
| 228 | { | ||
| 229 | /* We need to truncate here otherwise pthread_setname_np | ||
| 230 | fails to set the name. TASK_COMM_LEN is what the length | ||
| 231 | is called in the Linux kernel headers (Bug#38632). */ | ||
| 232 | #define TASK_COMM_LEN 16 | ||
| 233 | char p_name[TASK_COMM_LEN]; | ||
| 234 | strncpy (p_name, name, TASK_COMM_LEN - 1); | ||
| 235 | p_name[TASK_COMM_LEN - 1] = '\0'; | ||
| 236 | pthread_setname_np (*thread_ptr, p_name); | ||
| 237 | } | ||
| 238 | #endif | ||
| 239 | } | ||
| 240 | 244 | ||
| 241 | out: ; | 245 | out: ; |
| 242 | int error = pthread_attr_destroy (&attr); | 246 | int error = pthread_attr_destroy (&attr); |
| @@ -457,26 +461,24 @@ w32_set_thread_name (DWORD thread_id, const char *name) | |||
| 457 | 461 | ||
| 458 | static thread_creation_function *thread_start_address; | 462 | static thread_creation_function *thread_start_address; |
| 459 | 463 | ||
| 464 | void | ||
| 465 | sys_thread_set_name (const char *name) | ||
| 466 | { | ||
| 467 | w32_set_thread_name (GetCurrentThreadId (), name); | ||
| 468 | } | ||
| 469 | |||
| 460 | /* _beginthread wants a void function, while we are passed a function | 470 | /* _beginthread wants a void function, while we are passed a function |
| 461 | that returns a pointer. So we use a wrapper. See the command in | 471 | that returns a pointer. So we use a wrapper. See the command in |
| 462 | w32term.h about the need for ALIGN_STACK attribute. */ | 472 | w32term.h about the need for ALIGN_STACK attribute. */ |
| 463 | static void ALIGN_STACK | 473 | static void ALIGN_STACK |
| 464 | w32_beginthread_wrapper (void *arg) | 474 | w32_beginthread_wrapper (void *arg) |
| 465 | { | 475 | { |
| 466 | /* FIXME: This isn't very clean: systhread.c is not supposed to know | ||
| 467 | that ARG is a pointer to a thread_state object, or be familiar | ||
| 468 | with thread_state object's structure in general. */ | ||
| 469 | struct thread_state *this_thread = arg; | ||
| 470 | |||
| 471 | if (this_thread->thread_name) | ||
| 472 | w32_set_thread_name (GetCurrentThreadId (), this_thread->thread_name); | ||
| 473 | |||
| 474 | (void)thread_start_address (arg); | 476 | (void)thread_start_address (arg); |
| 475 | } | 477 | } |
| 476 | 478 | ||
| 477 | bool | 479 | bool |
| 478 | sys_thread_create (sys_thread_t *thread_ptr, const char *name, | 480 | sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func, |
| 479 | thread_creation_function *func, void *arg) | 481 | void *arg) |
| 480 | { | 482 | { |
| 481 | /* FIXME: Do threads that run Lisp require some minimum amount of | 483 | /* FIXME: Do threads that run Lisp require some minimum amount of |
| 482 | stack? Zero here means each thread will get the same amount as | 484 | stack? Zero here means each thread will get the same amount as |