How to create a non single-shot timer in C? - c

I need to use a non single shot Timer (such as QTimer from the Qt library) in a C code for embedded Linux (by no single shot Timer I mean one that triggers once ever x seconds indefinitely till a "stop timer" is called, not one that triggers only once or one that blocks the code while it's counting).
Some libraries that are available to me do implement such a timer using signal handlers, but I would like to avoid using such a system (I learned that is not the best solution). I know I can emulate what I want with single shot Timers by restarting the timer (calling it again) once it's finished, and that is an acceptable solution (actually the libraries I talked about work that way), but I don't know how to implement that without blocking the running code till the timer is triggered.
And one more thing: I need to be capable of implementing more then just one of them (here is where signal handlers stop being a viable solution AFAIK).
So how could I do such a solution? The closes to what Qt's QTimer has to offer, the better!

If you do need an unspecified number of triggers at varying intervals/times, a dedicated timer thread (as described by nneonneo in another answer) has the least number of pitfalls in my experience.
Timers are a limited resource (the number of timers available is configurable, and varies from system to system, so you cannot make any sweeping statements like "I'm sure there's enough for my purposes").
Signals interrupt blocking syscalls unless SA_RESTART flag is used; even then there are a few exceptions (see man 7 signal, Interruption of system calls and library functions by signal handlers chapter for details).
A dedicated timer thread is built around two components:
A queue, list, tree, or heap holding all timer events
A typical implementation only needs to know when the next event occurs, so a min-heap or a priority queue works quite well. I've found a min-heap to be simple and robust to implement, and efficient enough (O(log N) time complexity for both inserts and deletes); using absolute times (using CLOCK_MONOTONIC in Linux) for the events as keys.
Note that if you use the timer events as timeouts, you'll also need to make sure cancelling an event is efficient. In normal operation, timeouts are rare, so something like a web server is likely to cancel just about all the timeouts it sets, without any of them actually ever triggering.
A thread that waits for either the next event, or another thread inserting a new timer event
Personally, I use an array to hold the min-heap of events, protected by a pthread_mutex_t, with a pthread_cond_t for other threads to signal on after adding a new event. Then, it's a simple matter to use pthread_cond_timedwait() to wait/sleep for either the specified time, or until a thread notifies of a new event, whichever happens sooner.
When the next event occurs -- note that due to scheduling, you might find more than one separate event to occur, so you might not wish to sleep at all (but you might still check if new events were added) --, you perform the event. If the event is periodic, you reinsert it into the heap/queue, too, primed for the next time.
Choosing how events are performed is very important, and really, the only truly tricky bit. You can use flags -- switching from zero to nonzero is safe in practice, even if the change is not atomic, as long as you don't rely on any specific nonzero value --; you can cause a condition variable to be signaled or broadcast on; you can post a semaphore; you can raise a specific signal in a specific thread (even an empty signal handler will cause blocking I/O calls to interrupt, if the handler is installed without SA_RESTART flag; I've used this as an I/O timeout quite successfully); you can even use __atomic or __sync to modify a value atomically if using GCC (or Intel CC, Pathscale, or Portland Group C compilers); and so on.
If you need a specific function to be called, I recommend using a separate thread (or, if most of the work in the application/program/game is done in these timer events, a thread pool) to execute the events. This keeps the timer thread simple and precise, while keeping all resource use easily controlled. The worker thread or thread pool should simply have a FIFO queue of events protected by a mutex and a condition variable, so that the timer thread can add each event to the queue and then signal on the condition variable to notify the (next) worker thread that work is available.
Indeed, in the couple of instances I used other event action models, I now believe the function worker model would have been easier. Especially if you make the worker functions to take a pointer (to a structure), defined by the caller, so that they all have the same signature, this interface becomes quite straightforward to implement, but extremely powerful and versatile.
There is one downside to the timer-thread plus worker-thread(s) approach, and that is the (minimal) added latency. The worker thread will not get the work at the appointed time, but a short while afterwards. However, if you have the worker thread get the current time, compare to the (un-adjusted) target time, and use that as a statistic to trigger the events correspondingly prior to the target time, you can typically take care of this issue. (I have not verified, but I do believe both Qt and GTK+ toolkits do continuously estimate this latency in a similar if not same manner.)
Questions?

You have several options, none of which require any libraries beyond the standard C and POSIX libraries.
POSIX timers API, e.g. timer_create and friends. These have flexible notification scheme based on sigev, which allows you to specify how you want to be notified (signal to a specific thread, creation of a new thread, or arbitrary signal). By specifying that the signal goes to a specific thread, you can set that thread up to be ready for async signals, and use sig_atomic_t to signal work to be done by the thread. The most interesting notification option is to use the creation of a brand new thread, but note that this can get expensive if the timer fires frequently.
Linux timerfd API, e.g. timerfd_create. These create timers that you can poll with poll or epoll, enabling you to add the timers to a low-level event loop, as well as operate on them in a perfectly thread-safe and signal-safe way.
alarm. This uses the SIGALRM asynchronous signal, so again you'll want to use sig_atomic_t and a signal-processing thread to handle the timer.
select, poll, or nanosleep on a dedicated timer thread: This is what QTimer usually does under the covers. You simply create a dedicated timer thread and have the thread repeatedly sleep. To keep the timer on schedule, you adjust the sleep time based on the length of each processing cycle.
The last option is the most portable, but also basically the most work (since you're implementing the timer yourself). The upshot is that you get to customize the "timer" completely since you're implementing it on top of a sleep primitive.

Related

Is it good to use Semaphore in tasklet execution ISR resource usage

I want to use Semaphore in a one of the Bottom half technique in Tasklet timer interrupts, but i know from theory that tasklet won't sleep but semaphore do sleep. any solution for this ?
The job of bottom halves is to perform any interrupt-related work not performed by the interrupt handler itself you want the interrupt handler to perform as little work (and in turn be as fast) as possible and return ASAP to the interrupted code / process.
Tasklets are a bottom-half mechanism built on top of softirqs. Work queue is another interface for creating kernel threads to handle work that is queued later on. If it must sleep, use work queues. Otherwise, use tasklets.
Spinlocks are always a better choice in dealing with synchronization mechanisms in bottom halves, specially in cases where you are using softirq's or tasklets.
Semaphores: (are only in older 2.6.16 kernels), as mutex's appread after that kernel version. Its recommended to use mutex's when serializing code in the process context.

Can del_timer return while its handler is running?

I'm looking at some Linux kernel module code that starts and stops timers using add_timer and del_timer.
Sometimes, the implementation goes on to delete the timer "object" (the struct timer_list) right after calling del_timer.
I'd like to find out is if this is safe. Note that this is a uniprocessor implementation, with SMP disabled (which would mandate the use of del_timer_sync instead).
The del_timer_sync implementation checks if the timer is being handled anywhere right now, but del_timer does not. On a UP system, is it possible to have the timer being handled without del_timer knowing, i.e. the timer has been removed from the pending timers list and is being handled?
UP makes things quite a bit simpler, but I think the answer is still "it depends."
If you are doing del_timer in process context, then on UP I think you are safe in assuming the timer is not running anywhere after that returns: the timers are removed from the pending lists and run from the timer interrupt, and if that interrupt starts, it will run to completion before allowing the process context code to continue.
However, if you are in interrupt context, then your interrupt might have interrupted the timer interrupt, and so the timer might be in the middle of being run.

sleeping on an event

I have a multi threaded program in which I sleep in one thread(Thread A) unconditionally for infinite time. When an event happens in another thread (Thread B), it wake up Thread-A by signaling. Now I know there are multiple ways to do it.
When my program runs in windows environment, I use WaitForSingleObject in Thread-A and SetEvent in the Thread-B. It is working without any issues.
I can also use file descriptor based model where I do poll, select. There are more than one way to do it.
However, I am trying to find which is the most efficient way. I want to wake up the Thread-A asap whenever Thread-B signals. What do you think is the best option.
I am ok to explore a driver based option.
Thanks
As said, triggering an SetEvent in thread B and a WaitForSingleObject in thread A is fast.
However some conditions have to be taken into account:
Single core/processor: As Martin says, the waiting thread will preempt the signalling thread. With such a scheme you should take care that the signalling thread (B) is going idle right after the SetEvent. This can be done by a sleep(0) for example.
Multi core/processor: One might think there is an advantage to put the two threads onto different cores/processors but this is not really such a good idea. If both threads are on the same core/processor, the time-span between calling SetEventand the return of WaitForSingleObject is much shorter shorter.
Handling both threads on one core (SetThreadAffinityMask) also allows to handle the behavior of them by means of their priority setting (SetThreadPriority). You may run the waiting thread at a higher priorty or you have to ensure that the signalling thread is really not doing anything after it has set the event.
You have to deal with some other synchronization matter: When is the next event going to happen? Will thread A have completed its task? Most effective a second event can be used to solve this matter: When thread A is done, it sets an event to indicate that thread B is allowed to set its event again. Thread B will effectively first set the event and then wait for the feedback event, it meets the requirment to go idle immedeately.
If you want to allow thread B to set the event even when thread A is not finished and not yet in a wait state, you should consider using semaphores instead of events. This way the number of "calls/events" from thread B is kept and the wait function in thread A can follow up, because it is returning for the number of times the semaphore has been released. Semaphore objects are about as fast as events.
Summary:
Have both threads on the same core/cpu by means of SetThreadAffinityMask.
Extend the SetEvent/WaitForSingleObject by another event to establish a Handshake.
Depending on the details of the processing you may also consider semaphore objects.

timer_create how to stop recursive thread function invocation after first timer expiry?

I have created a timer using the simple "timer_create". The timer is created using SIGEV_THREAD. That is when the timer expires, there is a call to the timer thread function.
How timer_create works is, suppose assume: expiry=3 secs and timer interval is 1 ns, then the timer keeps ticking every 1 ns until expiry reaches. Once the timer expires, from that instance it keeps on hitting the timer thread function after every 1 ns (timer interval). And keeps on creating one thread per hit till the timer is deleted.
I don't want this to happen, i want once the timer expires, it should go and hit the thread function only once.
How can i achieve this? Can we put any option in timer_create? If not any other timer API?
Thanks a lot in advance
I think this is an implementation flaw in the glibc implementation of POSIX timers. There is certainly no way the timer_getoverrun function, which is critical for realtime usage, can work in the glibc implementation, since it returns from the kernel the overrun count for the "current" expiration, but when multiple expiration events are running in parallel, "current" makes no sense. There are also serious issues with resource exhaustion and dropped expiration events which make the implementation unusable for realtime purposes. For example, in nptl/sysdeps/unix/sysv/linux/timer_routines.c:
struct thread_start_data *td = malloc (sizeof (*td));
/* There is not much we can do if the allocation fails. */
...
In the Linux man page for sigevent, you see for SIGEV_THREAD:
Among the implementation possibilities here are that each timer notification could result in the creation of a new thread, or that a single thread is created to receive all notifications.
The latter is the only choice that could provide correct realtime semantics, but for some reason, glibc did not take this choice.
Here is a possible workaround:
Choose a realtime signal, block that signal before creating any threads, and setup your timer to use that signal with SIGEV_SIGNAL. Now, create a thread for handling your timer(s), and loop on sigwaitinfo, then call your handler function each time it returns. This is actually one possible implementation (and the most-correct implementation) of SIGEV_THREAD which glibc should be using.
Another possibility: there is exactly one synchronization-related, non-syscall-invoking, async-signal-safe function in POSIX: sem_post. Thus it may be possible to make a signal handler (as opposed to getting the signal from sigwaitinfo) synchronize with another thread for the purpose of delivering timer events. But I haven't worked out the details, and it seems like it may be difficult or impossible still.
Just set timer interval to 0 and expiry to whatever you want. Your timer will expire once (and thread created and run) and then stay disarmed.

Gracefully (i.e eventually cooperatively) suspend thread execution

I have to develop an application that tries to emulate the executing flow of an embedded target. This target has 2 levels of priority : the highest one being preemptive on the lowest one. The low priority level is managed with a round-robin scheduler which gives 1ms of execution to each thread in turn.
My goal is to write a library that provide the thread_create, thread_start, and all the system calls that are available on my target and use POSIX functions to reproduce the behavior natively on a standard PC.
Thus, when an high priority thread executes, low priority threads should be suspended whatever they are doing at that very moment. It is to the responsibility of the low priority thread's implementation to ensure that it won't be perturbed.
I now it is usually unsafe to suspend a thread, which explains why I didn't find any "suspend(pid)" function.
I basically imagine two solutions to the problem :
-find a way to suspend the low priority threads when a high priority thread starts (and resume them when there is no more high priority activity)
-periodically call a very small "suspend_if_necessary" function everywhere in my low-priority code, and whenever an high priority must start, wait for all low-priority process to call that function and be suspended, execute as single high priority thread, then resume them all.
Even if it is not-so-clean, I quite like the second solution, but still have one problem : how to call the function everywhere without changing all my code?
I wonder if there is an easy way to doing that, somewhat like debugging code does : add a hook call at every line executed that checks for a flag and run some specific code when that flag changes?
I'd be very happy if there is an easy solution to that problem, since I really need to be representative with the behavior of the target execution flow...
Thanks in advance,
Goulou.
Unfortunately, it's not really possible to implement what you want with true threads - even if the high prio thread is restarted, it can take arbitrarily long before the high prio thread is scheduled back in and goes to suspend all the low priority threads. Moreover, there is no reliable way to determine whether the high priority thread is blocked or not using only POSIX threads; you could try tracking things manually, but this runs the risk of both false positives (the thread's blocked on something, but the low prio threads think it's running and suspend itself) and false negatives (you miss a resumed annotation, or there's lag between when the thread's actually resumed and when it marks itself as running).
If you want to implement a thread priority system with pure POSIX, one option is to not use threads, but rather use setcontext for cooperative multitasking. This would allow you to swap between threads at a user level. However you must explicitly yield the CPU in this case. It also doesn't help with blocking syscalls, which would then block all threads in your app; but since you're writing an emulator this might not be an issue.
You may also be able to swap threads using setcontext within a signal handler; I've not tested this case myself, but it could be worth a try scheduling using setcontext in a SIGALRM handler.
To suspend a thread, you sleep it. If you want to be able to wake it on command, sleep it using sigwait, which puts the thread to sleep until it gets a signal. You can send a specific thread a signal with pthread_kill (crazy name, but it actually just sends signals to a thread). This is a very fast way to sleep and wake up threads. 40x Faster than condition variables and very easy.

Resources