Spawn multiple threads dynamically from inside a loop.

I would like to spawn multiple threads dynamically from inside a loop to create a simulation.

t0s: TaskA.0 runs for 4sec
t1s: TaskA.1 runs for 4sec
t2s: TaskA.2 runs for 4sec
t3s: TaskA.3 runs for 4sec
t4s: TaskA.4 runs for 4sec
...
t50s: TaskA.50 runs for 4sec

The same 4sec task begins every second, so the tasks overlap, but also expire. No more than 4 instances of the same task will run at any time. Spawning them from the loop works when the tasks don't overlap (delay between task > 4sec). CONFIG_USERSPACE=y allows me to reuse the thread.

Things crash when the threads overlap (delay between task(t) < 4sec).  I seem to be able to create k_thread as an array, but it's reusing "my_stack_area" which is probably a problem.  

Because this is predictable I might be able to create five separate threads that could overlap each other and use a loop 10x. But, I'm new to Zephyr/RTOS and want to know if there a way, or alternative approach, to accomplishing this with a single thread definition and without statically creating multiple threads to handle the overlap?

This code doesn't exactly work, but illustrates what I was thinking:

static int thread_count = 0;

extern void my_entry_point(void *, void *, void *)
{
	int mycount = thread_count;

	LOG_INF("thread: %d", mycount);
	//do something that takes 4000ms
	k_sleep(K_MSEC(4000));


	return;
}

#define MY_STACK_SIZE 2048
#define MY_PRIORITY 5

K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE);
struct k_thread my_thread_data[50];

int main(){
	for(int i = 0; i < 50; i++){
		thread_count++;
		LOG_INF("LOOP: %d", thread_count);

		k_thread_create(&my_thread_data[i], my_stack_area,
										K_THREAD_STACK_SIZEOF(my_stack_area),
										my_entry_point,
										NULL, NULL, NULL,
										MY_PRIORITY, 0, K_NO_WAIT);

		k_sleep(K_MSEC(1000));
	}
}

Parents
  • I never tried this, but I think having a common stack during the overlap period is the problem. Either split the stack into number of parts that you can have maximum number of overlaps at a time (which is 3 overlaps at a time) or have separate tasks.

    , to accomplishing this with a single thread definition and without statically creating multiple threads to handle the overlap?

    I think Zephyr is designed to best think in a statically creation of stuff. This was pretty evident when I started to use Zephyr for Bluetooth and saw the way the services were defined (statically).. 

    No I can't think of any way but I do not think that I have thought this through. If you manage to find a way, Please write it here so that I can learn a thing.

  • Thanks for your reply! I ended up creating additional threads with individual stacks statically, which removed the timing overlap and that worked as expected. I also suspect that with my dynamic approach the common stack is the problem. That makes sense... But Zephyr is new to me too and I wanted to get feedback on if I might be missing something obvious. If I have to readdress this I will update this post with anything I learn.

Reply
  • Thanks for your reply! I ended up creating additional threads with individual stacks statically, which removed the timing overlap and that worked as expected. I also suspect that with my dynamic approach the common stack is the problem. That makes sense... But Zephyr is new to me too and I wanted to get feedback on if I might be missing something obvious. If I have to readdress this I will update this post with anything I learn.

Children
No Data
Related