will the timer started by "setitimer()" be restarted? - linux

Each task_struct in linux kernel has a field named "real timer", which is a struct hrtimer (high resolution timer). When we set a timer using setitimer, it sets the "real timer" in the process to be expired by the given value. When it is expired, the function named it_real_fn is called. Here is the source code in Linux kernel 2.6.39.4:
/*
* The timer is automagically restarted, when interval != 0
*/
enum hrtimer_restart it_real_fn(struct hrtimer *timer)
{
struct signal_struct *sig =
container_of(timer, struct signal_struct, real_timer);
trace_itimer_expire(ITIMER_REAL, sig->leader_pid, 0);
kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid);
return HRTIMER_NORESTART;
}
I found that it returns HRTIMER_NORESTART, which means it shall not be restarted. However, if we assign an interval value when calling setitimer, meaning that we want to trigger the timer at every interval, where shall the "real timer" be restarted?

You are correct in saying that the it_real_fn function will not restart the real-time timer but it is not the function that is called on timer expiration when using setitimer.
The setitimer function is part of the POSIX timers and their Linux implementation is in posix-timers.c, In this file, the function posix_timer_fn, which may return both HRTIMER_RESTART and HRTIMER_NORESTART is defined and assigned to the it_real_fn of the struct hrtimer (the code which sets this function as the timer callback is in common_timer_set, which is called by the POSIX timer initialization).

Related

What is the purpose of putting a thread on a wait queue with a condition when only one thread is allowed to enter?

On this request
ssize_t foo_read(struct file *filp, char *buf, size_t count,loff_t *ppos)
{
foo_dev_t * foo_dev = filp->private_data;
if (down_interruptible(&foo_dev->sem)
return -ERESTARTSYS;
foo_dev->intr = 0;
outb(DEV_FOO_READ, DEV_FOO_CONTROL_PORT);
wait_event_interruptible(foo_dev->wait, (foo_dev->intr= =1));
if (put_user(foo_dev->data, buf))
return -EFAULT;
up(&foo_dev->sem);
return 1;
}
With this completion
irqreturn_t foo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
foo->data = inb(DEV_FOO_DATA_PORT);
foo->intr = 1;
wake_up_interruptible(&foo->wait);
return 1;
}
Assuming foo_dev->sem is initially 1 then only one thread is allowed to execute the section after down_interruptible(&foo_dev->sem) and threads waiting for that semaphore make sense to be put in a queue.(As i understand making foo_dev->sem greater than one will be a problem in that code).
So if only one passes always whats the use of foo_dev->wait queue, isnt it possible to suspend the current thread, save its pointer as a global *curr and wake it up when it completes its request?
Yes, it is possible to put single thread to wait (using set_current_state() and schedule()) and resume it later (using wake_up_process).
But this requires writing some code for check wakeup conditions and possible absent of a thread to wakeup.
Waitqueues provide ready-made functions and macros for wait on condition and wakeup it later, so resulted code becomes much shorter: single macro wait_event_interruptible() processes checking for event and putting thread to sleep, and single macro wake_up_interruptible() processes resuming possibly absent thread.

Can two hrtimer callbacks in linux kernel run at the same time?

As stated in https://lwn.net/Articles/308545/ hrtimer callbacks run in hard interrupt context with irqs disabled.
But what about a SMP?
Can a second callback for another hrtimer run on another core,
while a first callback is allready running or do they exclude each other on all cores, so that no locking is needed between them?
edit:
When a handler for a "regular" hardware IRQ (let's call it X) is running on a core, all IRQs are disabled on only that core, but IRQ X is disabled on the whole system, so two handlers for X never run concurrently.
How do hrtimer interrupts behave in this regard?
Do they all share the same quasi IRQ, or is there one IRQ per hrtimer?
edit:
Did some experiments with two timers A and B:
// starting timer A to fire as fast as possible...
A_ktime = ktime_set(0, 1); // 1 NS
hrtimer_start( &A, A_ktime, HRTIMER_MODE_REL );
// starting timer B to fire 10 us later
B_ktime = ktime_set(0, 10000); // 10 us
hrtimer_start( &B, B_ktime, HRTIMER_MODE_REL );
Put some printks into the callbacks and a huge delay into the one for timer A
// fired after 1 NS
enum hrtimer_restart A(struct hrtimer *timer)
{
printk("timer A: %lu\n",jiffies);
int i;
for(i=0;i<10000;i++){ // delay 10 seconds (1000 jiffies with HZ 100)
udelay(1000);
}
printk("end timer A: %lu\n",jiffies);
return HRTIMER_NORESTART;
}
// fired after 10 us
enum hrtimer_restart B(struct hrtimer *timer)
{
printk("timer B: %lu\n",jiffies);
return HRTIMER_NORESTART;
}
Result was reproducible something like
[ 6.217393] timer A: 4294937914
[ 16.220352] end timer A: 4294938914
[ 16.224059] timer B: 4294938915
1000 jiffies after start of timer A,
when timer B was setup to fire after less than one jiffie after it.
When driving this further and increasing the delay to 70 seconds,
I got 7000 jiffies between start of timer A callback and timer B callback.
[ 6.218258] timer A: 4294937914
[ 76.220058] end timer A: 4294944914
[ 76.224192] timer B: 4294944915
edit:
Locking is probably required, because hrtimers
just get enqueued an any CPU. If two of them are enqueued on the same, it might happen, that they delay each other, but there is no guarantee.
from hrtimer.h:
* On SMP it is possible to have a "callback function running and enqueued"
* status. It happens for example when a posix timer expired and the callback
* queued a signal. Between dropping the lock which protects the posix timer
* and reacquiring the base lock of the hrtimer, another CPU can deliver the
* signal and rearm the timer.

Multithreaded Environment - Signal Handling in c++ in unix-like environment (freeBSD and linux)

I wrote a network packet listener program and I have 2 threads. Both runs forever but one of them sleeps 30 sec other sleeps 90 sec. In main function, I use sigaction function and after installed signal handler, I created these 2 threads. After creation of threads, main function calls pcaploop function, which is infinite loop. Basic structure of my program:
(I use pseudo syntax)
signalHandler()
only sets a flag (exitState = true)
thread1()
{
while 1
{
sleep 30 sec
check exit state, if so exit(0);
do smth;
}
}
thread2()
{
while 1
{
sleep 90 sec
check exit state, if so exit(0);
do smth;
}
}
main()
{
necassary snytax for sigaction ;
sigaction( SIGINT, &act, NULL );
sigaction( SIGUSR1, &act, NULL );
create thread1;
create thread2;
pcaploop(..., processPacket,...); // infinite loop, calls callback function (processPacket) everytime a packet comes.
join threads;
return 0;
}
processPacket()
{
check exitState, if true exit(0);
do smth;
}
And here is my question. When I press CTRL-C program does not terminate. If the program run less than 6-7 hours, when I press CTRL-C, program terminates. If the program run 1 night, at least 10 hours or more, I cannot terminate the program. Actually, signal handler is not called.
What could be the problem? Which thread does catch the signal?
Basically it would be better to remove all pseudo code you put in your example, and leave the minimum working code, what exactly you have.
From what I can see so far from your example, is that the error handling of sigaction's is missing.
Try to perform checks against errors in your code.
I am writing this for those who had faced with this problem. My problem was about synchronization of threads. After i got handle synchronization problem, the program now, can handle the signals. My advice is check the synchronization again and make sure that it works correctly.
I am sorry for late answer.
Edited :
I have also used sigaction for signal handling
and I have change my global bool variable whit this definition :
static volatile sig_atomic_t exitFlag = 0;
This flag has been used for checking whether the signal received or not.

Kernel mode clock_gettime()

I'm trying to use the POSIX clock functions in the kernel but the compiler keeps giving me the error: error: implicit declaration of function ‘clock_gettime’
long __timer_end(struct timespec start_time)
{
struct timespec end_time;
clock_gettime(CLOCK_REALTIME_COARSE, &end_time);
return(end_time.tv_nsec - start_time.tv_nsec);
}
struct timespec __timer_start(void)
{
struct timespec start_time;
clock_gettime(CLOCK_REALTIME_COARSE, &start_time);
return start_time;
}
The functions are defined in <linux/posix_clock.h> as part of structure called posix_clock_operations and there are a pair of functions, posix_clock_register() and posix_clock_unregister(). The comments lead one to believe that these functions will populate the posix_clock_operations structure. I've implemented both in my init and exit functions hoping that their presence would magically make the forward declarations for clock_gettime() appear, but it doesn't.
Does anyone know what I need to do to make this one function work? Do I really need to define all my own functions an populate posix clock_operations?
Thanks in advance,
Pete
It seems there is no clock_gettime() in the kernel however there is a nsec resolution clock called current_kernel_time(). So rewriting my timer looks like this:
long timer_end(struct timespec start_time)
{
struct timespec end_time = current_kernel_time();
return(end_time.tv_nsec - start_time.tv_nsec);
}
struct timespec timer_start(void)
{
return current_kernel_time();
}
It seems to work fine, but a higher performance version of the same suitable for ns granular performance testing looks like this:
long timer_end(struct timespec start_time)
{
struct timespec end_time;
getrawmonotonic(&end_time);
return(end_time.tv_nsec - start_time.tv_nsec);
}
struct timespec timer_start(void)
{
struct timespec start_time;
getrawmonotonic(&start_time);
return start_time;
}
Thanks for the comments and pointers.
Pete
As pointed out in answer by pjenney58, you can use current_kernel_time(), but do keep in mind that it gives you the "wallclock" time (in HZ accuracy), which is not recommended if you want to profile time taken by some kernel code - simply because it'll also consider time spent in suspended mode. To profile timing in kernel code there is a kernel equivalent of userland clock_gettime(CLOCK_MONOTONIC,...) viz. do_posix_clock_monotonic_gettime() which is defined as a macro in timekeeping.h. It takes pointer to struct timespec as an argument in which monotonic clock time is returned in sec and nsec accuracy.

Asynchronous timer in Linux

I want to use an asynchronous timer which fires a call back function when it expires. I want the precison in micro secs.
my code flow goes like this..
timer_t tid;
struct itimerspec val;
val.it_value.tv_sec = 0;
val.it_value.tv_nsec = 100000;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 100000;
timer_create (CLOCK_REALTIME, NULL, &tid);
timer_connect (tid, myfunc,0);
timer_settime (tid, 0, &val, NULL);
and write my handle function:
myfunc(){
blah blah blah...
}
I think timer_connect is not been used in recent Linux versions.. Do I have an alternative?
Thanks,
Indeed timer_connect does not exist in recent Linux version. Actually, I'm quite sure it doesn't exist in ANY Linux version, recent or not. Some googling suggests it's something found in VxWorks. It's not found in POSIX either, FWIW.
In Linux (and POSIX) you can provide a pointer to a struct sigevent as the second argument to timer_create() (the one which is NULL in your example). struct sigevent in turn has a member (*sigev_notify_function) which, as the name implies, is the function to call when the timer expires (this requires that the notification method is SIGEV_THREAD).

Resources