InterruptLock among processes

Hi,
We have a real time application that consists of several cooperating
processes that use a shared memory object and communicate using posix
signals. Currently, critical sections of code are protected by
InterruptDisable and InterruptEnable. This limits the application to
running on single processor machines. Can InterruptLock and
InterruptUnlock be used across processes with the intrspin_t object in
shared memory? If so, this would require the least amount of effort to
port the application to multiple processors.
Thanks.

First, let me see if I understand this. You disable interrupts so
that the timer interrupt will not occur when you are inside critical
code where the data structure is vulnerable? This is generally
frowned upon if the time in the critical code is not negligable.

Is there some reason why you don’t use the available OS features that
are designed to solve this problem, eg. mutexes or semaphores?
If you aren’t upgrading to multiple processors to provide more cpu for
these cooperating processes, you could also use processor affinity to
confine them to a single processor.

It is also possible that you might be able to create your own
semaphore using atomic operations, but that would require the waiting
processes to loop. This too is not a good idea except for very short
periods.

While this would work, mutexes can be placed in shared memory, and unless you are
trying to gain mutual exclusion between a user level thread and an interrupt handler
then InterruptDisable() is to be avoided when possible.

Cheers,

Colin

John McClurkin wrote:

Hi,
We have a real time application that consists of several cooperating
processes that use a shared memory object and communicate using posix
signals. Currently, critical sections of code are protected by
InterruptDisable and InterruptEnable. This limits the application to
running on single processor machines. Can InterruptLock and
InterruptUnlock be used across processes with the intrspin_t object in
shared memory? If so, this would require the least amount of effort to
port the application to multiple processors.
Thanks.


cburgess@qnx.com

maschoen wrote:

First, let me see if I understand this. You disable interrupts so
that the timer interrupt will not occur when you are inside critical
code where the data structure is vulnerable? This is generally
frowned upon if the time in the critical code is not negligable.

Is there some reason why you don’t use the available OS features that
are designed to solve this problem, eg. mutexes or semaphores?
If you aren’t upgrading to multiple processors to provide more cpu for
these cooperating processes, you could also use processor affinity to
confine them to a single processor.

It is also possible that you might be able to create your own
semaphore using atomic operations, but that would require the waiting
processes to loop. This too is not a good idea except for very short
periods.

Thanks for your response
We disable interrupts so that a hardware interrupt (A/D card) will not
occur when we are in a critical section. Interrupts during a critical
section cause the program to crash or the computer to freeze. The
critical sections are very short, on the order of 1 microsecond or so.
{ block interrupts, increment shared memory index, assign value to
shared memory, unblock interrupts }

I have done some timing with mutexes and gotten unsatisfactory results.
The method I used to time blocks of code is to set a bit on a parallel
port, execute the code, then clear the bit. I can then examine the bit
with an oscilloscope. I found that, when a mutex is free, acquiring the
mutex, executing the code, then releasing the mutex was very fast, about
1 to 2 microseconds. However, if a second thread tries to acquire the
mutex while it is owned by another thread, that second thread can be
blocked for 1 to 2 HUNDRED microseconds, long after the first thread has
released the mutex. This happens once every several seconds. This kind
of variability is fatal to our application. I am hoping that, because
InterruptLock and InterruptUnlock are kernel calls, we won’t see this
kind of variability.

I agree that your third suggestion is not too good.

Colin Burgess wrote:

While this would work, mutexes can be placed in shared memory, and
unless you are
trying to gain mutual exclusion between a user level thread and an
interrupt handler
then InterruptDisable() is to be avoided when possible.

Cheers,

Colin

John McClurkin wrote:
Hi,
We have a real time application that consists of several
cooperating processes that use a shared memory object and communicate
using posix signals. Currently, critical sections of code are
protected by InterruptDisable and InterruptEnable. This limits the
application to running on single processor machines. Can InterruptLock
and InterruptUnlock be used across processes with the intrspin_t
object in shared memory? If so, this would require the least amount of
effort to port the application to multiple processors.
Thanks.

Thanks for your response.
I have done some testing with mutexes and have gotten unsatisfactory
results. I time code by setting a bit on a parallel port, execute the
code, the clear the bit. I then examine the bit with an oscilloscope. In
timing mutex use, I found that, if a mutex is free, then the time to
acquire the mutex, execute the critical code, then release the mutex is
on the order of 1 to 2 microseconds. However, if a second thread tries
to acquire the mutex while another thread is in the critical section,
the second thread can be blocked for 1 to 2 HUNDRED microseconds. I am
hoping that because InterruptLock and InterruptUnlock are kernel calls,
we won’t see this kind of variabilty.

As you mentioned in your other post to Mitch, you are protecting against
an interrupt handler accessing the data, so in this particular case
InterruptDisable() is appropriate (and you should use InterruptLock()
for SMP safety).

FYI - InterruptDisable() is not generally a kernel call - it’s a single instruction
on x86.

When a mutex is not contested, the thread doesn’t need to enter the kernel to aquire
it, but when there is a contention the the pthread_mutex_lock() ends up in a kernel
call to SyncMutexLock(), plus now the lock holder must call SyncMutexUnlock() to release
the mutex.

Regards,

Colin

John McClurkin wrote:

Colin Burgess wrote:
While this would work, mutexes can be placed in shared memory, and
unless you are
trying to gain mutual exclusion between a user level thread and an
interrupt handler
then InterruptDisable() is to be avoided when possible.

Cheers,

Colin

John McClurkin wrote:
Hi,
We have a real time application that consists of several
cooperating processes that use a shared memory object and communicate
using posix signals. Currently, critical sections of code are
protected by InterruptDisable and InterruptEnable. This limits the
application to running on single processor machines. Can
InterruptLock and InterruptUnlock be used across processes with the
intrspin_t object in shared memory? If so, this would require the
least amount of effort to port the application to multiple processors.
Thanks.


Thanks for your response.
I have done some testing with mutexes and have gotten unsatisfactory
results. I time code by setting a bit on a parallel port, execute the
code, the clear the bit. I then examine the bit with an oscilloscope. In
timing mutex use, I found that, if a mutex is free, then the time to
acquire the mutex, execute the critical code, then release the mutex is
on the order of 1 to 2 microseconds. However, if a second thread tries
to acquire the mutex while another thread is in the critical section,
the second thread can be blocked for 1 to 2 HUNDRED microseconds. I am
hoping that because InterruptLock and InterruptUnlock are kernel calls,
we won’t see this kind of variabilty.


cburgess@qnx.com