Hello,
I have encountered a problem running real time application on i686 with
kernel 2.6.18
The problem: a high priority thread is preempted by a low priority thread.
All the threads use FIFO real time scheduling.
Thread #1 with priority 50 is running, receiving and sending messages
through IPC queues.
It is preempted by thread #2, that runs in priority 34.
The preemption is discovered by testing a global variable, when it is
corrupted the application (running thread#1) aborts.
The backtrace of the core dump file looks like this:
#5 0xb7e2ffb9 in abort () from /lib/tls/i686/cmov/libc.so.6
#6 0x081ef33d in f2 (table_num=1) at cpoolbuf.c:180
#7 0x081899ea in f1 (feature_ptr_address=0x875ff2a) at vcgetfea.c:70
The code of these functions is:
vcgetfea.c - lines 66-70
line#66: if (public_signature != 0x1234){
line#67: printf("signature %s:%i %i\n",__FILE__,__LINE__,public_signature);
line#68: abort();
line#69: }
line#70: f2(FEATURES_POOL_TABLE);
cpoolbuf.c - lines 66-180
line#177: void f2(short unsigned int table_num){
line#178: if (public_signature != 0x1234){
line#179: printf("signature %s:%i %i\n",__FILE__,__LINE__,public_signature);
line#180: abort();
line#181: }
The variable public_signature was OK in vcgetfea.c:66
A call to f2() was done in line 70.
The variable was tested again at the start of f2() and abort() was called.
The value of public_signature idicates that thread#2 changed it.
I dont understand how thread#2 preempts thread#1.
My guess is that thread#1 performed a system call and it was marked for
blocking. It completed the system call and when the scheduler was activated
by the system tick it blocked thread#1 and activated thread#2.
Am I right?
Why does the scheduler activate thread#2 when thread#1 is running?
(It performs the call from f1() to f2())
Is there a way to configure the kernel not to mark the thread if the system
call is non blocking?
thank you,
Zeev