Commit 6b611d36 authored by Henrik Gramner's avatar Henrik Gramner

Linux: Add a workaround for a glibc stack size issue

parent eb211838
......@@ -84,13 +84,15 @@ test_args = []
optional_arguments = []
# Define _POSIX_C_SOURCE to POSIX.1–2001 (IEEE Std 1003.1-2001)
test_args += '-D_POSIX_C_SOURCE=200112L'
add_project_arguments('-D_POSIX_C_SOURCE=200112L', language: 'c')
if host_machine.system() == 'darwin'
if host_machine.system() == 'linux'
test_args += '-D_GNU_SOURCE'
add_project_arguments('-D_GNU_SOURCE', language: 'c')
elif host_machine.system() == 'darwin'
test_args += '-D_DARWIN_C_SOURCE'
add_project_arguments('-D_DARWIN_C_SOURCE', language: 'c')
else
test_args += '-D_POSIX_C_SOURCE=200112L'
add_project_arguments('-D_POSIX_C_SOURCE=200112L', language: 'c')
endif
if host_machine.system() == 'windows'
......@@ -131,6 +133,12 @@ else
endif
endif
libdl_dependency = []
if host_machine.system() == 'linux'
libdl_dependency = cc.find_library('dl', required : false)
endif
# Header checks
stdatomic_dependency = []
......
......@@ -31,6 +31,10 @@
#include <errno.h>
#include <string.h>
#ifdef __linux__
#include <dlfcn.h>
#endif
#include "dav1d/dav1d.h"
#include "dav1d/data.h"
......@@ -94,7 +98,19 @@ COLD int dav1d_open(Dav1dContext **const c_out, const Dav1dSettings *const s) {
pthread_attr_t thread_attr;
if (pthread_attr_init(&thread_attr)) return DAV1D_ERR(ENOMEM);
pthread_attr_setstacksize(&thread_attr, 1024 * 1024);
size_t stack_size = 1024 * 1024;
#ifdef __linux__
/* glibc has an issue where the size of the TLS is subtracted from the stack
* size instead of allocated separately. As a result the specified stack
* size may be insufficient when used in an application with large amounts
* of TLS data. The following is a workaround to compensate for that.
* See https://sourceware.org/bugzilla/show_bug.cgi?id=11787 */
size_t (*const get_minstack)(const pthread_attr_t*) =
dlsym(RTLD_DEFAULT, "__pthread_get_minstack");
if (get_minstack)
stack_size += get_minstack(&thread_attr) - PTHREAD_STACK_MIN;
#endif
pthread_attr_setstacksize(&thread_attr, stack_size);
Dav1dContext *const c = *c_out = dav1d_alloc_aligned(sizeof(*c), 32);
if (!c) goto error;
......
......@@ -278,6 +278,7 @@ libdav1d = library('dav1d',
stdatomic_dependency,
thread_dependency,
thread_compat_dep,
libdl_dependency,
],
c_args : [stackalign_flag, api_export_flags],
version : dav1d_soname_version,
......
......@@ -72,9 +72,10 @@ static inline int pthread_attr_destroy(pthread_attr_t *const attr) {
}
static inline int pthread_attr_setstacksize(pthread_attr_t *const attr,
const unsigned stack_size)
const size_t stack_size)
{
attr->stack_size = stack_size;
if (stack_size > UINT_MAX) return 1;
attr->stack_size = (unsigned) stack_size;
return 0;
}
......
......@@ -90,7 +90,12 @@ if is_asm_enabled
include_directories: dav1d_inc_dirs,
c_args: [stackalign_flag, stackrealign_flag],
build_by_default: false,
dependencies : [thread_dependency, rt_dependency, m_lib],
dependencies : [
thread_dependency,
rt_dependency,
libdl_dependency,
m_lib,
],
)
test('checkasm', checkasm, is_parallel: false)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment