aboutsummaryrefslogtreecommitdiff
path: root/helper
diff options
context:
space:
mode:
authorJere Leppänen <jere.leppanen@nokia.com>2021-08-10 15:47:33 +0300
committerPetri Savolainen <petri.savolainen@nokia.com>2021-09-30 11:10:11 +0300
commit36fd6663b71343e09659d7ed5b30788e97d5a8e9 (patch)
tree0fedcda9867e117f637182de7281628e3c956bed /helper
parent84c474392f411a72185a9b62b82778fd30a36c3e (diff)
helper: threads: add thread stack size parameter
Add a parameter in odph_thread_param_t, which allows specifying the minimum thread stack size. This parameter is used only in odph_thread_create(), it is ignored in odph_odpthreads_create(). Signed-off-by: Jere Leppänen <jere.leppanen@nokia.com> Reviewed-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'helper')
-rw-r--r--helper/include/odp/helper/threads.h6
-rw-r--r--helper/threads.c50
2 files changed, 50 insertions, 6 deletions
diff --git a/helper/include/odp/helper/threads.h b/helper/include/odp/helper/threads.h
index 983537f9d..fda9a3b4f 100644
--- a/helper/include/odp/helper/threads.h
+++ b/helper/include/odp/helper/threads.h
@@ -69,6 +69,12 @@ typedef struct {
/** @deprecated ODP instance handle for odph_odpthreads_create(). */
odp_instance_t instance;
+ /**
+ * Minimum stack size in bytes. 0 = use default. Ignored by
+ * odph_odpthreads_create().
+ */
+ uint64_t stack_size;
+
} odph_thread_param_t;
/** Helper internal thread start arguments. Used both in process and thread
diff --git a/helper/threads.c b/helper/threads.c
index 181ea66eb..9326e12e6 100644
--- a/helper/threads.c
+++ b/helper/threads.c
@@ -15,6 +15,10 @@
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include <odp_api.h>
#include <odp/helper/threads.h>
@@ -81,7 +85,7 @@ static void *run_thread(void *arg)
/*
* Create a single linux process
*/
-static int create_process(odph_thread_t *thread, int cpu)
+static int create_process(odph_thread_t *thread, int cpu, uint64_t stack_size)
{
cpu_set_t cpu_set;
pid_t pid;
@@ -118,6 +122,22 @@ static int create_process(odph_thread_t *thread, int cpu)
return -2;
}
+ if (stack_size) {
+ struct rlimit rlimit;
+
+ if (getrlimit(RLIMIT_STACK, &rlimit)) {
+ ODPH_ERR("getrlimit() failed: %s\n", strerror(errno));
+ return -3;
+ }
+
+ rlimit.rlim_cur = stack_size;
+
+ if (setrlimit(RLIMIT_STACK, &rlimit)) {
+ ODPH_ERR("setrlimit() failed: %s\n", strerror(errno));
+ return -4;
+ }
+ }
+
run_thread(&thread->start_args);
return 0; /* never reached */
@@ -160,7 +180,7 @@ static int wait_process(odph_thread_t *thread)
/*
* Create a single linux pthread
*/
-static int create_pthread(odph_thread_t *thread, int cpu)
+static int create_pthread(odph_thread_t *thread, int cpu, uint64_t stack_size)
{
int ret;
cpu_set_t cpu_set;
@@ -175,6 +195,24 @@ static int create_pthread(odph_thread_t *thread, int cpu)
pthread_attr_setaffinity_np(&thread->thread.attr,
sizeof(cpu_set_t), &cpu_set);
+ if (stack_size) {
+ /*
+ * Round up to page size. "On some systems,
+ * pthread_attr_setstacksize() can fail with the error EINVAL if
+ * stacksize is not a multiple of the system page size." (man
+ * page)
+ */
+ stack_size = (stack_size + ODP_PAGE_SIZE - 1) & ~(ODP_PAGE_SIZE - 1);
+
+ if (stack_size < PTHREAD_STACK_MIN)
+ stack_size = PTHREAD_STACK_MIN;
+
+ if (pthread_attr_setstacksize(&thread->thread.attr, stack_size)) {
+ ODPH_ERR("pthread_attr_setstacksize() failed\n");
+ return -1;
+ }
+ }
+
thread->start_args.mem_model = ODP_MEM_MODEL_THREAD;
ret = pthread_create(&thread->thread.thread_id,
@@ -283,10 +321,10 @@ int odph_thread_create(odph_thread_t thread[],
odp_atomic_init_u32(&start_args->status, NOT_STARTED);
if (use_pthread) {
- if (create_pthread(&thread[i], cpu))
+ if (create_pthread(&thread[i], cpu, start_args->thr_params.stack_size))
break;
} else {
- if (create_process(&thread[i], cpu))
+ if (create_process(&thread[i], cpu, start_args->thr_params.stack_size))
break;
}
@@ -390,10 +428,10 @@ int odph_odpthreads_create(odph_odpthread_t *thread_tbl,
start_args->instance = thr_params->instance;
if (helper_options.mem_model == ODP_MEM_MODEL_THREAD) {
- if (create_pthread(&thread_tbl[i], cpu))
+ if (create_pthread(&thread_tbl[i], cpu, 0))
break;
} else {
- if (create_process(&thread_tbl[i], cpu))
+ if (create_process(&thread_tbl[i], cpu, 0))
break;
}