the efficient way to implement an asynchronous delayed work

I need to implement an asynchronous delayed work function, let’s name it “delayed_work(int nanoseconds, void *cb_func)”, which delays for a pre-defined time before being executed, The calling process doesn’t block on this function call. It’s just like the linux function “queue_delayed_work”. Here are 2 options that’s what I can think out of:

  1. Using timeout event and signal.
    struct sigaction act;

    event.sigev_notify = SIGEV_SIGNAL;
    SIGEV_SIGNAL_INIT( &event, my_signal);
    act.sa_handler = cd_func;
    sigaction(my_signal, act, NULL);

    timer_create(CLOCK_REALTIME, &event, &timer_id);

  2. Using timeout event and pulse message.
    In this case, I have to create a new thread which is dedicated to process time out event:

SIGEV_PULSE_INIT(&event, ConnectAttach(ND_LOCAL_NODE, 0, channelId, _NTO_SIDE_CHANNEL, 0), SIGEV_PULSE_PRIO_INHERIT, 0, userId);
timer_create(CLOCK_REALTIME, &event, &timer_id);

//the following code is in a seperate new thread
while (1)
{
// Wait till the timer expires.
if ((MsgReceive(channelId, &msg, sizeof(Message), NULL)) >= 0)
{
cb_func();
}

After doing some search on the forum, I found the second option is preferred. But I am wondering if the new creating thread consumes more resources.

So my question is, is there any existing system function that does this delayed call back work for me? Like I set up a timer, and pass into the call back function pointer, later on when the time expires, the system automatically run my call back function.

I check the “ClockPeriod()”, it seems that every tick the system has an interrupt which it can do some periodical routine work, does it expose some call back function interface to the user?

Yes a thread consume some resources but if you start it in advances then at least there is no run-time cost in creating the threads.

I use the Poco C++ library for this kind of stuff.

You can hook an ISR to the system timer interrupt ( 0 on x86 ).

Is it done by "InterruptAttach(SYSPAGE_ENTRY(qtime)->intr,&timerHandler,NULL,0,0); "? The interrupt occurs at a frequency pre-defined by “ClockPeriod()”?

So I can put my user code at timerHandler call back function, like:
void *timerHandler()
{
timer_counter++;
if(timer_counter > expires)
my_cb_func();
}

Compared with option 2 which uses event pulse and thread, which one is better?

Which one is better depends on your requirement.

I would stay away from using any interrupt all together and stick with a thread instead. Easier to debug, don’t have to deal with ClockPeriod()

The problem with the ISR is that if your function crashes it takes the whole machine down. InterruptAttachEvent you be better if you insist on using interrupt.

I would write a module that simulate the linux functions and hide the detail of the threads in these functions.

My concern with the thread option is in SMP condition, does the timer thread have to be bound to a specific CPU?

Say you create your timer and init the timer thread in CPU 1, later on you set your timer out in CPU 2, will it cause some problem? Which CPU will generate the timer out event?

SMP is irrelevant in this case. The kernel will take of all the details for you and make best use of the available CPUs. The short answer this will not be a problem at all.

If your design is broken on a SMP then you can force the process/threads to run on specific CPU.