Skip to content
Snippets Groups Projects
Commit df95f525 authored by Damien George's avatar Damien George
Browse files

py/modthread: Allow to properly set the stack limit of a thread.

We rely on the port setting and adjusting the stack size so there is
enough room to recover from hitting the stack limit.
parent eef4f13a
Branches
No related tags found
No related merge requests found
......@@ -107,32 +107,37 @@ STATIC void freertos_entry(void *arg) {
}
}
void mp_thread_create(void *(*entry)(void*), void *arg, size_t stack_size) {
void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
// store thread entry function into a global variable so we can access it
ext_thread_entry = entry;
if (stack_size == 0) {
stack_size = 2048; // default stack size
if (*stack_size == 0) {
*stack_size = 4096; // default stack size
} else if (*stack_size < 2048) {
*stack_size = 2048; // minimum stack size
}
mp_thread_mutex_lock(&thread_mutex, 1);
// create thread
StackType_t *stack = m_new(StackType_t, stack_size / sizeof(StackType_t));
StackType_t *stack = m_new(StackType_t, *stack_size / sizeof(StackType_t));
StaticTask_t *task_buf = m_new(StaticTask_t, 1);
TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", stack_size / sizeof(void*), arg, 2, stack, task_buf);
TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", *stack_size / sizeof(void*), arg, 2, stack, task_buf);
if (id == NULL) {
mp_thread_mutex_unlock(&thread_mutex);
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, "can't create thread"));
}
// adjust stack_size to provide room to recover from hitting the limit
*stack_size -= 512;
// add thread to linked list of all threads
thread_t *th = m_new_obj(thread_t);
th->id = id;
th->ready = 0;
th->arg = arg;
th->stack = stack;
th->stack_len = stack_size / sizeof(StackType_t);
th->stack_len = *stack_size / sizeof(StackType_t);
th->next = thread;
thread = th;
......
......@@ -160,6 +160,7 @@ STATIC mp_obj_t mod_thread_stack_size(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_thread_stack_size_obj, 0, 1, mod_thread_stack_size);
typedef struct _thread_entry_args_t {
size_t stack_size;
mp_obj_t fun;
size_t n_args;
size_t n_kw;
......@@ -175,7 +176,7 @@ STATIC void *thread_entry(void *args_in) {
mp_thread_set_state(&ts);
mp_stack_set_top(&ts + 1); // need to include ts in root-pointer scan
mp_stack_set_limit(16 * 1024); // fixed stack limit for now
mp_stack_set_limit(args->stack_size);
MP_THREAD_GIL_ENTER();
......@@ -256,11 +257,14 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
th_args->n_args = pos_args_len;
memcpy(th_args->args, pos_args_items, pos_args_len * sizeof(mp_obj_t));
// set the stack size to use
th_args->stack_size = thread_stack_size;
// set the function for thread entry
th_args->fun = args[0];
// spawn the thread!
mp_thread_create(thread_entry, th_args, thread_stack_size);
mp_thread_create(thread_entry, th_args, &th_args->stack_size);
return mp_const_none;
}
......
......@@ -40,7 +40,7 @@ struct _mp_state_thread_t;
struct _mp_state_thread_t *mp_thread_get_state(void);
void mp_thread_set_state(void *state);
void mp_thread_create(void *(*entry)(void*), void *arg, size_t stack_size);
void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size);
void mp_thread_start(void);
void mp_thread_finish(void);
void mp_thread_mutex_init(mp_thread_mutex_t *mutex);
......
......@@ -133,10 +133,12 @@ void mp_thread_start(void) {
pthread_mutex_unlock(&thread_mutex);
}
void mp_thread_create(void *(*entry)(void*), void *arg, size_t stack_size) {
// default stack size is 8k machine-words
if (stack_size == 0) {
stack_size = 8192 * BYTES_PER_WORD;
void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
// default stack size is 8k machine-words, minimum is 2k
if (*stack_size == 0) {
*stack_size = 8192 * BYTES_PER_WORD;
} else if (*stack_size < 2048 * BYTES_PER_WORD) {
*stack_size = 2048 * BYTES_PER_WORD;
}
// set thread attributes
......@@ -145,7 +147,7 @@ void mp_thread_create(void *(*entry)(void*), void *arg, size_t stack_size) {
if (ret != 0) {
goto er;
}
ret = pthread_attr_setstacksize(&attr, stack_size);
ret = pthread_attr_setstacksize(&attr, *stack_size);
if (ret != 0) {
goto er;
}
......@@ -160,6 +162,9 @@ void mp_thread_create(void *(*entry)(void*), void *arg, size_t stack_size) {
goto er;
}
// adjust stack_size to provide room to recover from hitting the limit
*stack_size -= 1024 * BYTES_PER_WORD;
// add thread to linked list of all threads
thread_t *th = malloc(sizeof(thread_t));
th->id = id;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment