UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » Threads
  • » What's the best strategy for simulating a hardware interrupt in a user app?

#1 2007-08-22 10:34 PM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Hi all,

I'm soon going to be starting a prototype for a new hardware system that will run under Linux (wth the Xenomai real-time extensions, if that's important).  Before I do that though, I want to make a relatively simple proof-of-concept app that can run under "vanilla" Linux on a regular PC, and use that to develop the design.

The plan for the final hardware is that a regular user process will run the non-real-time code, and there will be a hardware timer interrupt that goes off every so many milliseconds that will handle the real-time stuff.  Since the interrupt can't do any locking/mutexes, I will be using a double-buffering scheme where the non-real-time code maintains two parallel copies of the shared data, and writes only to the copy that the interrupt is not currently reading from.  When the non-real-time code has finished its update, it will (atomically) change the pointer that the interrupt uses, and then (now that the interrupt is reading only the updated copy), the user process will go back and make the same changes to the other copy as well.

That should all work fine, as long as I can guarantee that the interrupt routine is *never* interrupted by the non-real-time code.  In the actual hardware, this behavior will happen naturally; my question is, how can I best obtain this behavior in a plain old Linux user app?  I can think of two strategies:

1) Spawn a thread that will act as the "interrupt", and set it to real-time priority.  The main thread remains at normal priority.  The real-time thread then runs a while(1) {doStuff(); sleep();} loop.  I think this would work okay, but setting a thread to real time priority requires that the app be run as root, which I'd rather not have to require if I can avoid it.

2) Set up a Unix signal (SIGUSR1?) to fire every so often.  The signal handler routine will act as the "interrupt".  I think this might work, but I'm worried about the potential side effects it might have on my user thread... e.g. causing system calls to fail with EAGAIN, and so on.  I'd prefer a solution that acts as much like the final (hardware-based) implementation as possible.

Is either of these "better"?  Or is there some third way I haven't thought of?

Thanks,
Jeremy

Offline

#2 2007-08-22 11:05 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: What's the best strategy for simulating a hardware interrupt in a user app?

I'd use signals. System calls might fail with EINTR then, but you should handle
that case anyway, if they aren't restarted automatically already.

How will the non-realtime code know that it's interrupted and that it might be
reading stale data? Are you reading the current buffer pointer atomically or
doing something else to avoid following it halfway an update, which would
corrupt both buffers? Or better question, what is preventing the realtime part
from using half updated, thus invalid data anyway?

It seems a bit shaky approach, as there's nothing that prevents race conditions, so
you should be very careful that all updates done are stand-alone and atomic. And
if you're at that point, why use a double buffer? Using double buffers only seems
to make sense if the shared data can't be modified atomically by the real-time
part, and the data modified by the other part can be. But then it would make
more sense to split up the part that can be modified race-free and atomically from
the rest. At this point the shared data is only read by the non-rt part, in which case
you should use a sequence lock instead.

Another matter is that if the code is real-time critical, and it shares data with non-rt
code, how much does it depend on that the shared data is being updated on time?

Offline

#3 2007-08-22 11:37 PM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Offline

#4 2007-08-23 01:00 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Just to touch on the signal idea...  You can probably do it via setitimer()...  But, I
don't know how reliably it's going to simulate any real hardware interrupt, since
timers and signals can be a bit flaky and unreliable, especially if the system is loaded...

Also, if you're worried about interrupted syscalls, you can control the auto-restart
behavior either via siginterrupt() or by registering your handler with sigaction() and
the SA_RESTART flag...

Offline

#5 2007-08-23 02:05 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Offline

#6 2007-08-25 01:06 AM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Very interesting ... I set up a timer using setitimer(), and it basically works, but every time the timer signal goes off, all the sockets that my main thread is select()'ing on immediately select as ready-for-read and ready-for-write.  Then my main thread's event loop goes to service them, but of course there is no actual data there for it to read or write.

Is that normal?  If so, why does that happen?  If not, what am I doing wrong?

FWIW, here is the setitimer code I added:

static void _signalCatcherFunc(int sig)
{
   // empty, for now... but if I put a printf() in here I see it get called at
   // the proper times....
}

[...]

struct sigaction sact;
sigemptyset( &sact.sa_mask );
sact.sa_flags = 0;
sact.sa_handler = _signalCatcherFunc;
sigaction( SIGALRM, &sact, NULL );

 // start up the "interrupt"!
struct itimerval val;  memset(&val, 0, sizeof(val));
val.it_interval.tv_usec = val.it_value.tv_usec = 1000000; 
if (setitimer(ITIMER_REAL, &val, NULL) != 0) printf("setitimer failed!\n");

// select() loop is here

Also, while I'm on the subject, is there a way to pass a (void *) argument to a signal handler function?  Right now I have to set a global pointer variable to give the signal handler access to the relevant data, and global variables are icky....

Offline

#7 2007-08-25 08:49 AM

mlampkin
Administrator
From: Sol 3
Registered: 2002-06-12
Posts: 911
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?


"The only difference between me and a madman is that I'm not mad."

Salvador Dali (1904-1989)

Offline

#8 2007-08-25 12:11 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Select probably set errno to EINTR and returned -1, are you handling that correctly? If something else happens we'll need more info/code.

Offline

#9 2007-08-27 03:24 AM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Offline

#10 2007-08-27 03:34 AM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Offline

#11 2007-08-27 11:47 AM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

So, select() is returning a positive value?  AND, subsequent calls to FD_ISSET() on
the fd_set(s) return TRUE?  That seems highly strange to me...  Can you post the
actual select() and FD_ISSET() checking code?

However, one thing you might want to do anyway, is change this bit of your signal
handler registration code:

sact.sa_flags = 0;

To this:

sact.sa_flags = SA_RESTART;

Which should allow for auto-restart of interrupted syscalls when you get hit with
that signal...

Offline

#12 2007-08-27 05:33 PM

jfriesne
Administrator
From: California
Registered: 2005-07-06
Posts: 348
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?

Offline

#13 2007-08-27 05:46 PM

mlampkin
Administrator
From: Sol 3
Registered: 2002-06-12
Posts: 911
Website

Re: What's the best strategy for simulating a hardware interrupt in a user app?


"The only difference between me and a madman is that I'm not mad."

Salvador Dali (1904-1989)

Offline

  • Index
  • » Threads
  • » What's the best strategy for simulating a hardware interrupt in a user app?

Board footer

Powered by FluxBB