Create new signal or multiplex SIGALRM? - c

I am trying to write a benchmark that receives a signal from the kernel telling it to adjust its parameters. I'm trying to study whether a proactive or reactive approach works best.
In the proactive approach, I use setitimer to set an alarm periodically and force the benchmark to look at its performance thus far and re-tune itself.
In the reactive approach, the kernel periodically monitors the process and signals it if it is performing poorly.
Since I've been using the setitimer functionality, and since setitimer causes SIGALRM, I have asked the kernel to throw a SIGALRM in the reactive approach. This has been working fine. However, now I need to use SIGALRM to run the benchmark for a specific duration of time.
Is there a way to multiplex SIGALRM to serve both purposes - to do a timed run and terminate and to re-tune. Is there a function/syscall similar to setitimer that allows the user to set an alarm but with a custom signal?

Yes. You want to look at the timer_create / timer_settime etc., family of calls.
The 2nd parameter of timer_create is a struct sigevent. The field within that, sigev_signo can be set to send a specific signal number on timer expiration.

Related

sleep vs SIG_ALARM usage and CPU performance

When should I use sleep() and a reconfiguration of SIG_ALRM?
For example, I'm thinking of scheduling some task at some specific time. I could spawn a thread with an sleep() call inside and when sleep() returns, do some task, or I could specify a handler for SIG_ALRM and do the task inside the alarm interrupt. Do they take the same CPU usage and time? (besides the thread).
I've done some "tests" looking at the processes with ps command, showing me a CPU % and a CPU TIME of 0, but I'm wondering if I'm missing something or I'm looking at the wrong data.
BTW, I'm using Linux.
Note that what you do in a signal handler is very limited. You can only call certain POSIX functions and most of the C library is not allowed. Certainly not any C functions that might allocate or free memory or do I/O (you can use some POSIX I/O calls).
The sleeping thread might be the easiest way for you to go. If you use nanosleep it won't cause a signal at all, so you won't need to mess with handlers and such.
If your program is doing work, a common pattern is to have a central work loop, and in that loop you can check the time periodically to see if you should run your delayed job. Or you can skip checking the time and check a flag variable instead which your SIG_ALARM handler will set. Setting a sig_atomic_t variable is one of the things a signal handler is allowed to do.
CPU usage for a sleeping task is zero. It goes into the kernel as a timer event and is woken up to run when the timer expires.

How to create a non single-shot timer in 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.

Running select() socket and timers in the same linux thread

I am writing code on ucLinux for socket communication. I use select() for reading the data on sockets. I also have a 20 msec timer (created using setitimer) running in the same thread for performing a parallel operation. My select function gets blocked each time saying "Interrupted by system call", since it receives the SIGALRM signal issue by the timer on overflow, every 20 msec. I tried restarting the system when EINTR is issued, and run select() again. but this wont help, since i will always receive the SIGALRM by timer every 20 msec. I dont want to ignore this signal since it is used for performing other tasks in the system, but i want to use select without being affected by this signal. Is there any way to handle this? I cannot use functions like timer_create() as these are not supported on the platform I am using. So, I am stuck up with using setitimerfor timer creation. Is there any way I can run both together independently in my code?
What you're doing is pretty weird. Let's face it: timers are an ancient and mostly-obsolete mechanism for doing work. Pretty much everyone these days avoids signals like the plague. There's essentially nothing useful you can do in a signal callback (you certainly can't call anything complicated like malloc for example), so you must have some way to get the timer notification back from the SIGALRM handler to the main thread already -- you're not actually doing the work in the signal handler are you?
So you have two tactics: use the standard self-pipe trick to turn the signal into an event on an fd, the "normal" way to handle things like SIGTERM, SIGINT and so on. You call socketpair or pipe to make a pipe, then write a byte into the pipe from the signal handler. You read the byte back from you select loop. You commonly write the value of the signal as the data, but you could write anything really.
The other tactic (much more sane) is to avoid the mess with signals and setitimer completely. setitimer is seriously legacy and causes problems for all sorts of things (eg. it can cause functions like getaddrinfo to hang, a bug that still hasn't been fixed in glibc (http://www.cygwin.org/frysk/bugzilla/show_bug.cgi?id=15819). Signals are bad for your health. So the "normal" tactic is to use the timeout argument to select. You have a linked list of timers, objects you use to manager periodic events in your code. When you call select, you use as the timeout the shortest of your remaining timers. When the select call returns, you check if any timers are expired and call the timer handler as well as the handlers for your fd events. That's a standard application event loop. This way your loop code so you can listen for timer-driven events as well as fd-driven events. Pretty much every application on your system uses some variant on this mechanism.
Is an option for you doing something like this?
While(1) {
int rc = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
if ((rc < 0) && (errno == EINTR) )
continue;
else {
// some instructions
}
}
If this is not an option for you you can probably use pselect which adds a parameter to the end (sigmask) which specifies a set of signals that should be blocked during the pselect(), see here

Is alarm(unsigned int second) function thread_safe?

With alarm function, I want to implement UDP retransmission. Is this function thread safe? Will it work under multi-threaded environment.
Calling alarm() in a thread will not reset pending signals, so you probably don't want to call it in a thread. You'd only want to call it within the parent no matter what language you are using if the underlying functionality is pthreads.
You'd probably be better off making provisions in a structure shared with the threads to re-send data as needed, or poke all (or some) running threads to resend upon servicing the signal in the parent.
I can't think of an implementation where calling it within a thread would be a good idea, so no - I wouldn't use it that way.
alarm() function is not thread safe.
Because it is process level. You can't control which thread should receive the signal once timer triggers. So at the time of signal arrival, another thread may be running. Sometimes it may crash you program with SIG_SEGV.
According to the docs alarm is "process-level" and only the last call is active... it uses the SIGNAL model and sends an async SIGALARAM to the process... whether the called signal handler is threadsafe depends on your implementation...

Handling 'intterupted system call' error when using timer

I'm writing an application that uses timer to do some data acquisition and processing at a fix sample rate (200Hz).
The application acts like a server and run in background. It should be controllable from other processes or other machines from UDP.
To do so, I use the timer_create() API to generate SIGUSR1 periodically and call an handler that do the acquisition and the processing.
The code to configure the timer is as follow (minus error check for clarity):
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGUSR1;
sev.sigev_value.sival_ptr = &timerid;
timer_create(CLOCK_REALTIME, &sev, &timerid);
timer_settime(...)
The code above is called when a 'start' command is received from UDP. To check for command I have an infinite loop in my main program that call recvfrom() syscall.
The problem is, when a 'start' command is received, and then, the timer is properly started and running (using the code above), I get an 'interrupted system calls' error (EINTR) due the SIGUSR1 signal sent by the timer interrupting the recvfrom() call. If I check for this particular error code and ignore it, I finally get a 'connection refused' error when calling recvfrom().
So here my questions:
How to solve this 'interrupted system calls' error as it seems to
ignore it and re-do the recvfrom() doesn't work?
Why do I get the 'connection refused' error after about twenty tries?
I have the feeling that using SIGEV_THREAD could be a solution, as I understand it, create a new thread (like phread_create) without generate a signal. Am I right?
Is the signal number important here? Is there any plus to use real time signal?
Is there any other way to do what I intent to do: having a background loop checking for command from UDP and real-time periodic task?
And here the bonus question:
Is it safe to do the data acquisition and the processing in the handler or should I use a semaphore mechanism to wake up a thread that do it?
Solution:
As suggest in an answer and in the comments, using SA_RESTART seems to fix the main issue.
Solution 2:
Using SIGEV_THREAD over SIGEV_SIGNAL works too. I've read somewhere that using SIGEV_THREAD could require more ressources than SIGEV_SIGNAL. However I have not seen significant difference regarding the timing of the task.
Timers tend to be implemented using SIGALARM.
Signal receipt, including SIGALARM, tends to cause long running system calls to return early with EINTR in errno.
SA_RESTART is one way around this, so system calls interrupted by receipt of a signal, will be automatically restarted. Another is to check for EINTR from your system calls' errno's and restart them when you receive EINTR.
With read() and write() of course, you can't just restart, you need to pick up where you left off. That's why these return the length of data transmitted.
Given that you're using Linux, I would opt for using timerfd_create instead.
That way you can just select(2), poll(2) or epoll(7) instead and handle timer events without the difficulty of signal handlers in your main loop.
As for EINTR (Interrupted System Call), those are properly handled by just restarting the specific system call that got interrupted.
Restarting the interrupted system call is the correct response to EINTR. You "Connection Refused" problem is an unrelated error - on a UDP socket, it indicates that a previous packet sent on that socket was rejected by the destination (notified through an ICMP message).
Question 5: Your use of a message and real-time periodic thread is perfectly fine. However, I would suggest you avoid using timers altogether, precisely because they use signals. I've run into this problem myself and eventually replaced the timer with a simple clock_nanosleep() that uses TIMER_ABSTIME with time updated to maintain the desired rate (i.e. add the period to the absolute time). The result was simpler code, no more problems with signals, and a more accurate timer than the signal-based timer. BTW, you should measure your timer's period in the handler to make sure it is accurate enough. My experience with timers was 8 years ago, so the problem with accuracy might be fixed. However, the other problems with signals are inherent to signals themselves and thus can't be "solved" -- only worked around.
Also, I see no problem with doing data acquisition from the handler, it should certainly reduce latency in retrieving the data.

Resources