Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/videolan/dav1d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Gramner <gramner@twoorioles.com>2019-05-03 16:01:04 +0300
committerHenrik Gramner <henrik@gramner.com>2019-05-04 22:58:02 +0300
commit2756254fc6ba402c5b6ab345944d0878975ed715 (patch)
treeace10546f1201c056478f58492e9cc867c9964c6
parent1d5c1a493742503838b12f108e041644d4838656 (diff)
Control the stack size of spawned threads
On some systems (e.g. Google Fuchsia) the default stack size of new threads is insufficient, resulting in crashes. On other systems the default stack size is unnecessarily large, which can waste a lot of virtual memory. By setting it to a sufficiently large fixed value we can ensure that we don't run out of stack space while keeping down memory usage.
-rw-r--r--src/lib.c11
-rw-r--r--src/thread.h22
-rw-r--r--src/win32/thread.c8
3 files changed, 35 insertions, 6 deletions
diff --git a/src/lib.c b/src/lib.c
index 0088024..88aaf83 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -90,6 +90,10 @@ int dav1d_open(Dav1dContext **const c_out,
validate_input_or_ret(s->operating_point >= 0 &&
s->operating_point <= 31, -EINVAL);
+ pthread_attr_t thread_attr;
+ if (pthread_attr_init(&thread_attr)) return -ENOMEM;
+ pthread_attr_setstacksize(&thread_attr, 512 * 1024);
+
Dav1dContext *const c = *c_out = dav1d_alloc_aligned(sizeof(*c), 32);
if (!c) goto error;
memset(c, 0, sizeof(*c));
@@ -151,7 +155,7 @@ int dav1d_open(Dav1dContext **const c_out,
goto error;
}
t->tile_thread.fttd = &f->tile_thread;
- if (pthread_create(&t->tile_thread.td.thread, NULL, dav1d_tile_task, t)) {
+ if (pthread_create(&t->tile_thread.td.thread, &thread_attr, dav1d_tile_task, t)) {
pthread_cond_destroy(&t->tile_thread.td.cond);
pthread_mutex_destroy(&t->tile_thread.td.lock);
goto error;
@@ -167,7 +171,7 @@ int dav1d_open(Dav1dContext **const c_out,
pthread_mutex_destroy(&f->frame_thread.td.lock);
goto error;
}
- if (pthread_create(&f->frame_thread.td.thread, NULL, dav1d_frame_task, f)) {
+ if (pthread_create(&f->frame_thread.td.thread, &thread_attr, dav1d_frame_task, f)) {
pthread_cond_destroy(&f->frame_thread.td.cond);
pthread_mutex_destroy(&f->frame_thread.td.lock);
goto error;
@@ -182,10 +186,13 @@ int dav1d_open(Dav1dContext **const c_out,
c->intra_edge.root[BL_64X64] = &c->intra_edge.branch_sb64[0].node;
dav1d_init_mode_tree(c->intra_edge.root[BL_64X64], c->intra_edge.tip_sb64, 0);
+ pthread_attr_destroy(&thread_attr);
+
return 0;
error:
if (c) close_internal(c_out, 0);
+ pthread_attr_destroy(&thread_attr);
return -ENOMEM;
}
diff --git a/src/thread.h b/src/thread.h
index f8da628..b2529fc 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -40,11 +40,15 @@ typedef struct {
void *arg;
} pthread_t;
+typedef struct {
+ unsigned stack_size;
+} pthread_attr_t;
+
typedef SRWLOCK pthread_mutex_t;
typedef CONDITION_VARIABLE pthread_cond_t;
typedef INIT_ONCE pthread_once_t;
-int dav1d_pthread_create(pthread_t *thread, const void *attr,
+int dav1d_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*func)(void*), void *arg);
int dav1d_pthread_join(pthread_t *thread, void **res);
int dav1d_pthread_once(pthread_once_t *once_control,
@@ -54,6 +58,22 @@ int dav1d_pthread_once(pthread_once_t *once_control,
#define pthread_join(thread, res) dav1d_pthread_join(&(thread), res)
#define pthread_once dav1d_pthread_once
+static inline int pthread_attr_init(pthread_attr_t *const attr) {
+ attr->stack_size = 0;
+ return 0;
+}
+
+static inline int pthread_attr_destroy(pthread_attr_t *const attr) {
+ return 0;
+}
+
+static inline int pthread_attr_setstacksize(pthread_attr_t *const attr,
+ const unsigned stack_size)
+{
+ attr->stack_size = stack_size;
+ return 0;
+}
+
static inline int pthread_mutex_init(pthread_mutex_t *const mutex,
const void *const attr)
{
diff --git a/src/win32/thread.c b/src/win32/thread.c
index c3fb557..2c2a578 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -41,13 +41,15 @@ static unsigned __stdcall thread_entrypoint(void *const data) {
return 0;
}
-int dav1d_pthread_create(pthread_t *const thread, const void *const attr,
+int dav1d_pthread_create(pthread_t *const thread,
+ const pthread_attr_t *const attr,
void *(*const func)(void*), void *const arg)
{
+ const unsigned stack_size = attr ? attr->stack_size : 0;
thread->func = func;
thread->arg = arg;
- thread->h = (HANDLE)_beginthreadex(NULL, 0, thread_entrypoint,
- thread, 0, NULL);
+ thread->h = (HANDLE)_beginthreadex(NULL, stack_size, thread_entrypoint, thread,
+ STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
return !thread->h;
}