diff options
| -rw-r--r-- | configure.ac | 17 | ||||
| -rw-r--r-- | src/systhread.c | 58 | ||||
| -rw-r--r-- | src/systhread.h | 5 | ||||
| -rw-r--r-- | src/thread.c | 5 | ||||
| -rw-r--r-- | src/thread.h | 3 |
5 files changed, 55 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac index de4710f150a..068ef5c20c6 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -4183,6 +4183,23 @@ getpwent endpwent getgrent endgrent \ | |||
| 4183 | cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np) | 4183 | cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np) |
| 4184 | LIBS=$OLD_LIBS | 4184 | LIBS=$OLD_LIBS |
| 4185 | 4185 | ||
| 4186 | if test "$ac_cv_func_pthread_setname_np" = "yes"; then | ||
| 4187 | AC_CACHE_CHECK( | ||
| 4188 | [whether pthread_setname_np takes a single argument], | ||
| 4189 | [emacs_cv_pthread_setname_np_1arg], | ||
| 4190 | [AC_COMPILE_IFELSE( | ||
| 4191 | [AC_LANG_PROGRAM( | ||
| 4192 | [[#include <pthread.h>]], | ||
| 4193 | [[pthread_setname_np ("a");]])], | ||
| 4194 | [emacs_cv_pthread_setname_np_1arg=yes], | ||
| 4195 | [emacs_cv_pthread_setname_np_1arg=no])]) | ||
| 4196 | if test "$emacs_cv_pthread_setname_np_1arg" = "yes"; then | ||
| 4197 | AC_DEFINE( | ||
| 4198 | HAVE_PTHREAD_SETNAME_NP_1ARG, 1, | ||
| 4199 | [Define to 1 if pthread_setname_np takes a single argument.]) | ||
| 4200 | fi | ||
| 4201 | fi | ||
| 4202 | |||
| 4186 | dnl No need to check for posix_memalign if aligned_alloc works. | 4203 | dnl No need to check for posix_memalign if aligned_alloc works. |
| 4187 | AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break]) | 4204 | AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break]) |
| 4188 | AC_CHECK_DECLS([aligned_alloc], [], [], [[#include <stdlib.h>]]) | 4205 | AC_CHECK_DECLS([aligned_alloc], [], [], [[#include <stdlib.h>]]) |
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 |
diff --git a/src/systhread.h b/src/systhread.h index 5368acfb52c..005388fd5a4 100644 --- a/src/systhread.h +++ b/src/systhread.h | |||
| @@ -112,10 +112,11 @@ extern sys_thread_t sys_thread_self (void) | |||
| 112 | extern bool sys_thread_equal (sys_thread_t, sys_thread_t) | 112 | extern bool sys_thread_equal (sys_thread_t, sys_thread_t) |
| 113 | ATTRIBUTE_WARN_UNUSED_RESULT; | 113 | ATTRIBUTE_WARN_UNUSED_RESULT; |
| 114 | 114 | ||
| 115 | extern bool sys_thread_create (sys_thread_t *, const char *, | 115 | extern bool sys_thread_create (sys_thread_t *, thread_creation_function *, |
| 116 | thread_creation_function *, void *) | 116 | void *) |
| 117 | ATTRIBUTE_WARN_UNUSED_RESULT; | 117 | ATTRIBUTE_WARN_UNUSED_RESULT; |
| 118 | 118 | ||
| 119 | extern void sys_thread_yield (void); | 119 | extern void sys_thread_yield (void); |
| 120 | extern void sys_thread_set_name (const char *); | ||
| 120 | 121 | ||
| 121 | #endif /* SYSTHREAD_H */ | 122 | #endif /* SYSTHREAD_H */ |
diff --git a/src/thread.c b/src/thread.c index f7e39dc4273..c7fe0614269 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -725,6 +725,9 @@ run_thread (void *state) | |||
| 725 | self->m_stack_bottom = self->stack_top = (char *) &stack_pos; | 725 | self->m_stack_bottom = self->stack_top = (char *) &stack_pos; |
| 726 | self->thread_id = sys_thread_self (); | 726 | self->thread_id = sys_thread_self (); |
| 727 | 727 | ||
| 728 | if (self->thread_name) | ||
| 729 | sys_thread_set_name (self->thread_name); | ||
| 730 | |||
| 728 | acquire_global_lock (self); | 731 | acquire_global_lock (self); |
| 729 | 732 | ||
| 730 | /* Put a dummy catcher at top-level so that handlerlist is never NULL. | 733 | /* Put a dummy catcher at top-level so that handlerlist is never NULL. |
| @@ -832,7 +835,7 @@ If NAME is given, it must be a string; it names the new thread. */) | |||
| 832 | else | 835 | else |
| 833 | new_thread->thread_name = NULL; | 836 | new_thread->thread_name = NULL; |
| 834 | sys_thread_t thr; | 837 | sys_thread_t thr; |
| 835 | if (! sys_thread_create (&thr, c_name, run_thread, new_thread)) | 838 | if (! sys_thread_create (&thr, run_thread, new_thread)) |
| 836 | { | 839 | { |
| 837 | /* Restore the previous situation. */ | 840 | /* Restore the previous situation. */ |
| 838 | all_threads = all_threads->next_thread; | 841 | all_threads = all_threads->next_thread; |
diff --git a/src/thread.h b/src/thread.h index e96a063a10b..a09929fa440 100644 --- a/src/thread.h +++ b/src/thread.h | |||
| @@ -169,8 +169,7 @@ struct thread_state | |||
| 169 | interrupter should broadcast to this condition. */ | 169 | interrupter should broadcast to this condition. */ |
| 170 | sys_cond_t *wait_condvar; | 170 | sys_cond_t *wait_condvar; |
| 171 | 171 | ||
| 172 | /* Thread's name in the locale encoding. Actually used only on | 172 | /* Thread's name in the locale encoding. */ |
| 173 | WINDOWSNT. */ | ||
| 174 | char *thread_name; | 173 | char *thread_name; |
| 175 | 174 | ||
| 176 | /* This thread might have released the global lock. If so, this is | 175 | /* This thread might have released the global lock. If so, this is |