<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.E-MailFormatvorlage17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=DE-CH link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span lang=EN-US>Hi <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>I have a problem which has already been discussed here, but I couldn’t find an answer or solution for it.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>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. <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>But during this time, some time consuming but not time critical functions can run (compression etc.).<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>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:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>No interruption of the low priority tasks after the semaphore has been posted.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Below there’s a small test program which demonstrates the effect. BUT: when the line 1) is uncommented, usleep(1) it works.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>System: Running on a virtex4 PowerPC, RTEMS Version 4.10.99.0, commit 39a6e4ea690d265233a68efe993cb107d1d864ca<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Configured with:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>CPU=powerpc<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>BSP=virtex<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>configure --target=${CPU}-rtems4.11 --enable-rtemsbsp=${BSP} \<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> --prefix=/mnt/extended/ppc_rtems/bsp-install \<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> --disable-cxx --enable-posix --disable-networking --disable-tests …<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Test program:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>************************************************************************************<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>// minimal system for testing<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>/* configuration information */<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_MICROSECONDS_PER_TICK 1000<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_TICKS_PER_TIMESLICE 5<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_MAXIMUM_POSIX_THREADS 3<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_POSIX_INIT_THREAD_TABLE<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define CONFIGURE_INIT<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>#include <rtems/confdefs.h><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#include <bsp.h><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#include <assert.h><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#include <semaphore.h><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>void* test_full_thread( void* arg );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>void* test_wait_thread( void* arg );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>#include <pthread.h><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>sem_t test_semaphore;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>void* test_full_thread( void* arg )<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>{<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> int i=0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> int counter = 0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> printk( "-> Full busy thread started\n" );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> while(1)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> if( i>4000000 )<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> // posting the semaphore for sys_scheduler_test_wait_task()<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk( "\nFULL posting %d...", counter );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> counter++;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> sem_post( &test_semaphore );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> i=0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>// usleep(1); // 1) when usleep is called, the task switch works<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> i++;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> return 0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>void* test_wait_thread( void* arg )<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>{<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> int counter=0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> printk( "-> Wait thread started\n" );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> while(1)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> // waits for sys_scheduler_test_full_task() posting the semaphore<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> sem_wait( &test_semaphore );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk( "WAIT received %d ", counter );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> counter++;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> return 0;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>// Main startup routine<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>void *POSIX_Init( void *argument )<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>{<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>#define SCHEDULER_POLICY (SCHED_RR)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_t thread_full;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_t thread_wait;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_attr_t test_attr;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> struct sched_param test_param;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> assert( sem_init( &test_semaphore, 0, 0 )==0 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> // get default attributes<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_attr_init( &test_attr );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> // store parameters<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_attr_getschedparam( &test_attr, &test_param );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> // set policy<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_attr_setschedpolicy( &test_attr, SCHEDULER_POLICY );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> printk( "\n\n========= STARTING ============ \n” );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> // start the waiting task, highest priority<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> test_param.sched_priority = sched_get_priority_max( SCHEDULER_POLICY );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> assert( pthread_attr_setschedparam( &test_attr, &test_param )==0 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_create( &thread_wait, &test_attr, test_wait_thread, 0 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> // start the full running task, lowest priority<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> test_param.sched_priority = sched_get_priority_min( SCHEDULER_POLICY );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> assert( pthread_attr_setschedparam( &test_attr, &test_param )==0 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> pthread_create( &thread_full, &test_attr, test_full_thread, 0 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> while(1)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> sleep( 1 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> exit( 0 );<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>//-------------------------------------------------------------------------------------------------------------------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>************************************************************************************<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Output without usleep (the higher priority thread has never been called):<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>========= STARTING ============<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>-> Wait thread started<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>-> Full busy thread started<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 0...<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 1...<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 2...<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 3... <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>************************************************************************************<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Output with usleep (works as expected):<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>========= STARTING ============ <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>-> Wait thread started<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>-> Full busy thread started<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 0...WAIT received 0 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 1...WAIT received 1 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 2...WAIT received 2 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>FULL posting 3...WAIT received 3 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>************************************************************************************<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Compiling and running exactly the same code in an Ubuntu 32-bit system works perfectly.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>I also tried different settings (SCHED_FIFO, different priorities etc.), but nothing helped.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Distributing usleeps in the time consuming code is not an option ;-)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>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.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Not to handle the time critical interrupts in time is a show stopper for our application.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Now my question: what am I doing wrong? <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Thank you!!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Kind regards<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Stefan Gempeler<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div></body></html>