portability: cmsis: Remove max limit on new statically created threads

Clarify thread Kconfigs to denote the maximum number of dynamically
allocated control blocks and stacks for threads. Allow application to
create any number of threads with statically allocated control block
and stack.

Signed-off-by: Utsav Munendra <utsavm@meta.com>
This commit is contained in:
Utsav Munendra 2025-02-18 09:48:56 +05:30 committed by Benjamin Cabé
commit c006922b22
3 changed files with 45 additions and 26 deletions

View file

@ -16,23 +16,20 @@ config CMSIS_RTOS_V2
if CMSIS_RTOS_V2
config CMSIS_V2_THREAD_MAX_COUNT
int "Maximum thread count in CMSIS RTOS V2 application"
int "Maximum thread count in CMSIS RTOS V2 application with dynamic control blocks"
default 15
range 0 $(UINT8_MAX)
help
Mention max number of threads in CMSIS RTOS V2 compliant application.
There's a limitation on the number of threads due to memory
related constraints.
Max number of threads in CMSIS RTOS V2 application that can be created with
dynamically allocated control block.
config CMSIS_V2_THREAD_DYNAMIC_MAX_COUNT
int "Maximum dynamic thread count in CMSIS RTOS V2 application"
int "Maximum thread count in CMSIS RTOS V2 application with dynamic stack"
default 0
range 0 $(UINT8_MAX)
help
Mention max number of dynamic threads in CMSIS RTOS V2 compliant
application. There's a limitation on the number of threads due to memory
related constraints. Dynamic threads are a subset of all other CMSIS
threads i.e. they also count towards that maximum too.
Max number of threads in CMSIS RTOS V2 application that can be created with
dynamically allocated stack.
config CMSIS_V2_THREAD_MAX_STACK_SIZE
int "Max stack size threads can be allocated in CMSIS RTOS V2 application"

View file

@ -26,10 +26,11 @@ static const osThreadAttr_t init_thread_attrs = {
};
static sys_dlist_t thread_list;
static atomic_t thread_num;
static atomic_t num_dynamic_cb;
#if CONFIG_CMSIS_V2_THREAD_MAX_COUNT != 0
static struct cmsis_rtos_thread_cb cmsis_rtos_thread_cb_pool[CONFIG_CMSIS_V2_THREAD_MAX_COUNT];
#endif
static atomic_t num_dynamic_stack;
#if CONFIG_CMSIS_V2_THREAD_DYNAMIC_MAX_COUNT != 0
@ -106,17 +107,11 @@ osThreadId_t osThreadNew(osThreadFunc_t threadfunc, void *arg, const osThreadAtt
static uint32_t one_time;
void *stack;
size_t stack_size;
uint32_t this_thread_num;
uint32_t this_dynamic_cb;
if (k_is_in_isr()) {
return NULL;
}
if (thread_num >= CONFIG_CMSIS_V2_THREAD_MAX_COUNT) {
return NULL;
}
if (attr == NULL) {
attr = &init_thread_attrs;
}
@ -139,9 +134,6 @@ osThreadId_t osThreadNew(osThreadFunc_t threadfunc, void *arg, const osThreadAtt
BUILD_ASSERT(osPriorityISR <= CONFIG_NUM_PREEMPT_PRIORITIES,
"Configure NUM_PREEMPT_PRIORITIES to at least osPriorityISR");
BUILD_ASSERT(CONFIG_CMSIS_V2_THREAD_DYNAMIC_MAX_COUNT <= CONFIG_CMSIS_V2_THREAD_MAX_COUNT,
"Number of dynamic threads cannot exceed max number of threads.");
BUILD_ASSERT(CONFIG_CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE <=
CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE,
"Default dynamic thread stack size cannot exceed max stack size");
@ -150,18 +142,18 @@ osThreadId_t osThreadNew(osThreadFunc_t threadfunc, void *arg, const osThreadAtt
__ASSERT((cv2_prio >= osPriorityIdle) && (cv2_prio <= osPriorityISR), "invalid priority\n");
if (attr->stack_mem != NULL) {
if (attr->stack_size == 0) {
return NULL;
}
if (attr->stack_mem != NULL && attr->stack_size == 0) {
return NULL;
}
this_thread_num = atomic_inc(&thread_num);
#if CONFIG_CMSIS_V2_THREAD_MAX_COUNT != 0
if (attr->cb_mem == NULL) {
uint32_t this_dynamic_cb;
this_dynamic_cb = atomic_inc(&num_dynamic_cb);
tid = &cmsis_rtos_thread_cb_pool[this_dynamic_cb];
} else {
} else
#endif
{
tid = (struct cmsis_rtos_thread_cb *)attr->cb_mem;
}

View file

@ -417,4 +417,34 @@ ZTEST(cmsis_thread_apis, test_thread_apis_join_after_exit)
status = osThreadJoin(id);
zassert_equal(status, osOK, "osThreadJoin failed with status=%d!", status);
}
static K_THREAD_STACK_DEFINE(test_stack9, STACKSZ);
static struct cmsis_rtos_thread_cb test_cb9;
static const osThreadAttr_t os_thread9_attr = {
.name = "Thread9",
.attr_bits = osThreadJoinable,
.cb_mem = &test_cb9,
.cb_size = sizeof(test_cb9),
.stack_mem = &test_stack9,
.stack_size = STACKSZ,
.priority = osPriorityNormal,
};
static void thread9(void *argument)
{
osThreadExit();
}
ZTEST(cmsis_thread_apis, test_thread_apis_multiple_new_static)
{
osThreadId_t id;
osStatus_t status;
for (int i = 0; i < 100; i++) {
id = osThreadNew(thread9, NULL, &os_thread9_attr);
zassert_not_null(id,
"Failed to create thread with osThreadNew using static cb/stack");
status = osThreadJoin(id);
zassert_equal(status, osOK, "osThreadJoin failed with status=%d!", status);
}
}
ZTEST_SUITE(cmsis_thread_apis, NULL, NULL, NULL, NULL, NULL);