POSIX scheduling and priority question
Gempeler Stefan
Stefan.Gempeler at nanotronic.ch
Tue Apr 22 12:53:57 UTC 2014
Hi
I have a problem which has already been discussed here, but I couldn't
find an answer or solution for it.
We have a time critical process which has to respond in very little time
(<50us). A hardware interrupt will post only a semaphore which has to
start the waiting processing code.
But during this time, some time consuming but not time critical
functions can run (compression etc.).
I expected that giving the correct priorities to the threads should take
care of it, but the result looks exactly as if it would run on a
cooperatively scheduled system:
No interruption of the low priority tasks after the semaphore has been
posted.
Below there's a small test program which demonstrates the effect. BUT:
when the line 1) is uncommented, usleep(1) it works.
System: Running on a virtex4 PowerPC, RTEMS Version 4.10.99.0, commit
39a6e4ea690d265233a68efe993cb107d1d864ca
Configured with:
CPU=powerpc
BSP=virtex
configure --target=${CPU}-rtems4.11 --enable-rtemsbsp=${BSP} \
--prefix=/mnt/extended/ppc_rtems/bsp-install \
--disable-cxx --enable-posix --disable-networking
--disable-tests ...
Test program:
************************************************************************
************
//----------------------------------------------------------------------
---------------------------------------------
// minimal system for testing
//----------------------------------------------------------------------
---------------------------------------------
/* configuration information */
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK
1000
#define CONFIGURE_TICKS_PER_TIMESLICE 5
#define CONFIGURE_MAXIMUM_POSIX_THREADS
3
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES
1
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
//----------------------------------------------------------------------
---------------------------------------------
#include <bsp.h>
#include <assert.h>
#include <semaphore.h>
void* test_full_thread( void* arg );
void* test_wait_thread( void* arg );
#include <pthread.h>
sem_t test_semaphore;
//----------------------------------------------------------------------
---------------------------------------------
void* test_full_thread( void* arg )
{
int i=0;
int counter = 0;
printk( "-> Full busy thread started\n" );
while(1)
{
if( i>4000000 )
{
// posting the semaphore
for sys_scheduler_test_wait_task()
printk( "\nFULL posting
%d...", counter );
counter++;
sem_post( &test_semaphore
);
i=0;
// usleep(1);
// 1) when usleep is called, the task switch works
}
i++;
}
return 0;
}
//----------------------------------------------------------------------
---------------------------------------------
void* test_wait_thread( void* arg )
{
int counter=0;
printk( "-> Wait thread started\n" );
while(1)
{
// waits for
sys_scheduler_test_full_task() posting the semaphore
sem_wait( &test_semaphore );
printk( "WAIT received %d ", counter );
counter++;
}
return 0;
}
//----------------------------------------------------------------------
---------------------------------------------
// Main startup routine
void *POSIX_Init( void *argument )
{
#define SCHEDULER_POLICY (SCHED_RR)
pthread_t thread_full;
pthread_t thread_wait;
pthread_attr_t test_attr;
struct sched_param test_param;
assert( sem_init( &test_semaphore, 0, 0 )==0 );
// get default attributes
pthread_attr_init( &test_attr );
// store parameters
pthread_attr_getschedparam( &test_attr, &test_param );
// set policy
pthread_attr_setschedpolicy( &test_attr,
SCHEDULER_POLICY );
printk( "\n\n========= STARTING ============ \n" );
// start the waiting task, highest priority
test_param.sched_priority = sched_get_priority_max(
SCHEDULER_POLICY );
assert( pthread_attr_setschedparam( &test_attr,
&test_param )==0 );
pthread_create( &thread_wait, &test_attr,
test_wait_thread, 0 );
// start the full running task, lowest priority
test_param.sched_priority = sched_get_priority_min(
SCHEDULER_POLICY );
assert( pthread_attr_setschedparam( &test_attr,
&test_param )==0 );
pthread_create( &thread_full, &test_attr,
test_full_thread, 0 );
while(1)
{
sleep( 1 );
}
exit( 0 );
}
//----------------------------------------------------------------------
---------------------------------------------
//----------------------------------------------------------------------
---------------------------------------------
************************************************************************
************
Output without usleep (the higher priority thread has never been
called):
========= STARTING ============
-> Wait thread started
-> Full busy thread started
FULL posting 0...
FULL posting 1...
FULL posting 2...
FULL posting 3...
************************************************************************
************
Output with usleep (works as expected):
========= STARTING ============
-> Wait thread started
-> Full busy thread started
FULL posting 0...WAIT received 0
FULL posting 1...WAIT received 1
FULL posting 2...WAIT received 2
FULL posting 3...WAIT received 3
************************************************************************
************
Compiling and running exactly the same code in an Ubuntu 32-bit system
works perfectly.
I also tried different settings (SCHED_FIFO, different priorities etc.),
but nothing helped.
Distributing usleeps in the time consuming code is not an option ;-)
Or would it be better to use the RTEMS task system? At the moment we use
POSIX for compatibility reasons, but it can be changed.
Not to handle the time critical interrupts in time is a show stopper for
our application.
Now my question: what am I doing wrong?
Thank you!!
Kind regards
Stefan Gempeler
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20140422/a0bf3d5a/attachment.html>
More information about the users
mailing list