Help: RTEMS Threads, Preemptation and Time slicing...
Alex
kbyte at iol.pt
Wed Oct 27 15:50:34 UTC 2004
Hi all,
I am making little rtems programs involving threads and the POSIX API.
I want to create a program that launchs 2 threads via posix calls. Then I want to split the
processor attent to both threads, i mean, both threads must execute in "parallel" and not to
wait one from another...
The RTEMS manual says the scheduler look to the different taks in this order:
Priority, preemptation (when activated) and then time slicing (when activated), right?
So, in the rtems program I launch the 2 extra threads with equal priority, priority 1! For
each thread, including the main thread I turn on the preemptation and time slicing, but the
second extra thread only starts execution when the first extra thread finishs its execution.
I cant understand why... :-(
Note: If I use a, for example, the sleep() instruction in the body of the thread, the processor
is switch to the other extra thread in a good way, but if i dont use functions that transfer the
execution to other threads, the processor is never switched to other threads...
Can you help me?
How to execute the 2 extra threads at the same time while the main thread
is waiting for the 2 extra threads?
by the way, is there any way to turn on preemptation and time slicing using only posix api?
Env: linux mandrake 9.2, i686, rtems v4.6
The source code is the following
#define CONFIGURE_INIT
#include <rtems.h>
#include <signal.h>
#include <rtems/posix/timer.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_t Task_id1;
pthread_t Task_id2;
void *Task_1(void *argument)
{
int i;
int result;
struct timespec resolution;
rtems_mode old_mode;
rtems_task_mode(RTEMS_PREEMPT|RTEMS_TIMESLICE, RTEMS_PREEMPT_MASK|RTEMS_TIMESLICE_MASK, &old_mode);
puts("\n Thread executing...");
for(i=0;i<100000000;i++)
{
result=clock_getres(CLOCK_REALTIME, &resolution); //just to take time in execution
result*=100000000; //just to take time in execution
}
puts("\n Thread Existing...");
pthread_exit( NULL );
return NULL;
}
rtems_task Init(rtems_task_argument argument)
{
int status;
void *return_pointer;
rtems_mode old_mode;
pthread_attr_t attr1;
struct sched_param schedparam1;
int policy1;
int policy2;
pthread_attr_t attr2;
struct sched_param schedparam2;
rtems_task_mode(RTEMS_PREEMPT|RTEMS_TIMESLICE, RTEMS_PREEMPT_MASK|RTEMS_TIMESLICE_MASK, &old_mode);
// CREATE AND LAUNCH TASK 1 //
policy1 = SCHED_RR; //SCHED_FIFO, SCHED_OTHER, SCHED_SPORADIC
status = pthread_attr_init( &attr1 );
if(status != 0)
{
printf( "Error in pthread_attr_init( %d ",status);
}
status = pthread_attr_setschedpolicy( &attr1, policy1 );
if(status != 0)
{
printf( "Error in pthread_attr_setschedpolicy( %d ",status);
}
schedparam1.sched_priority = 1;
status = pthread_attr_setschedparam( &attr1, &schedparam1 );
if(status != 0)
{
printf( "Error in pthread_attr_setschedparam %d ",status);
}
status = pthread_create( &Task_id1, &attr1, Task_1, NULL );
if(status != 0)
{
printf( "Error in pthread_create %d ",status );
}
// CREATE AND LAUNCH TASK 2 //
policy2 = SCHED_RR; //SCHED_FIFO, SCHED_OTHER, SCHED_SPORADIC;
status = pthread_attr_init( &attr2 );
if(status != 0)
{
printf( "Error in pthread_attr_init 2 %d ",status);
}
status = pthread_attr_setschedpolicy( &attr2, policy2 );
if(status != 0)
{
printf( "Error in pthread_attr_setschedpolicy 2 %d ",status);
}
schedparam2.sched_priority = 1;
status = pthread_attr_setschedparam( &attr2, &schedparam2 );
if(status != 0)
{
printf( "Error in pthread_attr_setschedparam2 %d ",status);
}
status = pthread_create( &Task_id2, &attr2, Task_1, NULL );
if(status != 0)
{
printf( "Error in pthread_create2 %d ",status );
}
status = pthread_join(Task_id2, &return_pointer );
if(status != 0)
{
printf( "Error in pthread_join %d ",status );
}
puts("\n End of RTEMS Application");
}
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
#define CONFIGURE_MAXIMUM_TASKS 20
#define CONFIGURE_MAXIMUM_SEMAPHORES 20
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 20
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
#include <bsp.h> /* for device driver prototypes */
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_MAXIMUM_POSIX_THREADS 20
#define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
#include <confdefs.h>
--------------------------------------------------------------------------------
The output of this program is:
Thread executing...
Thread Existing...
Thread executing...
Thread Existing...
End of RTEMS Application
--------------------------------------------------------------------------------
What I want is the following:
Thread executing...
Thread executing...
Thread Existing...
Thread Existing...
End of RTEMS Application
--------------------------------------------------------------------------------
Look, if I replace the "for" cicle, in the thread body, by the instruction sleep(5), the thread switching happens
but using the "for" cicle the second thread only starts execution after thread 1 finishing.
Both threads have the same priority, and the preemptation and time slicing are turned on...
Why this happens?
Many thanks,
Alex
________________________________________________________________________________
A protecção do e-mail contra vírus é cada vez mais necessária!
Proteja a sua Caixa de Correio: http://www.iol.pt/correio/rodape.php?dst=0409301
More information about the users
mailing list