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