Multi-threaded resmgr


I have written a multi-threaded resource manager to manage incoming packets from a microcontroller which works fine. Now however, I want to add some watchdog timers to ensure that everything keeps moving properly.
I have come up with two options and it would be a great help if somebody could recommend one or the other and explain why.

(i) I could set up a timer that sends pulses on expiry. As I already have a dispatch interface, I could use pulse_attach(…) to catch the pulses. A “watchdog” function would then increment a variable and send a “stay awake” message to the hardware if the variable was over a certain value(i.e it has timed out).
If the hardware is functioning normally it sends a pulse that will result in the same variable being decremented (preventing a timeout).

As I am using a thread pool, will a new thread be started every time a pulse is received by dispatch_block() or will the pulses be queued until the last call to the pulse_attach function has completed?

(ii) My other option was to start a totally independent (of the TPool) thread and have it block on a MsgReceivePulse(…) . I would start a timer and create a channel linking the thread and the timer. Every time the timer expires the thread increments or decrements the variable, as before. This way I could ensure that there was never any more than one thread running that dealt with the watchdog timers .

In general, how does a thread pool decide how to allocate another thread for a task? e.g. I have calls to the select_attach and pulse_attach functions. Will it create a new thread that handles all select calls and one that deals with pulses, or will it create a new thread for every call to either the select_attach or pulse_attach functions?

I hope my question is clear and thanks in advance for any help that you can give.

I would personally opt for option (ii). By having a single thread dedicated to handling the timer pulses you won’t have to worry about being at your thread pool limits, thus starving off the processing of the timer pulse. The thread pool will initially create ‘n’ threads (determined by the _thread_pool_attr.lo_water parameter) to be in the blocked state. As these threads become unblocked, the thread pool will grow to a thread count of _thread_pool_attr.hi_water with an upper bound of _thread_pool_attr.maximum total threads (blocked+unblocked). If the number of threads in your thread pool reaches thread_pool_attr.maximum AND all the pool threads are in the unblocked (i.e. handling) state, any timer pulses that you receive will not get processed until one of the threads returns to the blocked state at which time it will become unblocked to process the timer pulse. So, if you run into a condition where your thread pool gets stressed, you may not be able to process the watchdog timer in sufficient time. By having a single thread (i.e. not controlled by the thread pool) to handle the watchdog timer, you can avoid this situation totally. Althoughthis could alos be avoided by tuning the thread pool parameters properly (but why bother with tuning if you can have asingle dedicated thread :wink: ).

Hi RoverFan,
Thanks for the reply. I had a preference for option (ii) myself, but I read in the QNX docs that if I had already created a dispatch interface it would make more sense to use that. I don’t think I would run into the problem of not having enough threads to service the timers, but I was concerned about the criteria that the dispatch layer uses to make calls to pthread_create. I thought I would probably be better off in this case to start the thread explicitly myself as I would have total control over it.
Thanks again for the reply!