sleep vs SIG_ALARM usage and CPU performance - c

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.

Related

Minimum time quantum needed in nanosleep(), usleep() to yield the CPU

In concurrent code in my workplace, there are several occurrences of nanosleep() or usleep() with a non-zero constant to free up the CPU without relying on futex(), or a sleeping synchronization primitive to put the thread to sleep (for instance, when waiting for an element from a concurrent queue). The code claims to prevent pathological cases where threads consume CPU without doing any actual work when other threads are available to get scheduled on that CPU. This sounds reasonable by itself assuming the cooperation between the sleep functions and the kernel thread scheduler is correct.
Is there a concept in linux where a minimum duration passed to nanosleep(), usleep(), et al. is known to put the calling thread to sleep and run another thread in it's place on the same core when cores are oversubscribed? And if the duration is smaller than that, then the thread does not actually yield the CPU but continue spinning? This forms the basis of the constant passed to the sleep() functions in order to make it behave like a coarse-yield.
I realize that a sched_yield() is probably better suited for what the code is doing; but I just wanted to educate myself on the behavior of the linux sleep() functions before benchmarking a replacement or improvement on the existing code.
Thanks!
The man page makes it clear that it no longer busy-waits.
In order to support applications requiring much more precise pauses
(e.g., in order to control some time-critical hardware), nanosleep()
would handle pauses of up to 2 milliseconds by busy waiting with
microsecond precision when called from a thread scheduled under a
real-time policy like SCHED_FIFO or SCHED_RR. This special extension
was removed in kernel 2.5.39, and is thus not available in Linux
2.6.0 and later kernels.
#stark has answered your question as written, but to elaborate, don't do that. If you're waiting for an event to happen, perform an operation that waits for the event, like pthread_cond_wait, sem_wait, poll, read, etc. rather than sleeping and retrying. This will avoid wasting lots of cpu time, and it also discourages erroneous programming models full of data races (because normally the same primitive that waits also ensures exclusive access/synchronization).

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.

timer in a thread with pthread in C?

in threads, i need to periodically do some work in some different intervals, what would be a good way to do this? With sleep(), then i need keep track of the interval to the next wakeup, which doesn't seem to be the best way.
thanks.
You can use clock_nanosleep with the TIMER_ABSTIME flag to work with absolute times instead of relative times for your sleep. That will avoid error accumulation problems and race conditions where your program gets interrupted and another process scheduled after getting the current time but before calling sleep.
Alternatively you could use POSIX timers (timer_create) with a signal handler, where the signal you choose is blocked in all threads but yours, or with timer delivery in a new thread that signals a condition variable or semaphore your thread is waiting on.
Depends on how much accuracy you need:
you can use clock_gettime Which is very accurate (~10MHz). (Go with the realtime or monotonic clock)
If resolution and overhead is not a problem, but instead you would like to get the real-world time you can also you gettimeofday

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.

How to avoid the interruption of sleep calls due to a signal in Linux?

I'm using a real time signal in Linux to be notified of the arrival of new data in a serial port. Unfortunately this causes sleep calls to be interrupted when there is signal.
Does anybody know of a way to avoid this behavior?
I tried using a regular signal (SIGUSR1) but I keep getting the same behavior.
From the nanosleep manpage:
nanosleep delays the execution of the program for at least the time specified in *req. The function can return earlier if a signal has been delivered to the process. In this case, it returns -1, sets errno to EINTR, and writes the remaining time into the structure pointed to by rem unless rem is NULL. The value of *rem can then be used to call nanosleep again and complete the specified pause.
You can mask almost all signals (except SIGKILL) using sigprocmask() or signal() calls. The first one will return you the previous mask, which you can recover after sleep(). Some examples are here. If that does not help, please, be more verbose of what signal interrupts your sleep. I think, you can additionally check this condition ("sleep interrupted by signal?") and fall into sleep again.
Newer Linux kernels support signalfd(2). That, together with sigprocmask(2), is a very nice way to combine handling of signal and IO events in a single epoll_wait(2) call.
If you don't want to be interrupted, why are you using the real time signal?
Somewhere, either in Rockind's "Advanced Unix Programming" or Steven's book, there was an example of how to fake this out. You make note of the current time_t before starting your sleep. After the sleep ends, you check to make sure the required amount of time has elapsed, and if it hasn't, you start a new sleep. Put the sleep in a loop that calculates the time to go and sleeps that amount, and exits when the required time has passed.
Well, a realtime signal is supposed to interrupt sleep. You could use a non-realtime signal instead. Another approach is to check if the expected time to sleep has elapsed, and if not, sleep for the remaining interval.

Resources