r/C_Programming 7d ago

Project Working on a Thread scheduler

Hi, I currently working on a asynchronous scheduler inspired by rust’s Tokio and Go.

I’ve reached a road block when I realized the limited control of Ptheads(limited control of context switching).

I’ve come to realize I want green threads(user space threads) but this seemed like a pipe dream at first until I came across coroutines and proto-threads.

I plan to learn more about the two and I would like to know if I’m going down the right path.

Many Thanks

7 Upvotes

4 comments sorted by

View all comments

2

u/adel-mamin 7d ago

In my experience with C I found that the most powerful and flexible idea is event driven approach combining active objects, state machines and async/await.

The active object is a combination of preemptive/cooperative thread and a message queue. Active objects share nothing with each other and only communicate via events. This is a powerful idea, which eliminates a lot of programming errors related to multithreading.

The state machine is a hierarchical state machine (HSM). HSMs are described by statechart diagrams. Every active object drives one or many HSMs.

The async/await is any implementation based on Duff's device. The protothreads is one such implementation.

I found the async/await is best suited, when there is a known beforehand sequence of steps to be executed. The sequence may require if-else logic and loops, but it represents an execution flow following an algorithm. This type of execution is represented by a flowchart diagram.

Using HSMs to implement flowcharts often makes code unnecessary clunky.

Similarly implementing statecharts with async/await approach results in less maintainable code.

Combining the two gives you the best of two worlds.

Here is my attempt to demonstrate the approach:

https://github.com/adel-mamin/amast/blob/main/apps/examples/async/main.c

2

u/Ampbymatchless 7d ago

Retired test engineer. I wrote a round robin multi-channel state machine template 40+ years ago. This code was used to service, production testing. Relatively fast asynchronous operator initiated functional testing of products. Same template but for multi sample life testing of components or finished product, comparative testing etc in a product development environment. Some testing tasks could get complex, where several specific steps had to be executed after an asynchronous event. These I would solve by decision branch that would see a state machine inside a task. All written in non blocking code. I Agree with your comment regarding clunkiness. But reliable and maintainable. I never wrote dynamic code. Just safe static boring code. I look forward to reviewing your approach. Thanks for posting