Compression and decompression CPU usage in Leon 3

Rafael Morales rmorales at iaa.es
Wed Jan 14 14:04:45 UTC 2015


Dear all,

Thank you for you responses.

Finally I found the problem: priority assigned to tasks were not well 
defined.
Once is was solved, the compression task worked as expected.

I've attached a small sample that allows to play with compression and 
priorities tasks.
I hope that someone  find useful If she/he has similar problems.

Saludos from Spain.

> On 1/12/2015 3:33 PM, Rafael Morales wrote:
>> Dear Angelo,
>>
>> Thank you for your response.
>>
>> I've checked and there is no critical sections inside code. Just nested
>> "for" and memory buffers playing.
> Any chance the thread doing the compression is non-preemptible?
>
>> Saludos Rafael.
>>
>>
>>> Check that there is not a critical section running within the algorithm
>>>
>>> On 13/01/2015 5:39 AM, Rafael Morales wrote:
>>>> Dear all,
>>>>
>>>> I'm using a Leon 3 with RTEMS 4.10.
>>>>
>>>> When I run a compression/decompression algorithm (zlib or promDecode
>>>> from mkprom sources) on KB of data,
>>>> my other RTEMS tasks seems to be frozen.
>>>> I've tried to put the compression/decompression in a separate task
>>>> with low priority, but no luck.
>>>>
>>>> In theory, a more privileged task should stop the compression and
>>>> start to run, but I see just the opposite.
>>>>
>>>> Any idea?
>>>>
>>>> Thanks in advance.
>>>> _______________________________________________
>>>> users mailing list
>>>> users at rtems.org
>>>> http://lists.rtems.org/mailman/listinfo/users
>>> ---
>>> This email has been checked for viruses by Avast antivirus software.
>>> http://www.avast.com
>> _______________________________________________
>> users mailing list
>> users at rtems.org
>> http://lists.rtems.org/mailman/listinfo/users

-------------- next part --------------
/*  Test_task
 */

/*****************************************************************************/

#include <rtems.h>
#include <stdio.h>
#include <stdlib.h>

//============================================================================

//function prototypes

rtems_task Init(rtems_task_argument argument);
rtems_task task_1(rtems_task_argument unused);
rtems_task task_2(rtems_task_argument unused);
rtems_task task_3(rtems_task_argument unused);
rtems_task task_4(rtems_task_argument unused);

void create_compression_buffer();

//============================================================================
//glbal variables
rtems_id   Task_id[ 4 ];         /* array of task ids */
rtems_name Task_name[ 4 ];       /* array of task names */

/*****************************************************************************/
//RTEMS configuration
#define CONFIGURE_INIT
#include <bsp.h> /* for device driver prototypes */

/* configuration information */
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER    1
#define CONFIGURE_MAXIMUM_TASKS                    16
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_EXTRA_TASK_STACKS                (20 * RTEMS_MINIMUM_STACK_SIZE)
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS   32
#define CONFIGURE_INIT_TASK_PRIORITY	           100
#define CONFIGURE_MAXIMUM_DRIVERS                  16

/* Configure RTEMS Kernel */
#include <rtems/confdefs.h>

/* Configure Driver manager */
#if defined(RTEMS_DRVMGR_STARTUP) && defined(LEON3) /* if --drvmgr was given to configure */
 /* Add Timer and UART Driver for this example */
 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
  #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
 #endif
 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
  #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
 #endif
#endif



#include <drvmgr/drvmgr.h>
#include <drvmgr/drvmgr_confdefs.h>

/*****************************************************************************/

int task_1_waiting_second=    1;
int task_3_waiting_second=	  1;
int task_4_waiting_second=	  1;

rtems_task_priority task_1_priority=75;
rtems_task_priority task_2_priority=76;  //compression task
rtems_task_priority task_3_priority=75;
rtems_task_priority task_4_priority=75;


uint32_t ticks_per_second;



//============================================================================
//compression and decompression

#include "Zlib/ZlibCompressionLibrary.h"

#define BASE_BUFFER_BYTE_SIZE	        	(1024*360)
#define COMPRESSING_BUFFER_BYTE_SIZE		(BASE_BUFFER_BYTE_SIZE*2)


Bytef base_buffer[BASE_BUFFER_BYTE_SIZE+1024];
Bytef compression_buffer[COMPRESSING_BUFFER_BYTE_SIZE];
Bytef decompression_buffer[COMPRESSING_BUFFER_BYTE_SIZE];

//============================================================================

static inline uint32_t get_ticks_per_second( void ){
  rtems_interval ticks_per_second;
  (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second );
  return ticks_per_second;
}

//============================================================================
//============================================================================

rtems_task Init(rtems_task_argument argument){

   srand(time(NULL));


  rtems_status_code status;
  rtems_time_of_day time;

  time.year   = 1988;
  time.month  = 12;
  time.day    = 31;
  time.hour   = 9;
  time.minute = 0;
  time.second = 0;
  time.ticks  = 0;

  status = rtems_clock_set( &time );


  Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' );
  Task_name[ 2 ] = rtems_build_name( 'T', 'A', '2', ' ' );
  Task_name[ 3 ] = rtems_build_name( 'T', 'A', '3', ' ' );
  Task_name[ 4 ] = rtems_build_name( 'T', 'A', '4', ' ' );


  status = rtems_task_create(
    Task_name[ 1 ],
    task_1_priority,
    RTEMS_MINIMUM_STACK_SIZE * 2,
    RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES,
    &Task_id[ 1 ]
  );

  status = rtems_task_create(
    Task_name[ 2 ],
    task_2_priority,
    RTEMS_MINIMUM_STACK_SIZE * 2,
    RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES,
    &Task_id[ 2 ]
  );

  status = rtems_task_create(
    Task_name[ 3 ],
    task_3_priority,
    RTEMS_MINIMUM_STACK_SIZE * 2,
    RTEMS_DEFAULT_MODES,
    RTEMS_DEFAULT_ATTRIBUTES,
    &Task_id[ 3 ]
  );

  status = rtems_task_create(
      Task_name[ 4 ],
      task_4_priority,
      RTEMS_MINIMUM_STACK_SIZE * 2,
      RTEMS_DEFAULT_MODES,
      RTEMS_DEFAULT_ATTRIBUTES,
      &Task_id[ 4]
    );

  ticks_per_second=get_ticks_per_second();

  status = rtems_task_start( Task_id[ 1 ], task_1, 1 );
  status = rtems_task_start( Task_id[ 2 ], task_2, 2 );
  status = rtems_task_start( Task_id[ 3 ], task_3, 3 );
  status = rtems_task_start( Task_id[ 4 ], task_4, 4 );

  status = rtems_task_delete( RTEMS_SELF );
}

//============================================================================
//Functions
//============================================================================

//============================================================================

//============================================================================

void create_compression_buffer(){

	int i=0;
	int max=BASE_BUFFER_BYTE_SIZE;

	for(i=0;i<max;i=i+1)
		base_buffer[i]=rand();
}

//============================================================================

rtems_task task_1(rtems_task_argument unused){

	struct timespec current_time;

	while(true){
		while(true){
				rtems_task_wake_after(task_1_waiting_second * ticks_per_second );
				clock_gettime(CLOCK_REALTIME,
							   &current_time);

				printf( "%s%i%s%i%s",
						"\n TASK 1-> ",
						(int)current_time.tv_sec,
						"s ",
						(int)current_time.tv_nsec/1000000,
						"ms\n");
			}
	}
}

//============================================================================


rtems_task task_2(rtems_task_argument unused){


	struct timespec current_time;

	while(true){

		clock_gettime(CLOCK_REALTIME,
					  &current_time);
		printf( "%s%i%s%i%s",
				"\n TASK 2 COMPRESSING AND UNCOMPRESSING STARTS-> ",
				(int)current_time.tv_sec,
				"s ",
				(int)current_time.tv_nsec/1000000,
				"ms\n");

		create_compression_buffer();
		memset(compression_buffer,0,COMPRESSING_BUFFER_BYTE_SIZE);
		memset(decompression_buffer,0,COMPRESSING_BUFFER_BYTE_SIZE);

		uLongf compressed_byte_size=COMPRESSING_BUFFER_BYTE_SIZE;
		if (zlib_compress (compression_buffer,
					       &compressed_byte_size,
					       base_buffer,
					       BASE_BUFFER_BYTE_SIZE)!=0){

			printf( "\nERROR compressing\n" );
			break;
		}

		uLong uncompressed_byte_size=COMPRESSING_BUFFER_BYTE_SIZE;
		if (zlib_decompress (decompression_buffer,
		           	 	     &uncompressed_byte_size,
		           	 	     compression_buffer,
		           	 	     compressed_byte_size)!=0){
			printf( "\nERROR decompressing\n" );
						break;
		}

		clock_gettime(CLOCK_REALTIME,
							  &current_time);
		printf( "%s%i%s%i%s",
				"\n TASK 2 COMPRESSING AND UNCOMPRESSING ENDS-> ",
				(int)current_time.tv_sec,
				"s ",
				(int)current_time.tv_nsec/1000000,
				"ms\n");
	}
}

//============================================================================

rtems_task task_3(rtems_task_argument unused){

	struct timespec current_time;

	while(true){
			rtems_task_wake_after(task_3_waiting_second * ticks_per_second );
			clock_gettime(CLOCK_REALTIME,
						   &current_time);

			printf( "%s%i%s%i%s",
					"\n   TASK 3-> ",
					(int)current_time.tv_sec,
					"s ",
					(int)current_time.tv_nsec/1000000,
					"ms\n");
		}
}

//============================================================================

rtems_task task_4(rtems_task_argument unused){

	struct timespec current_time;

	while(true){
		rtems_task_wake_after(task_4_waiting_second * ticks_per_second );
		clock_gettime(CLOCK_REALTIME,
					   &current_time);

		printf( "%s%i%s%i%s",
				"\n    TASK 4-> ",
				(int)current_time.tv_sec,
				"s ",
				(int)current_time.tv_nsec/1000000,
				"ms\n");
	}
}

/*****************************************************************************/
/*****************************************************************************/



More information about the users mailing list