1
votes

I am working on a timer now, timers are maintained by a linked list.Like this:

struct timer
{
    struct timer* prev;
    struct timer* next;
    struct timespec start;
    struct timespec interval;
    void* par; 
    int (*handler) (void* par);
};

Then I use a thread called dispatch to sleep and pick timers from the list.The code is simplified as below:

//just pseudo code here
void dispatch() {
    for (;;) {
        while (list_empty()) {
            wait();
        }
        timer* ptr = listhead();
        if (timer_begin(ptr)) {
            ptr->handler(ptr->par);
            list_pop_front();
        }
    }
}

Question: When there is a long precedure in the callback function handler(say the handler function costs 500ms to execute, then dispatch stucks), the rest timers in the list may not be processed in time.So do we need a thread pool here?Or is there any other advices?

1

1 Answers

2
votes

The problem of long duration tasks interleaved with short duration tasks is a fundamental problem of real-time (and near-real-time) systems. Having a separate thread to handle longer running tasks, and delegating longer tasks to a second thread is a good solution. But is your long-running task waiting on io, or just heavy processing?

Should the delay be caused by asynchronous processing (waiting on io, for example), You might split the work into a 'top-half' and a 'bottom-half', where the 'top-half' dispatches the io request, and then schedules a 'bottom-half' to check for the results. Alternatives are to handle the signal from the response, possibly with a promise (really interesting technique).

Should the delay be cause by a processing heavy task, you might still be able to use a similar technique, by forming your compute heavy task in such a way that it 'yields' periodically. Threading is better, but may not be available in some embedded environments.