Replace __pthread_get_minstack() with a const

This commit is contained in:
Azat Khuzhin 2021-06-20 10:00:15 +03:00
parent 9a3a1397e6
commit 4dcbf3a5c5
2 changed files with 19 additions and 41 deletions

View File

@ -8,37 +8,8 @@
extern "C" { extern "C" {
#endif #endif
#include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <assert.h>
/// glibc __pthread_get_minstack() will take TLS into account for the minimal
/// stack size (since you cannot use stack less then TLS block size, otherwise
/// some variables may be overwritten)
///
/// So glibc implementation is:
///
/// sysconf(_SC_PAGESIZE) + __static_tls_size + PTHREAD_STACK_MIN;
///
/// But this helper cannot do this since:
/// - __pthread_get_minstack() is hidden in libc (note that rust tried to do
/// this but revert it to retry loop, for compatibility, while we cannot
/// use retry loop since this function is used for sigaltstack())
/// - __static_tls_size is not exported in glibc
/// - it is not used anywhere except for clickhouse itself (for sigaltstack(),
/// to handle SIGSEGV only) and using PTHREAD_STACK_MIN (16k) is enough right
/// now.
///
/// Also we cannot use getStackSize() (pthread_attr_getstack()) since it will
/// return 8MB, and this is too huge for signal stack.
size_t __pthread_get_minstack(const pthread_attr_t * attr)
{
_Static_assert(PTHREAD_STACK_MIN == 16<<10, "Too small return value of __pthread_get_minstack()");
return PTHREAD_STACK_MIN;
}
#include <signal.h> #include <signal.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <sys/syscall.h> #include <sys/syscall.h>
@ -163,6 +134,8 @@ int __open_2(const char *path, int oflag)
} }
#include <pthread.h>
/// No-ops. /// No-ops.
int pthread_setname_np(pthread_t thread, const char *name) { return 0; } int pthread_setname_np(pthread_t thread, const char *name) { return 0; }
int pthread_getname_np(pthread_t thread, char *name, size_t len) { name[0] = '\0'; return 0; }; int pthread_getname_np(pthread_t thread, char *name, size_t len) { name[0] = '\0'; return 0; };

View File

@ -8,13 +8,7 @@
#include <Poco/Logger.h> #include <Poco/Logger.h>
#include <common/getThreadId.h> #include <common/getThreadId.h>
#include <signal.h> #include <csignal>
/// NOTE: clickhouse provide override for this function that will return
/// PTHREAD_STACK_MIN=16K (for compatibility reasons),
/// but this should be enough for signal stack.
extern "C" size_t __pthread_get_minstack(const pthread_attr_t * attr);
namespace DB namespace DB
@ -34,22 +28,33 @@ thread_local ThreadStatus * main_thread = nullptr;
namespace namespace
{ {
/// Alternative stack for signal handling.
///
/// This stack should not be located in the TLS (thread local storage), since:
/// - TLS locates data on the per-thread stack
/// - And in case of stack in the signal handler will grow too much,
/// it will start overwriting TLS storage
/// (and note, that it is not too small, due to StackTrace obtaining)
/// - Plus there is no way to determine TLS block size, yes there is
/// __pthread_get_minstack() in glibc, but it is private and hence not portable.
///
/// Also we should not use getStackSize() (pthread_attr_getstack()) since it
/// will return 8MB, and this is too huge for signal stack.
struct ThreadStack struct ThreadStack
{ {
ThreadStack() ThreadStack()
: size(__pthread_get_minstack(nullptr)) : data(aligned_alloc(4096, size))
, data(aligned_alloc(4096, size))
{} {}
~ThreadStack() ~ThreadStack()
{ {
free(data); free(data);
} }
size_t getSize() const { return size; } static size_t getSize() { return size; }
void* getData() const { return data; } void* getData() const { return data; }
private: private:
size_t size; static constexpr size_t size = 16 << 10;
void *data; void *data;
}; };