From f4a8ee1c55788aeb053ede7571b07906a9847a45 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 17 Mar 1999 16:01:03 +0000 Subject: Unlimited objects patch from Chris Johns . Email follows: First, the unlimited patch. I have compiled the unlmited patch for the Linux posix BSP only and it seems to work cleanly. I would like a really major application run on this change before commiting as the changes are very core and significant. I am currently building all the tests to run. I have no targets suitable to test on at the moment. I have tested the patch for inline functions and macros. Turning macros on has found some core bugs. I have fixed these but have not run all the tests. Please review the patch for these changes. They are: 1) The conditional compilation for MP support broke the core messages code. You cannot embed a conditional macro in another macro. The Send and Urgent Send calls are macros. 2) User extensions handler initialisation now has two parameters. I have updated the macros to support the extra parameter. The patch also contains the gcc-target-default.cfg fix required to build the kernel. More of a by product than a fix for you. --- c/src/exec/rtems/src/msg.c | 32 +- c/src/exec/sapi/include/rtems/config.h | 14 + c/src/exec/score/include/rtems/score/object.h | 110 +++-- c/src/exec/score/inline/rtems/score/coremsg.inl | 8 + c/src/exec/score/inline/rtems/score/object.inl | 56 ++- c/src/exec/score/macros/rtems/score/object.inl | 30 +- c/src/exec/score/macros/rtems/score/userext.inl | 16 +- c/src/exec/score/src/object.c | 564 ++++++++++++++++++++---- c/src/make/compilers/gcc-target-default.cfg | 2 +- c/src/tests/samples/Makefile.in | 2 +- c/src/tests/samples/unlimited/Makefile.in | 63 +++ c/src/tests/samples/unlimited/init.c | 126 ++++++ c/src/tests/samples/unlimited/system.h | 93 ++++ c/src/tests/samples/unlimited/test1.c | 102 +++++ c/src/tests/samples/unlimited/test2.c | 228 ++++++++++ c/src/tests/samples/unlimited/test3.c | 145 ++++++ c/src/tests/samples/unlimited/unlimited.doc | 37 ++ c/src/tests/samples/unlimited/unlimited.scn | 337 ++++++++++++++ 18 files changed, 1816 insertions(+), 149 deletions(-) create mode 100644 c/src/tests/samples/unlimited/Makefile.in create mode 100644 c/src/tests/samples/unlimited/init.c create mode 100644 c/src/tests/samples/unlimited/system.h create mode 100644 c/src/tests/samples/unlimited/test1.c create mode 100644 c/src/tests/samples/unlimited/test2.c create mode 100644 c/src/tests/samples/unlimited/test3.c create mode 100644 c/src/tests/samples/unlimited/unlimited.doc create mode 100644 c/src/tests/samples/unlimited/unlimited.scn (limited to 'c/src') diff --git a/c/src/exec/rtems/src/msg.c b/c/src/exec/rtems/src/msg.c index 2768050d8f..b0222601f0 100644 --- a/c/src/exec/rtems/src/msg.c +++ b/c/src/exec/rtems/src/msg.c @@ -31,6 +31,20 @@ #include #include +/*PAGE + * + * _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT + * + * Condition support for the MP. Helps the macro build. + * + */ + +#if defined(RTEMS_MULTIPROCESSING) +#define _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT _Message_queue_Core_message_queue_mp_support +#else +#define _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT NULL +#endif + /*PAGE * * _Message_queue_Manager_initialization @@ -450,11 +464,7 @@ rtems_status_code rtems_message_queue_broadcast( buffer, size, id, -#if defined(RTEMS_MULTIPROCESSING) - _Message_queue_Core_message_queue_mp_support, -#else - NULL, -#endif + _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT, count ); @@ -718,11 +728,7 @@ rtems_status_code _Message_queue_Submit( buffer, size, id, -#if defined(RTEMS_MULTIPROCESSING) - _Message_queue_Core_message_queue_mp_support -#else - NULL -#endif + _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT ); break; case MESSAGE_QUEUE_URGENT_REQUEST: @@ -731,11 +737,7 @@ rtems_status_code _Message_queue_Submit( buffer, size, id, -#if defined(RTEMS_MULTIPROCESSING) - _Message_queue_Core_message_queue_mp_support -#else - NULL -#endif + _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT ); break; default: diff --git a/c/src/exec/sapi/include/rtems/config.h b/c/src/exec/sapi/include/rtems/config.h index 5a01286059..ac2da06d97 100644 --- a/c/src/exec/sapi/include/rtems/config.h +++ b/c/src/exec/sapi/include/rtems/config.h @@ -21,6 +21,20 @@ extern "C" { #endif +/* + * Unlimited object support. Changes the configuration table entry for POSIX + * or RTEMS APIs to bounded only by the memory of the work-space. + * + * Use the macro to define the resource unlimited before placing in the configuration + * table. + */ + +#include +#define RTEMS_UNLIMITED_OBJECTS OBJECTS_UNLIMITED_OBJECTS + +#define rtems_resource_unlimited(resource) \ + ( resource | RTEMS_UNLIMITED_OBJECTS ) + /* * This is kind of kludgy but it allows targets to totally ignore the * POSIX API safely. diff --git a/c/src/exec/score/include/rtems/score/object.h b/c/src/exec/score/include/rtems/score/object.h index a0bf3707b6..7c72719679 100644 --- a/c/src/exec/score/include/rtems/score/object.h +++ b/c/src/exec/score/include/rtems/score/object.h @@ -25,6 +25,14 @@ extern "C" { #include +/* + * Mask to enable unlimited objects + * + * XXX - needs to be moved to the API some-where + */ + +#define OBJECTS_UNLIMITED_OBJECTS 0x80000000 + /* * The following type defines the control block used to manage * object names. @@ -121,9 +129,9 @@ typedef enum { */ typedef struct { - Chain_Node Node; - Objects_Id id; - Objects_Name name; + Chain_Node Node; + Objects_Id id; + Objects_Name name; } Objects_Control; /* @@ -132,18 +140,24 @@ typedef struct { */ typedef struct { - Objects_Classes the_class; /* Class of this object */ - Objects_Id minimum_id; /* minimum valid id of this type */ - Objects_Id maximum_id; /* maximum valid id of this type */ - unsigned32 maximum; /* maximum number of objects */ - Objects_Control **local_table; /* table of local object pointers */ - Objects_Name *name_table; /* table of local object names */ - Chain_Control *global_table; /* pointer to global table */ - Chain_Control Inactive; /* chain of inactive ctl blocks */ - boolean is_string; /* TRUE if names are strings */ - unsigned32 name_length; /* maximum length of names */ - boolean is_thread; /* TRUE if these are threads */ - /* irregardless of API */ + Objects_Classes the_class; /* Class of this object */ + Objects_Id minimum_id; /* minimum valid id of this type */ + Objects_Id maximum_id; /* maximum valid id of this type */ + unsigned32 maximum; /* maximum number of objects */ + boolean auto_extend; /* TRUE if unlimited objects */ + unsigned32 allocation_size; /* number of objects in a block */ + unsigned32 size; /* size of the objects */ + Objects_Control **local_table; + Objects_Name *name_table; + Chain_Control *global_table; /* pointer to global table */ + Chain_Control Inactive; /* chain of inactive ctl blocks */ + unsigned32 inactive; /* number of objects on the InActive list */ + unsigned32 *inactive_per_block; /* used to release a block */ + void **object_blocks; /* the object memory to remove */ + boolean is_string; /* TRUE if names are strings */ + unsigned32 name_length; /* maximum length of names */ + boolean is_thread; /* TRUE if these are threads */ + /* irregardless of API */ } Objects_Information; /* @@ -207,6 +221,30 @@ void _Objects_Handler_initialization( unsigned32 maximum_global_objects ); +/* + * _Objects_Extend_information + * + * DESCRIPTION: + * + * This function extends an object class information record. + */ + +void _Objects_Extend_information( + Objects_Information *information +); + +/* + * _Objects_Shrink_information + * + * DESCRIPTION: + * + * This function shrink an object class information record. + */ + +void _Objects_Shrink_information( + Objects_Information *information +); + /* * _Objects_Initialize_information * @@ -232,6 +270,35 @@ void _Objects_Initialize_information ( boolean is_task ); +/*PAGE + * + * _Objects_Allocate + * + * DESCRIPTION: + * + * This function allocates a object control block from + * the inactive chain of free object control blocks. + */ + +Objects_Control *_Objects_Allocate( + Objects_Information *information +); + +/*PAGE + * + * _Objects_Free + * + * DESCRIPTION: + * + * This function frees a object control block to the + * inactive chain of free object control blocks. + */ + +void _Objects_Free( + Objects_Information *information, + Objects_Control *the_object +); + /* * _Objects_Clear_name * @@ -369,19 +436,6 @@ Objects_Control *_Objects_Get_next( Objects_Id *next_id_p ); -/* - * _Objects_Get_information - * - * DESCRIPTION: - * - * Returns the information control block for the class of objects - * corresponding to this id. - */ - -Objects_Information *_Objects_Get_information( - Objects_Id id -); - /* * Pieces of object.inl are promoted out to the user */ diff --git a/c/src/exec/score/inline/rtems/score/coremsg.inl b/c/src/exec/score/inline/rtems/score/coremsg.inl index a43b0e7b06..d4dafd8fdc 100644 --- a/c/src/exec/score/inline/rtems/score/coremsg.inl +++ b/c/src/exec/score/inline/rtems/score/coremsg.inl @@ -41,7 +41,11 @@ RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send( buffer, size, id, +#if defined(RTEMS_MULTIPROCESSING) api_message_queue_mp_support, +#else + NULL, +#endif CORE_MESSAGE_QUEUE_SEND_REQUEST ); } @@ -68,7 +72,11 @@ RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent( buffer, size, id, +#if defined(RTEMS_MULTIPROCESSING) api_message_queue_mp_support, +#else + NULL, +#endif CORE_MESSAGE_QUEUE_URGENT_REQUEST ); } diff --git a/c/src/exec/score/inline/rtems/score/object.inl b/c/src/exec/score/inline/rtems/score/object.inl index 7e4d12aeec..ce149f33d8 100644 --- a/c/src/exec/score/inline/rtems/score/object.inl +++ b/c/src/exec/score/inline/rtems/score/object.inl @@ -158,37 +158,67 @@ RTEMS_INLINE_ROUTINE boolean _Objects_Are_ids_equal( /*PAGE * - * _Objects_Allocate + * _Objects_Get_local_object * * DESCRIPTION: * - * This function allocates a object control block from - * the inactive chain of free object control blocks. + * This function returns a pointer to the local_table object + * referenced by the index. */ -RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Allocate( - Objects_Information *information +RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_local_object( + Objects_Information *information, + unsigned32 index ) { - return (Objects_Control *) _Chain_Get( &information->Inactive ); + if ( index > information->maximum) + return NULL; + return ( information->local_table[ index ] ); } /*PAGE * - * _Objects_Free + * _Objects_Set_local_object * * DESCRIPTION: * - * This function frees a object control block to the - * inactive chain of free object control blocks. + * This function sets the pointer to the local_table object + * referenced by the index. */ -RTEMS_INLINE_ROUTINE void _Objects_Free( +RTEMS_INLINE_ROUTINE void _Objects_Set_local_object( Objects_Information *information, + unsigned32 index, Objects_Control *the_object ) { - _Chain_Append( &information->Inactive, &the_object->Node ); + if ( index <= information->maximum) + information->local_table[ index ] = the_object; +} + + +/*PAGE + * + * _Objects_Get_information + * + * DESCRIPTION: + * + * This function return the information structure given + * an id of an object. + */ + +RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information( + Objects_Id id +) +{ + Objects_Classes the_class; + + the_class = _Objects_Get_class( id ); + + if ( !_Objects_Is_class_valid( the_class ) ) + return NULL; + + return _Objects_Information_table[ the_class ]; } /*PAGE @@ -210,7 +240,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Open( unsigned32 index; index = _Objects_Get_index( the_object->id ); - information->local_table[ index ] = the_object; + _Objects_Set_local_object( information, index, the_object ); if ( information->is_string ) _Objects_Copy_name_string( name, the_object->name ); @@ -236,7 +266,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Close( unsigned32 index; index = _Objects_Get_index( the_object->id ); - information->local_table[ index ] = (Objects_Control *) NULL; + _Objects_Set_local_object( information, index, NULL ); _Objects_Clear_name( the_object->name, information->name_length ); } diff --git a/c/src/exec/score/macros/rtems/score/object.inl b/c/src/exec/score/macros/rtems/score/object.inl index cce2cbde9b..62994ee4e5 100644 --- a/c/src/exec/score/macros/rtems/score/object.inl +++ b/c/src/exec/score/macros/rtems/score/object.inl @@ -93,21 +93,39 @@ /*PAGE * - * _Objects_Allocate + * _Objects_Get_local_object * */ -#define _Objects_Allocate( _information ) \ - (Objects_Control *) _Chain_Get( &(_information)->Inactive ) +#define _Objects_Get_local_object( information, index ) \ + ( ( index > information->maximum) ? NULL : \ + information->local_table[ index ] ) /*PAGE * - * _Objects_Free + * _Objects_Set_local_object * */ -#define _Objects_Free( _information, _the_object ) \ - _Chain_Append( &(_information)->Inactive, &(_the_object)->Node ) +#define _Objects_Set_local_object( information, index, the_object ) \ + { \ + if ( index <= information->maximum) \ + information->local_table[ index ] = the_object; \ + } + + +/*PAGE + * + * _Objects_Get_information + * + */ + +#define _Objects_Get_information( id ) \ + ( \ + ( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \ + NULL : \ + _Objects_Information_table[ _Objects_Get_class( id ) ] \ + ) /*PAGE * diff --git a/c/src/exec/score/macros/rtems/score/userext.inl b/c/src/exec/score/macros/rtems/score/userext.inl index 37b0bf8d2a..69fd0de4b1 100644 --- a/c/src/exec/score/macros/rtems/score/userext.inl +++ b/c/src/exec/score/macros/rtems/score/userext.inl @@ -23,14 +23,22 @@ * */ -#define _User_extensions_Handler_initialization( _initial_extensions ) \ +#define _User_extensions_Handler_initialization( \ + number_of_extensions, _initial_extensions \ +) \ { \ + User_extensions_Control *extension; \ + unsigned32 i; \ _Chain_Initialize_empty( &_User_extensions_List ); \ \ if ( (_initial_extensions) ) { \ - _User_extensions_Initial.Callouts = *(_initial_extensions); \ - _Chain_Append( \ - &_User_extensions_List, &_User_extensions_Initial.Node ); \ + for (i=0 ; iCallouts = _initial_extensions[i]; \ + _Chain_Append( &_User_extensions_List, &extension->Node ); \ + } \ } \ } diff --git a/c/src/exec/score/src/object.c b/c/src/exec/score/src/object.c index 81bca89d7c..cbbe889a79 100644 --- a/c/src/exec/score/src/object.c +++ b/c/src/exec/score/src/object.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #if defined(RTEMS_MULTIPROCESSING) @@ -22,6 +23,7 @@ #include #include #include +#include /*PAGE * @@ -62,6 +64,352 @@ void _Objects_Handler_initialization( #endif } +/*PAGE + * + * _Objects_Extend_information + * + * This routine extends all object information related data structures. + * + * Input parameters: + * information - object information table + * + * Output parameters: NONE + */ + +void _Objects_Extend_information( + Objects_Information *information +) +{ + Objects_Control *the_object; + void *name_area; + Chain_Control Inactive; + unsigned32 block_count; + unsigned32 block; + unsigned32 index_base; + unsigned32 minimum_index; + unsigned32 index; + + /* + * Search for a free block of indexes. The block variable ends up set + * to block_count + 1 if the table needs to be extended. + */ + + minimum_index = _Objects_Get_index( information->minimum_id ); + index_base = minimum_index; + block = 0; + + if (information->maximum < minimum_index) + block_count = 0; + else { + block_count = information->maximum / information->allocation_size; + + for ( ; block < block_count; block++ ) { + if ( information->object_blocks[ block ] == NULL ) + break; + else + index_base += information->allocation_size; + } + } + + /* + * If the index_base is the maximum we need to grow the tables. + */ + + if (index_base >= information->maximum ) { + ISR_Level level; + void **object_blocks; + Objects_Name *name_table; + unsigned32 *inactive_per_block; + Objects_Control **local_table; + unsigned32 maximum; + void *old_tables; + + /* + * Growing the tables means allocating a new area, doing a copy and updating + * the information table. + * + * If the maximum is minimum we do not have a table to copy. First time through. + * + * The allocation has : + * + * void *objects[block_count]; + * unsiged32 inactive_count[block_count]; + * Objects_Name *name_table[block_count]; + * Objects_Control *local_table[maximum]; + * + * This is the order in memory. Watch changing the order. See the memcpy + * below. + */ + + /* + * Up the block count and maximum + */ + + block_count++; + + maximum = information->maximum + information->allocation_size; + + /* + * Allocate the tables and break it up. + */ + + if ( information->auto_extend ) { + object_blocks = (void**) + _Workspace_Allocate( + block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) + + ((maximum + minimum_index) * sizeof(Objects_Control *)) + ); + + if ( !object_blocks ) + return; + } + else { + object_blocks = (void**) + _Workspace_Allocate_or_fatal_error( + block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) + + ((maximum + minimum_index) * sizeof(Objects_Control *)) + ); + } + + /* + * Break the block into the various sections. + * + */ + + inactive_per_block = + (unsigned32 *) _Addresses_Add_offset( object_blocks, block_count * sizeof(void*) ); + name_table = + (Objects_Name *) _Addresses_Add_offset( inactive_per_block, + block_count * sizeof(unsigned32) ); + local_table = + (Objects_Control **) _Addresses_Add_offset( name_table, + block_count * sizeof(Objects_Name *) ); + + /* + * Take the block count down. Saves all the (block_count - 1) in the copies. + */ + + block_count--; + + if ( information->maximum > minimum_index ) { + + /* + * Copy each section of the table over. This has to be performed as + * separate parts as size of each block has changed. + */ + + memcpy( object_blocks, + information->object_blocks, + block_count * sizeof(void*) ); + memcpy( inactive_per_block, + information->inactive_per_block, + block_count * sizeof(unsigned32) ); + memcpy( name_table, + information->name_table, + block_count * sizeof(Objects_Name *) ); + memcpy( local_table, + information->local_table, + (information->maximum + minimum_index) * sizeof(Objects_Control *) ); + } + else { + + /* + * Deal with the special case of the 0 to minimum_index + */ + for ( index = 0; index < minimum_index; index++ ) { + local_table[ index ] = NULL; + } + } + + /* + * Initialise the new entries in the table. + */ + + object_blocks[block_count] = NULL; + inactive_per_block[block_count] = 0; + name_table[block_count] = NULL; + + for ( index=index_base ; + index < ( information->allocation_size + index_base ); + index++ ) { + local_table[ index ] = NULL; + } + + _ISR_Disable( level ); + + old_tables = information->object_blocks; + + information->object_blocks = object_blocks; + information->inactive_per_block = inactive_per_block; + information->name_table = name_table; + information->local_table = local_table; + information->maximum = maximum; + information->maximum_id = + _Objects_Build_id( + information->the_class, _Objects_Local_node, information->maximum + ); + + _ISR_Enable( level ); + + if ( old_tables ) + _Workspace_Free( old_tables ); + + block_count++; + } + + /* + * Allocate the name table, and the objects + */ + + if ( information->auto_extend ) { + information->object_blocks[ block ] = + _Workspace_Allocate( + (information->allocation_size * information->name_length) + + (information->allocation_size * information->size) + ); + + if ( !information->object_blocks[ block ] ) + return; + } + else { + information->object_blocks[ block ] = + _Workspace_Allocate_or_fatal_error( + (information->allocation_size * information->name_length) + + (information->allocation_size * information->size) + ); + } + + name_area = (Objects_Name *) information->object_blocks[ block ]; + information->name_table[ block ] = name_area; + + /* + * Initialize objects .. add to a local chain first. + */ + + _Chain_Initialize( + &Inactive, + _Addresses_Add_offset( information->object_blocks[ block ], + (information->allocation_size * information->name_length) ), + information->allocation_size, + information->size + ); + + /* + * Move from the local chain, initialise, then append to the inactive chain + */ + + index = index_base; + + while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) { + + the_object->id = + _Objects_Build_id( + information->the_class, _Objects_Local_node, index + ); + + the_object->name = (void *) name_area; + + name_area = _Addresses_Add_offset( name_area, information->name_length ); + + _Chain_Append( &information->Inactive, &the_object->Node ); + + index++; + } + + information->inactive_per_block[ block ] = information->allocation_size; + information->inactive += information->allocation_size; +} + +/*PAGE + * + * _Objects_Shrink_information + * + * This routine shrinks object information related data structures. + * The object's name and object space are released. The local_table + * etc block does not shrink. The InActive list needs to be scanned + * to find the objects are remove them. + * Input parameters: + * information - object information table + * the_block - the block to remove + * + * Output parameters: NONE + */ + +void _Objects_Shrink_information( + Objects_Information *information +) +{ + Objects_Control *the_object; + Objects_Control *extract_me; + unsigned32 block_count; + unsigned32 block; + unsigned32 index_base; + unsigned32 index; + + /* + * Search the list to find block or chunnk with all objects inactive. + */ + + index_base = _Objects_Get_index( information->minimum_id ); + block_count = ( information->maximum - index_base ) / information->allocation_size; + + for ( block = 0; block < block_count; block++ ) { + if ( information->inactive_per_block[ block ] == information->allocation_size ) { + + /* + * XXX - Not to sure how to use a chain where you need to iterate and + * and remove elements. + */ + + the_object = (Objects_Control *) information->Inactive.first; + + /* + * Assume the Inactive chain is never empty at this point + */ + + do { + index = _Objects_Get_index( the_object->id ); + + if ((index >= index_base) && + (index < (index_base + information->allocation_size))) { + + /* + * Get the next node before the node is extracted + */ + + extract_me = the_object; + + if ( !_Chain_Is_last( &the_object->Node ) ) + the_object = (Objects_Control *) the_object->Node.next; + else + the_object = NULL; + + _Chain_Extract( &extract_me->Node ); + } + else { + the_object = (Objects_Control *) the_object->Node.next; + } + } + while ( the_object && !_Chain_Is_last( &the_object->Node ) ); + + /* + * Free the memory and reset the structures in the object' information + */ + + _Workspace_Free( information->object_blocks[ block ] ); + information->name_table[ block ] = NULL; + information->object_blocks[ block ] = NULL; + information->inactive_per_block[ block ] = 0; + + information->inactive -= information->allocation_size; + + return; + } + + index_base += information->allocation_size; + } +} + /*PAGE * * _Objects_Initialize_information @@ -93,15 +441,19 @@ void _Objects_Initialize_information( { unsigned32 minimum_index; unsigned32 index; - Objects_Control *the_object; unsigned32 name_length; - void *name_area; - - information->maximum = maximum; - information->the_class = the_class; - information->is_string = is_string; - information->is_thread = is_thread; + information->the_class = the_class; + information->is_string = is_string; + information->is_thread = is_thread; + + information->local_table = 0; + information->name_table = 0; + information->inactive_per_block = 0; + information->object_blocks = 0; + + information->inactive = 0; + /* * Set the entry in the object information table. */ @@ -109,29 +461,36 @@ void _Objects_Initialize_information( _Objects_Information_table[ the_class ] = information; /* - * Calculate minimum and maximum Id's + * Set the size of the object */ - if ( maximum == 0 ) minimum_index = 0; - else minimum_index = 1; + information->size = size; + + /* + * Are we operating in unlimited, or auto-extend mode + */ - information->minimum_id = - _Objects_Build_id( the_class, _Objects_Local_node, minimum_index ); + information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE; + maximum &= ~OBJECTS_UNLIMITED_OBJECTS; + + /* + * The allocation unit is the maximum value + */ - information->maximum_id = - _Objects_Build_id( the_class, _Objects_Local_node, maximum ); + information->allocation_size = maximum; /* - * Allocate local pointer table + * Calculate minimum and maximum Id's */ - information->local_table = - (Objects_Control **) _Workspace_Allocate_or_fatal_error( - (maximum + 1) * sizeof(Objects_Control *) - ); + if ( maximum == 0 ) minimum_index = 0; + else minimum_index = 1; + + information->minimum_id = + _Objects_Build_id( the_class, _Objects_Local_node, minimum_index ); /* - * Allocate name table + * Calculate the maximum name length */ name_length = maximum_name_length; @@ -142,45 +501,29 @@ void _Objects_Initialize_information( information->name_length = name_length; - name_area = (Objects_Name *) - _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length ); - information->name_table = name_area; - - /* - * Initialize local pointer table - */ - - for ( index=0 ; index <= maximum ; index++ ) { - information->local_table[ index ] = NULL; - } - + _Chain_Initialize_empty( &information->Inactive ); + /* * Initialize objects .. if there are any */ - if ( maximum == 0 ) { - _Chain_Initialize_empty( &information->Inactive ); - } else { - - _Chain_Initialize( - &information->Inactive, - _Workspace_Allocate_or_fatal_error( maximum * size ), - maximum, - size - ); - - the_object = (Objects_Control *) information->Inactive.first; - for ( index=1; index <= maximum ; index++ ) { - the_object->id = - _Objects_Build_id( the_class, _Objects_Local_node, index ); - - the_object->name = (void *) name_area; - - name_area = _Addresses_Add_offset( name_area, name_length ); - - the_object = (Objects_Control *) the_object->Node.next; - } + if ( maximum ) { + /* + * Reset the maximum value. It will be updated when the information is + * extended. + */ + + information->maximum = 0; + + /* + * Always have the maximum size available so the current performance + * figures are create are met. If the user moves past the maximum + * number then a performance hit is taken. + */ + + _Objects_Extend_information( information ); + } /* @@ -201,6 +544,89 @@ void _Objects_Initialize_information( information->global_table = NULL; } +/*PAGE + * + * _Objects_Allocate + * + * DESCRIPTION: + * + * This function allocates a object control block from + * the inactive chain of free object control blocks. + */ + +Objects_Control *_Objects_Allocate( + Objects_Information *information +) +{ + Objects_Control *the_object = + (Objects_Control *) _Chain_Get( &information->Inactive ); + + if ( information->auto_extend ) { + /* + * If the list is empty then we are out of objects and need to + * extend information base. + */ + + if ( !the_object ) { + _Objects_Extend_information( information ); + the_object = (Objects_Control *) _Chain_Get( &information->Inactive ); + } + + if ( the_object ) { + unsigned32 block; + + block = + _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id ); + block /= information->allocation_size; + + information->inactive_per_block[ block ]--; + information->inactive--; + } + } + + return the_object; +} + +/*PAGE + * + * _Objects_Free + * + * DESCRIPTION: + * + * This function frees a object control block to the + * inactive chain of free object control blocks. + */ + +void _Objects_Free( + Objects_Information *information, + Objects_Control *the_object +) +{ + unsigned32 allocation_size = information->allocation_size; + + _Chain_Append( &information->Inactive, &the_object->Node ); + + if ( information->auto_extend ) { + unsigned32 block; + + block = + _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id ); + block /= information->allocation_size; + + information->inactive_per_block[ block ]++; + information->inactive++; + + /* + * Check if the threshold level has been met of + * 1.5 x allocation_size are free. + */ + + if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) { + _Objects_Shrink_information( information ); + } + } +} + /*PAGE * * _Objects_Clear_name @@ -341,7 +767,6 @@ Objects_Name_to_id_errors _Objects_Name_to_id( ) { boolean search_local_node; - Objects_Control **objects; Objects_Control *the_object; unsigned32 index; unsigned32 name_length; @@ -358,8 +783,6 @@ Objects_Name_to_id_errors _Objects_Name_to_id( search_local_node = TRUE; if ( search_local_node ) { - objects = information->local_table; - name_length = information->name_length; if ( information->is_string ) compare_them = _Objects_Compare_name_string; @@ -367,7 +790,7 @@ Objects_Name_to_id_errors _Objects_Name_to_id( for ( index = 1; index <= information->maximum; index++ ) { - the_object = objects[ index ]; + the_object = information->local_table[ index ]; if ( !the_object || !the_object->name ) continue; @@ -418,11 +841,11 @@ Objects_Control *_Objects_Get( Objects_Control *the_object; unsigned32 index; - index = id - information->minimum_id; + index = _Objects_Get_index( id ); if ( information->maximum >= index ) { _Thread_Disable_dispatch(); - if ( (the_object = information->local_table[index+1]) != NULL ) { + if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) { *location = OBJECTS_LOCAL; return( the_object ); } @@ -505,24 +928,3 @@ final: return 0; } -/*PAGE - * - * _Objects_Get_information - * - * XXX - */ - -Objects_Information *_Objects_Get_information( - Objects_Id id -) -{ - Objects_Classes the_class; - - the_class = _Objects_Get_class( id ); - - if ( !_Objects_Is_class_valid( the_class ) ) - return NULL; - - return _Objects_Information_table[ the_class ]; -} - diff --git a/c/src/make/compilers/gcc-target-default.cfg b/c/src/make/compilers/gcc-target-default.cfg index 4fc69721d7..b29a96e325 100644 --- a/c/src/make/compilers/gcc-target-default.cfg +++ b/c/src/make/compilers/gcc-target-default.cfg @@ -72,7 +72,7 @@ GCCSPECS = -B$(PROJECT_RELEASE)/lib/ -specs bsp_specs -qrtems CC += $(GCCSPECS) CXX += $(GCCSPECS) -CPPFLAGS += -I$(srcdir) $(INCLUDE_NETWORKING) +CPPFLAGS += $(INCLUDE_NETWORKING) # default location of Standard C Library ifndef LIBC_LIBC diff --git a/c/src/tests/samples/Makefile.in b/c/src/tests/samples/Makefile.in index 8f8397fef4..463ff7e710 100644 --- a/c/src/tests/samples/Makefile.in +++ b/c/src/tests/samples/Makefile.in @@ -27,7 +27,7 @@ MP_TESTS = $(MP_TESTS_$(HAS_MP)_V) FP_TESTS = paranoia -SUB_DIRS=hello ticker base_sp \ +SUB_DIRS=hello ticker base_sp unlimited \ $(MP_TESTS) $(CPLUSPLUS_TESTS) $(FP_TESTS) diff --git a/c/src/tests/samples/unlimited/Makefile.in b/c/src/tests/samples/unlimited/Makefile.in new file mode 100644 index 0000000000..a02f61f64f --- /dev/null +++ b/c/src/tests/samples/unlimited/Makefile.in @@ -0,0 +1,63 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +SAMPLE=unlimited +PGM=${ARCH}/$(SAMPLE).exe + +MANAGERS=io event + +# C source names, if any, go here -- minus the .c +C_PIECES=init test1 test2 test3 +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES=system.h + +DOCTYPES=doc scn +DOCS=$(DOCTYPES:%=$(SAMPLE).%) + +SRCS=$(DOCS) $(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +PRINT_SRCS=$(DOCS) + +PGM=${ARCH}/$(SAMPLE).exe + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(PGM) + $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/tests + $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/samples + +${PGM}: $(OBJS) $(LINK_FILES) + $(make-exe) diff --git a/c/src/tests/samples/unlimited/init.c b/c/src/tests/samples/unlimited/init.c new file mode 100644 index 0000000000..40614efaa7 --- /dev/null +++ b/c/src/tests/samples/unlimited/init.c @@ -0,0 +1,126 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is called from init_exec and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#define TEST_INIT + +#include "system.h" +#include + +rtems_id task_id[MAX_TASKS]; + +void test1(); +void test2(); + +rtems_task Init( + rtems_task_argument ignored +) +{ + rtems_task_priority old_priority; + rtems_mode old_mode; + rtems_unsigned32 task; + + /* lower the task priority to allow created tasks to execute */ + + rtems_task_set_priority(RTEMS_SELF, 20, &old_priority); + rtems_task_mode(RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, &old_mode); + + printf( "\n*** UNLIMITED TASK TEST ***\n" ); + + /* + * Invalid state if the task id is 0 + */ + + for (task = 0; task < MAX_TASKS; task++) + task_id[task] = 0; + + test1(); + test2(); + test3(); + + printf( "\n*** END OF UNLIMITED TASK TEST ***\n" ); + exit( 0 ); +} + +rtems_task test_task( + rtems_task_argument my_number + ) +{ + rtems_event_set out; + + printf( "task %i has started.\n", my_number); + + rtems_event_receive(1, RTEMS_WAIT | RTEMS_EVENT_ANY, 0, &out); + + printf( "task %i ending.\n", my_number); + + rtems_task_delete(RTEMS_SELF); +} + +void destory_all_tasks( + const char *who +) +{ + rtems_unsigned32 task; + + /* + * If the id is not zero, signal the task to delete. + */ + + for (task = 0; task < MAX_TASKS; task++) + if (task_id[task]) + { + printf(" %s : signal task %08x to delete, ", who, task_id[task]); + rtems_event_send(task_id[task], 1); + task_id[task] = 0; + } +} + +boolean status_code_bad( + rtems_status_code status_code + ) +{ + if (status_code != RTEMS_SUCCESSFUL) + { + printf("failure, "); + + if (status_code == RTEMS_TOO_MANY) + { + printf("too many.\n"); + return TRUE; + } + if (status_code == RTEMS_UNSATISFIED) + { + printf("unsatisfied.\n"); + return TRUE; + } + + printf("error code = %i\n", status_code); + exit( 1 ); + } + return FALSE; +} + + + + + diff --git a/c/src/tests/samples/unlimited/system.h b/c/src/tests/samples/unlimited/system.h new file mode 100644 index 0000000000..51a2bcee88 --- /dev/null +++ b/c/src/tests/samples/unlimited/system.h @@ -0,0 +1,93 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the test set. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +#define TASK_ALLOCATION_SIZE (5) +#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(TASK_ALLOCATION_SIZE) + +#include + +/* functions */ + +rtems_task Init( + rtems_task_argument argument +); + +rtems_task test_task( + rtems_task_argument my_number +); + +void +destory_all_tasks( + const char *who +); + +boolean status_code_bad( + rtems_status_code status_code +); + +void test1(); +void test2(); +void test3(); + +/* configuration information */ + +#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#include + +/* global variables */ + +TEST_EXTERN rtems_id Global_variable; /* example global variable */ + +/* + * Keep track of the task id's created, use a large array. + */ + +#define MAX_TASKS (1000) +#define TASK_INDEX_OFFSET (1) + +extern rtems_id task_id[MAX_TASKS]; + +/* + * Increment the task name. + */ + +#define NEXT_TASK_NAME(c1, c2, c3, c4) \ + if (c4 == '9') { \ + if (c3 == '9') { \ + if (c2 == 'z') { \ + if (c1 == 'z') { \ + printf("not enough task letters for names !!!\n"); \ + exit( 1 ); \ + } else \ + c1++; \ + c2 = 'a'; \ + } else \ + c2++; \ + c3 = '0'; \ + } else \ + c3++; \ + c4 = '0'; \ + } \ + else \ + c4++ \ + + +/* end of include file */ diff --git a/c/src/tests/samples/unlimited/test1.c b/c/src/tests/samples/unlimited/test1.c new file mode 100644 index 0000000000..2f415492d9 --- /dev/null +++ b/c/src/tests/samples/unlimited/test1.c @@ -0,0 +1,102 @@ +/* Test1 + * + * This test uses a hack to disable suto-extend then checks to see only the + * requested number of objects are allocated. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "system.h" +#include +#include + +void test1() +{ + boolean auto_extend; + rtems_status_code result; + rtems_unsigned32 task_count = 0; + + char c1 = 'a'; + char c2 = 'a'; + char c3 = '0'; + char c4 = '0'; + + printf( "\n TEST1 : auto-extend disabled.\n" ); + + /* + * This is a major hack and only recommended for a test. Doing this + * saves having another test. + */ + + auto_extend = _Objects_Information_table[OBJECTS_RTEMS_TASKS]->auto_extend; + _Objects_Information_table[OBJECTS_RTEMS_TASKS]->auto_extend = FALSE; + + while (task_count < MAX_TASKS) + { + rtems_name name; + + printf(" TEST1 : creating task '%c%c%c%c', ", c1, c2, c3, c4); + + name = rtems_build_name(c1, c2, c3, c4); + + result = rtems_task_create(name, + 10, + 4096, + RTEMS_DEFAULT_ATTRIBUTES, + RTEMS_LOCAL, + &task_id[task_count]); + + if (status_code_bad(result)) + break; + + printf("number = %3i, id = %08x, starting, ", task_count, task_id[task_count]); + + result = rtems_task_start(task_id[task_count], + test_task, + (rtems_task_argument) task_count); + + if (status_code_bad(result)) + break; + + /* + * Update the name. + */ + + NEXT_TASK_NAME(c1, c2, c3, c4); + + task_count++; + } + + if (task_count >= MAX_TASKS) + printf( "\nMAX_TASKS too small for work-space size, please make larger !!\n\n" ); + + if (task_count != (TASK_ALLOCATION_SIZE - 1)) { + printf( " FAIL1 : the number of tasks does not equal the expected size -\n" + " task created = %i, required number = %i\n", + task_count, TASK_ALLOCATION_SIZE); + exit( 1 ); + } + + destory_all_tasks("TEST1"); + + _Objects_Information_table[OBJECTS_RTEMS_TASKS]->auto_extend = auto_extend; + + printf( " TEST1 : completed\n" ); +} + + + + + diff --git a/c/src/tests/samples/unlimited/test2.c b/c/src/tests/samples/unlimited/test2.c new file mode 100644 index 0000000000..d25f95da02 --- /dev/null +++ b/c/src/tests/samples/unlimited/test2.c @@ -0,0 +1,228 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is called from init_exec and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "system.h" +#include + +void test2() +{ + rtems_status_code result; + rtems_unsigned32 remove_task; + rtems_unsigned32 task; + rtems_unsigned32 block; + rtems_unsigned32 task_count = 0; + rtems_id removed_ids[TASK_ALLOCATION_SIZE * 2]; + + char c1 = 'a'; + char c2 = 'a'; + char c3 = '0'; + char c4 = '0'; + + printf( "\n TEST2 : re-allocate of index numbers, and a block free'ed and one inactive\n" ); + + /* + * Allocate enought tasks so the Inactive list is empty. Remember + * to count the Init task, ie ... - 1. + */ + + while (task_count < ((TASK_ALLOCATION_SIZE * 5) - TASK_INDEX_OFFSET)) + { + rtems_name name; + + printf(" TEST2 : creating task '%c%c%c%c', ", c1, c2, c3, c4); + + name = rtems_build_name(c1, c2, c3, c4); + + result = rtems_task_create(name, + 10, + 4096, + RTEMS_DEFAULT_ATTRIBUTES, + RTEMS_LOCAL, + &task_id[task_count]); + + if (status_code_bad(result)) + break; + + printf("number = %3i, id = %08x, starting, ", task_count, task_id[task_count]); + + result = rtems_task_start(task_id[task_count], + test_task, + (rtems_task_argument) task_count); + + if (status_code_bad(result)) + break; + + /* + * Update the name. + */ + + NEXT_TASK_NAME(c1, c2, c3, c4); + + task_count++; + } + + /* + * Take out the second and fourth allocation size block of tasks + */ + + if (task_count != ((TASK_ALLOCATION_SIZE * 5) - TASK_INDEX_OFFSET)) { + printf( " FAIL2 : not enough tasks created -\n" + " task created = %i, required number = %i\n", + task_count, (TASK_ALLOCATION_SIZE * 5) - TASK_INDEX_OFFSET); + destory_all_tasks("TEST2"); + exit( 1 ); + } + + task = 0; + + for (block = 1; block < 4; block += 2) + { + for (remove_task = (block * TASK_ALLOCATION_SIZE) - TASK_INDEX_OFFSET; + remove_task < (((block + 1) * TASK_ALLOCATION_SIZE) - TASK_INDEX_OFFSET); + remove_task++) + { + if (!task_id[remove_task]) + { + printf( " FAIL2 : remove task has a 0 id -\n" + " task number = %i\n", + remove_task); + destory_all_tasks("TEST2"); + exit( 1 ); + } + + /* + * Save the id's to match them against the reallocated ids + */ + + removed_ids[task++] = task_id[remove_task]; + + printf(" TEST2 : block %i remove, signal task %08x, ", block, task_id[remove_task]); + rtems_event_send(task_id[remove_task], 1); + task_id[remove_task] = 0; + } + } + + for (task = 0; task < (TASK_ALLOCATION_SIZE * 2); task++) + { + rtems_name name; + rtems_unsigned32 id_slot; + + /* + * Find a free slot in the task id table. + */ + + for (id_slot = 0; id_slot < MAX_TASKS; id_slot++) + if (!task_id[id_slot]) + break; + + if (id_slot == MAX_TASKS) + { + printf( " FAIL2 : no free task id slot.\n"); + destory_all_tasks("TEST2"); + exit( 1 ); + } + + printf(" TEST2 : creating task '%c%c%c%c', ", c1, c2, c3, c4); + + name = rtems_build_name(c1, c2, c3, c4); + + result = rtems_task_create(name, + 10, + 4096, + RTEMS_DEFAULT_ATTRIBUTES, + RTEMS_LOCAL, + &task_id[id_slot]); + + if (status_code_bad(result)) + { + printf( " FAIL2 : re-creating a task -\n" + " task number = %i\n", + id_slot); + destory_all_tasks("TEST2"); + exit( 1 ); + } + + printf("number = %3i, id = %08x, starting, ", task_count, task_id[id_slot]); + + result = rtems_task_start(task_id[id_slot], + test_task, + (rtems_task_argument) task_count); + + if (status_code_bad(result)) + { + printf( " FAIL : re-starting a task -\n" + " task number = %i\n", + id_slot); + destory_all_tasks("TEST2"); + exit( 1 ); + } + + /* + * Update the name. + */ + + NEXT_TASK_NAME(c1, c2, c3, c4); + + /* + * Search the removed ids to see if it existed, clear the removed id when found + */ + + for (remove_task = 0; remove_task < (TASK_ALLOCATION_SIZE * 2); remove_task++) + if (removed_ids[remove_task] == task_id[id_slot]) + { + removed_ids[remove_task] = 0; + break; + } + + /* + * If not located in the removed id table, check and make sure it is not + * already allocated + */ + + if (remove_task == (TASK_ALLOCATION_SIZE * 2)) + { + rtems_unsigned32 allocated_id; + + for (allocated_id = 0; allocated_id < MAX_TASKS; allocated_id++) + if ((task_id[id_slot] == task_id[allocated_id]) && (id_slot != allocated_id)) + { + printf( " FAIL2 : the new id is the same as an id already allocated -\n" + " task id = %08x\n", + task_id[id_slot]); + exit( 1 ); + } + + printf( " FAIL2 : could not find the task id in the removed table -\n" + " task id = %08x\n", + task_id[id_slot]); + exit( 1 ); + } + + task_count++; + } + + destory_all_tasks("TEST2"); + + printf( " TEST2 : completed\n" ); +} + diff --git a/c/src/tests/samples/unlimited/test3.c b/c/src/tests/samples/unlimited/test3.c new file mode 100644 index 0000000000..c7e3091ca0 --- /dev/null +++ b/c/src/tests/samples/unlimited/test3.c @@ -0,0 +1,145 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is called from init_exec and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "system.h" +#include + +void test3() +{ + rtems_status_code result; + rtems_unsigned32 remove_task; + rtems_unsigned32 block; + rtems_unsigned32 task_count = 0; + + char c1 = 'a'; + char c2 = 'a'; + char c3 = '0'; + char c4 = '0'; + + printf( "\n TEST3 : free more than 3 x allocation size, but not the same block,\n" + " then free a block\n"); + + /* + * Check the value of the allocation unit + */ + + if (TASK_ALLOCATION_SIZE < 4) + { + printf( " FAIL3 : task allocation size must be greater than 4.\n"); + exit( 1 ); + } + + /* + * Allocate as many tasks as possible. + */ + + while (task_count < MAX_TASKS) + { + rtems_name name; + + printf(" TEST3 : creating task '%c%c%c%c', ", c1, c2, c3, c4); + + name = rtems_build_name(c1, c2, c3, c4); + + result = rtems_task_create(name, + 10, + 4096, + RTEMS_DEFAULT_ATTRIBUTES, + RTEMS_LOCAL, + &task_id[task_count]); + + if (status_code_bad(result)) + break; + + printf("number = %3i, id = %08x, starting, ", task_count, task_id[task_count]); + + result = rtems_task_start(task_id[task_count], + test_task, + (rtems_task_argument) task_count); + + if (status_code_bad(result)) + break; + + /* + * Update the name. + */ + + NEXT_TASK_NAME(c1, c2, c3, c4); + + task_count++; + } + + /* + * Take out 3 tasks from each block of allocated tasks. Do this for + * allocation size number of blocks. + */ + + if (task_count < (TASK_ALLOCATION_SIZE * 11)) + { + printf( " FAIL3 : not enough tasks created -\n" + " task created = %i, required number = %i\n", + task_count, (TASK_ALLOCATION_SIZE * 11)); + exit( 1 ); + } + + for (block = 0; block < TASK_ALLOCATION_SIZE; block++) + { + for (remove_task = ((block * TASK_ALLOCATION_SIZE) - TASK_INDEX_OFFSET); + remove_task < (((block * TASK_ALLOCATION_SIZE) + 3) - TASK_INDEX_OFFSET); + remove_task++) + { + if (!task_id[remove_task]) + { + printf( " FAIL3 : remove task has a 0 id -\n" + " task number = %i\n", + remove_task); + exit( 1 ); + } + + printf(" TEST3 : remove, signal task %08x, ", task_id[remove_task]); + rtems_event_send(task_id[remove_task], 1); + task_id[remove_task] = 0; + } + } + + /* + * Remove a complete block, not the first, forces a scan of the blocks in the + * allocator's free routine + */ + + for (remove_task = (TASK_ALLOCATION_SIZE - TASK_INDEX_OFFSET); + remove_task < ((TASK_ALLOCATION_SIZE * 2) - - TASK_INDEX_OFFSET); + remove_task++) + { + if (task_id[remove_task]) + { + printf(" TEST3 : remove, signal task %08x, ", task_id[remove_task]); + rtems_event_send(task_id[remove_task], 1); + task_id[remove_task] = 0; + } + } + + destory_all_tasks("TEST3"); + + printf( " TEST3 : completed\n" ); +} diff --git a/c/src/tests/samples/unlimited/unlimited.doc b/c/src/tests/samples/unlimited/unlimited.doc new file mode 100644 index 0000000000..aad9af7f8a --- /dev/null +++ b/c/src/tests/samples/unlimited/unlimited.doc @@ -0,0 +1,37 @@ +# +# $Id$ +# +# COPYRIGHT (c) 1989-1997. +# On-Line Applications Research Corporation (OAR). +# Copyright assigned to U.S. Government, 1994. +# +# The license and distribution terms for this file may in +# the file LICENSE in this distribution or at +# http://www.OARcorp.com/rtems/license.html. +# + +This file describes the directives and concepts tested by this test set. + +test set name: test1 + +directives: + _Object_Allocate, _Object_Free, _Object_Extend_information, + _Object_Shrink_information + +concepts: + + a. Verifies when the auto-extend is false the number of objects does + not grow, and the number of objects is the maximum number specified + in the Configuration table. + + b. Verify the re-allocation of index numbers, and a block of objects is + freed while another remains yet all it objects are not in + use. Four blocks of the allocation size of objects are created, + then the first and third blocks are freed. Only the first + block's memory will be released, while the second remains. This + is due the allocation hystersis. + + c. Allocate as many objects are the work-space can hold. Free objects + from a number of blocks with-out freeing the blocks. Free the remaining + blocks. + diff --git a/c/src/tests/samples/unlimited/unlimited.scn b/c/src/tests/samples/unlimited/unlimited.scn new file mode 100644 index 0000000000..f1c026fe4b --- /dev/null +++ b/c/src/tests/samples/unlimited/unlimited.scn @@ -0,0 +1,337 @@ + +*** UNLIMITED TASK TEST *** + + TEST1 : auto-extend disabled. + TEST1 : creating task 'aa00', number = 0, id = 08010002, starting, task 0 has started. + TEST1 : creating task 'aa01', number = 1, id = 08010003, starting, task 1 has started. + TEST1 : creating task 'aa02', number = 2, id = 08010004, starting, task 2 has started. + TEST1 : creating task 'aa03', number = 3, id = 08010005, starting, task 3 has started. + TEST1 : creating task 'aa04', failure, too many. + TEST1 : signal task 08010002 to delete, task 0 ending. + TEST1 : signal task 08010003 to delete, task 1 ending. + TEST1 : signal task 08010004 to delete, task 2 ending. + TEST1 : signal task 08010005 to delete, task 3 ending. + TEST1 : completed + + TEST2 : re-allocate of index numbers, and a block free'ed and one inactive + TEST2 : creating task 'aa00', number = 0, id = 08010002, starting, task 0 has started. + TEST2 : creating task 'aa01', number = 1, id = 08010003, starting, task 1 has started. + TEST2 : creating task 'aa02', number = 2, id = 08010004, starting, task 2 has started. + TEST2 : creating task 'aa03', number = 3, id = 08010005, starting, task 3 has started. + TEST2 : creating task 'aa04', number = 4, id = 08010006, starting, task 4 has started. + TEST2 : creating task 'aa05', number = 5, id = 08010007, starting, task 5 has started. + TEST2 : creating task 'aa06', number = 6, id = 08010008, starting, task 6 has started. + TEST2 : creating task 'aa07', number = 7, id = 08010009, starting, task 7 has started. + TEST2 : creating task 'aa08', number = 8, id = 0801000a, starting, task 8 has started. + TEST2 : creating task 'aa09', number = 9, id = 0801000b, starting, task 9 has started. + TEST2 : creating task 'aa10', number = 10, id = 0801000c, starting, task 10 has started. + TEST2 : creating task 'aa11', number = 11, id = 0801000d, starting, task 11 has started. + TEST2 : creating task 'aa12', number = 12, id = 0801000e, starting, task 12 has started. + TEST2 : creating task 'aa13', number = 13, id = 0801000f, starting, task 13 has started. + TEST2 : creating task 'aa14', number = 14, id = 08010010, starting, task 14 has started. + TEST2 : creating task 'aa15', number = 15, id = 08010011, starting, task 15 has started. + TEST2 : creating task 'aa16', number = 16, id = 08010012, starting, task 16 has started. + TEST2 : creating task 'aa17', number = 17, id = 08010013, starting, task 17 has started. + TEST2 : creating task 'aa18', number = 18, id = 08010014, starting, task 18 has started. + TEST2 : creating task 'aa19', number = 19, id = 08010015, starting, task 19 has started. + TEST2 : creating task 'aa20', number = 20, id = 08010016, starting, task 20 has started. + TEST2 : creating task 'aa21', number = 21, id = 08010017, starting, task 21 has started. + TEST2 : creating task 'aa22', number = 22, id = 08010018, starting, task 22 has started. + TEST2 : creating task 'aa23', number = 23, id = 08010019, starting, task 23 has started. + TEST2 : block 1 remove, signal task 08010006, task 4 ending. + TEST2 : block 1 remove, signal task 08010007, task 5 ending. + TEST2 : block 1 remove, signal task 08010008, task 6 ending. + TEST2 : block 1 remove, signal task 08010009, task 7 ending. + TEST2 : block 1 remove, signal task 0801000a, task 8 ending. + TEST2 : block 3 remove, signal task 08010010, task 14 ending. + TEST2 : block 3 remove, signal task 08010011, task 15 ending. + TEST2 : block 3 remove, signal task 08010012, task 16 ending. + TEST2 : block 3 remove, signal task 08010013, task 17 ending. + TEST2 : block 3 remove, signal task 08010014, task 18 ending. + TEST2 : creating task 'aa24', number = 24, id = 08010010, starting, task 24 has started. + TEST2 : creating task 'aa25', number = 25, id = 08010011, starting, task 25 has started. + TEST2 : creating task 'aa26', number = 26, id = 08010012, starting, task 26 has started. + TEST2 : creating task 'aa27', number = 27, id = 08010013, starting, task 27 has started. + TEST2 : creating task 'aa28', number = 28, id = 08010014, starting, task 28 has started. + TEST2 : creating task 'aa29', number = 29, id = 08010006, starting, task 29 has started. + TEST2 : creating task 'aa30', number = 30, id = 08010007, starting, task 30 has started. + TEST2 : creating task 'aa31', number = 31, id = 08010008, starting, task 31 has started. + TEST2 : creating task 'aa32', number = 32, id = 08010009, starting, task 32 has started. + TEST2 : creating task 'aa33', number = 33, id = 0801000a, starting, task 33 has started. + TEST2 : signal task 08010002 to delete, task 0 ending. + TEST2 : signal task 08010003 to delete, task 1 ending. + TEST2 : signal task 08010004 to delete, task 2 ending. + TEST2 : signal task 08010005 to delete, task 3 ending. + TEST2 : signal task 08010010 to delete, task 24 ending. + TEST2 : signal task 08010011 to delete, task 25 ending. + TEST2 : signal task 08010012 to delete, task 26 ending. + TEST2 : signal task 08010013 to delete, task 27 ending. + TEST2 : signal task 08010014 to delete, task 28 ending. + TEST2 : signal task 0801000b to delete, task 9 ending. + TEST2 : signal task 0801000c to delete, task 10 ending. + TEST2 : signal task 0801000d to delete, task 11 ending. + TEST2 : signal task 0801000e to delete, task 12 ending. + TEST2 : signal task 0801000f to delete, task 13 ending. + TEST2 : signal task 08010006 to delete, task 29 ending. + TEST2 : signal task 08010007 to delete, task 30 ending. + TEST2 : signal task 08010008 to delete, task 31 ending. + TEST2 : signal task 08010009 to delete, task 32 ending. + TEST2 : signal task 0801000a to delete, task 33 ending. + TEST2 : signal task 08010015 to delete, task 19 ending. + TEST2 : signal task 08010016 to delete, task 20 ending. + TEST2 : signal task 08010017 to delete, task 21 ending. + TEST2 : signal task 08010018 to delete, task 22 ending. + TEST2 : signal task 08010019 to delete, task 23 ending. + TEST2 : completed + TEST3 : free more than 3 x allocation size, but not the same block, + then free a block + TEST3 : creating task 'aa00', number = 0, id = 08010002, starting, task 0 has started. + TEST3 : creating task 'aa01', number = 1, id = 08010003, starting, task 1 has started. + TEST3 : creating task 'aa02', number = 2, id = 08010004, starting, task 2 has started. + TEST3 : creating task 'aa03', number = 3, id = 08010005, starting, task 3 has started. + TEST3 : creating task 'aa04', number = 4, id = 08010015, starting, task 4 has started. + TEST3 : creating task 'aa05', number = 5, id = 08010016, starting, task 5 has started. + TEST3 : creating task 'aa06', number = 6, id = 08010017, starting, task 6 has started. + TEST3 : creating task 'aa07', number = 7, id = 08010018, starting, task 7 has started. + TEST3 : creating task 'aa08', number = 8, id = 08010019, starting, task 8 has started. + TEST3 : creating task 'aa09', number = 9, id = 08010006, starting, task 9 has started. + TEST3 : creating task 'aa10', number = 10, id = 08010007, starting, task 10 has started. + TEST3 : creating task 'aa11', number = 11, id = 08010008, starting, task 11 has started. + TEST3 : creating task 'aa12', number = 12, id = 08010009, starting, task 12 has started. + TEST3 : creating task 'aa13', number = 13, id = 0801000a, starting, task 13 has started. + TEST3 : creating task 'aa14', number = 14, id = 0801000b, starting, task 14 has started. + TEST3 : creating task 'aa15', number = 15, id = 0801000c, starting, task 15 has started. + TEST3 : creating task 'aa16', number = 16, id = 0801000d, starting, task 16 has started. + TEST3 : creating task 'aa17', number = 17, id = 0801000e, starting, task 17 has started. + TEST3 : creating task 'aa18', number = 18, id = 0801000f, starting, task 18 has started. + TEST3 : creating task 'aa19', number = 19, id = 08010010, starting, task 19 has started. + TEST3 : creating task 'aa20', number = 20, id = 08010011, starting, task 20 has started. + TEST3 : creating task 'aa21', number = 21, id = 08010012, starting, task 21 has started. + TEST3 : creating task 'aa22', number = 22, id = 08010013, starting, task 22 has started. + TEST3 : creating task 'aa23', number = 23, id = 08010014, starting, task 23 has started. + TEST3 : creating task 'aa24', number = 24, id = 0801001a, starting, task 24 has started. + TEST3 : creating task 'aa25', number = 25, id = 0801001b, starting, task 25 has started. + TEST3 : creating task 'aa26', number = 26, id = 0801001c, starting, task 26 has started. + TEST3 : creating task 'aa27', number = 27, id = 0801001d, starting, task 27 has started. + TEST3 : creating task 'aa28', number = 28, id = 0801001e, starting, task 28 has started. + TEST3 : creating task 'aa29', number = 29, id = 0801001f, starting, task 29 has started. + TEST3 : creating task 'aa30', number = 30, id = 08010020, starting, task 30 has started. + TEST3 : creating task 'aa31', number = 31, id = 08010021, starting, task 31 has started. + TEST3 : creating task 'aa32', number = 32, id = 08010022, starting, task 32 has started. + TEST3 : creating task 'aa33', number = 33, id = 08010023, starting, task 33 has started. + TEST3 : creating task 'aa34', number = 34, id = 08010024, starting, task 34 has started. + TEST3 : creating task 'aa35', number = 35, id = 08010025, starting, task 35 has started. + TEST3 : creating task 'aa36', number = 36, id = 08010026, starting, task 36 has started. + TEST3 : creating task 'aa37', number = 37, id = 08010027, starting, task 37 has started. + TEST3 : creating task 'aa38', number = 38, id = 08010028, starting, task 38 has started. + TEST3 : creating task 'aa39', number = 39, id = 08010029, starting, task 39 has started. + TEST3 : creating task 'aa40', number = 40, id = 0801002a, starting, task 40 has started. + TEST3 : creating task 'aa41', number = 41, id = 0801002b, starting, task 41 has started. + TEST3 : creating task 'aa42', number = 42, id = 0801002c, starting, task 42 has started. + TEST3 : creating task 'aa43', number = 43, id = 0801002d, starting, task 43 has started. + TEST3 : creating task 'aa44', number = 44, id = 0801002e, starting, task 44 has started. + TEST3 : creating task 'aa45', number = 45, id = 0801002f, starting, task 45 has started. + TEST3 : creating task 'aa46', number = 46, id = 08010030, starting, task 46 has started. + TEST3 : creating task 'aa47', number = 47, id = 08010031, starting, task 47 has started. + TEST3 : creating task 'aa48', number = 48, id = 08010032, starting, task 48 has started. + TEST3 : creating task 'aa49', number = 49, id = 08010033, starting, task 49 has started. + TEST3 : creating task 'aa50', number = 50, id = 08010034, starting, task 50 has started. + TEST3 : creating task 'aa51', number = 51, id = 08010035, starting, task 51 has started. + TEST3 : creating task 'aa52', number = 52, id = 08010036, starting, task 52 has started. + TEST3 : creating task 'aa53', number = 53, id = 08010037, starting, task 53 has started. + TEST3 : creating task 'aa54', number = 54, id = 08010038, starting, task 54 has started. + TEST3 : creating task 'aa55', number = 55, id = 08010039, starting, task 55 has started. + TEST3 : creating task 'aa56', number = 56, id = 0801003a, starting, task 56 has started. + TEST3 : creating task 'aa57', number = 57, id = 0801003b, starting, task 57 has started. + TEST3 : creating task 'aa58', number = 58, id = 0801003c, starting, task 58 has started. + TEST3 : creating task 'aa59', number = 59, id = 0801003d, starting, task 59 has started. + TEST3 : creating task 'aa60', number = 60, id = 0801003e, starting, task 60 has started. + TEST3 : creating task 'aa61', number = 61, id = 0801003f, starting, task 61 has started. + TEST3 : creating task 'aa62', number = 62, id = 08010040, starting, task 62 has started. + TEST3 : creating task 'aa63', number = 63, id = 08010041, starting, task 63 has started. + TEST3 : creating task 'aa64', number = 64, id = 08010042, starting, task 64 has started. + TEST3 : creating task 'aa65', number = 65, id = 08010043, starting, task 65 has started. + TEST3 : creating task 'aa66', number = 66, id = 08010044, starting, task 66 has started. + TEST3 : creating task 'aa67', number = 67, id = 08010045, starting, task 67 has started. + TEST3 : creating task 'aa68', number = 68, id = 08010046, starting, task 68 has started. + TEST3 : creating task 'aa69', number = 69, id = 08010047, starting, task 69 has started. + TEST3 : creating task 'aa70', number = 70, id = 08010048, starting, task 70 has started. + TEST3 : creating task 'aa71', number = 71, id = 08010049, starting, task 71 has started. + TEST3 : creating task 'aa72', number = 72, id = 0801004a, starting, task 72 has started. + TEST3 : creating task 'aa73', number = 73, id = 0801004b, starting, task 73 has started. + TEST3 : creating task 'aa74', number = 74, id = 0801004c, starting, task 74 has started. + TEST3 : creating task 'aa75', number = 75, id = 0801004d, starting, task 75 has started. + TEST3 : creating task 'aa76', number = 76, id = 0801004e, starting, task 76 has started. + TEST3 : creating task 'aa77', number = 77, id = 0801004f, starting, task 77 has started. + TEST3 : creating task 'aa78', number = 78, id = 08010050, starting, task 78 has started. + TEST3 : creating task 'aa79', number = 79, id = 08010051, starting, task 79 has started. + TEST3 : creating task 'aa80', number = 80, id = 08010052, starting, task 80 has started. + TEST3 : creating task 'aa81', number = 81, id = 08010053, starting, task 81 has started. + TEST3 : creating task 'aa82', number = 82, id = 08010054, starting, task 82 has started. + TEST3 : creating task 'aa83', number = 83, id = 08010055, starting, task 83 has started. + TEST3 : creating task 'aa84', number = 84, id = 08010056, starting, task 84 has started. + TEST3 : creating task 'aa85', number = 85, id = 08010057, starting, task 85 has started. + TEST3 : creating task 'aa86', number = 86, id = 08010058, starting, task 86 has started. + TEST3 : creating task 'aa87', number = 87, id = 08010059, starting, task 87 has started. + TEST3 : creating task 'aa88', number = 88, id = 0801005a, starting, task 88 has started. + TEST3 : creating task 'aa89', number = 89, id = 0801005b, starting, task 89 has started. + TEST3 : creating task 'aa90', number = 90, id = 0801005c, starting, task 90 has started. + TEST3 : creating task 'aa91', number = 91, id = 0801005d, starting, task 91 has started. + TEST3 : creating task 'aa92', number = 92, id = 0801005e, starting, task 92 has started. + TEST3 : creating task 'aa93', number = 93, id = 0801005f, starting, task 93 has started. + TEST3 : creating task 'aa94', number = 94, id = 08010060, starting, task 94 has started. + TEST3 : creating task 'aa95', number = 95, id = 08010061, starting, task 95 has started. + TEST3 : creating task 'aa96', number = 96, id = 08010062, starting, task 96 has started. + TEST3 : creating task 'aa97', number = 97, id = 08010063, starting, task 97 has started. + TEST3 : creating task 'aa98', number = 98, id = 08010064, starting, task 98 has started. + TEST3 : creating task 'aa99', number = 99, id = 08010065, starting, task 99 has started. + TEST3 : creating task 'ab00', number = 100, id = 08010066, starting, task 100 has started. + TEST3 : creating task 'ab01', number = 101, id = 08010067, starting, task 101 has started. + TEST3 : creating task 'ab02', number = 102, id = 08010068, starting, task 102 has started. + TEST3 : creating task 'ab03', number = 103, id = 08010069, starting, task 103 has started. + TEST3 : creating task 'ab04', number = 104, id = 0801006a, starting, task 104 has started. + TEST3 : creating task 'ab05', number = 105, id = 0801006b, starting, task 105 has started. + TEST3 : creating task 'ab06', number = 106, id = 0801006c, starting, task 106 has started. + TEST3 : creating task 'ab07', number = 107, id = 0801006d, starting, task 107 has started. + TEST3 : creating task 'ab08', number = 108, id = 0801006e, starting, task 108 has started. + TEST3 : creating task 'ab09', number = 109, id = 0801006f, starting, task 109 has started. + TEST3 : creating task 'ab10', number = 110, id = 08010070, starting, task 110 has started. + TEST3 : creating task 'ab11', number = 111, id = 08010071, starting, task 111 has started. + TEST3 : creating task 'ab12', number = 112, id = 08010072, starting, task 112 has started. + TEST3 : creating task 'ab13', number = 113, id = 08010073, starting, task 113 has started. + TEST3 : creating task 'ab14', number = 114, id = 08010074, starting, task 114 has started. + TEST3 : creating task 'ab15', number = 115, id = 08010075, starting, task 115 has started. + TEST3 : creating task 'ab16', number = 116, id = 08010076, starting, task 116 has started. + TEST3 : creating task 'ab17', number = 117, id = 08010077, starting, task 117 has started. + TEST3 : creating task 'ab18', number = 118, id = 08010078, starting, task 118 has started. + TEST3 : creating task 'ab19', number = 119, id = 08010079, starting, task 119 has started. + TEST3 : creating task 'ab20', number = 120, id = 0801007a, starting, task 120 has started. + TEST3 : creating task 'ab21', failure, unsatisfied. + TEST3 : remove, signal task 08010015, task 4 ending. + TEST3 : remove, signal task 08010016, task 5 ending. + TEST3 : remove, signal task 08010017, task 6 ending. + TEST3 : remove, signal task 08010006, task 9 ending. + TEST3 : remove, signal task 08010007, task 10 ending. + TEST3 : remove, signal task 08010008, task 11 ending. + TEST3 : remove, signal task 0801000b, task 14 ending. + TEST3 : remove, signal task 0801000c, task 15 ending. + TEST3 : remove, signal task 0801000d, task 16 ending. + TEST3 : remove, signal task 08010010, task 19 ending. + TEST3 : remove, signal task 08010011, task 20 ending. + TEST3 : remove, signal task 08010012, task 21 ending. + TEST3 : remove, signal task 08010018, task 7 ending. + TEST3 : remove, signal task 08010019, task 8 ending. + TEST3 : signal task 08010002 to delete, task 0 ending. + TEST3 : signal task 08010003 to delete, task 1 ending. + TEST3 : signal task 08010004 to delete, task 2 ending. + TEST3 : signal task 08010005 to delete, task 3 ending. + TEST3 : signal task 08010009 to delete, task 12 ending. + TEST3 : signal task 0801000a to delete, task 13 ending. + TEST3 : signal task 0801000e to delete, task 17 ending. + TEST3 : signal task 0801000f to delete, task 18 ending. + TEST3 : signal task 08010013 to delete, task 22 ending. + TEST3 : signal task 08010014 to delete, task 23 ending. + TEST3 : signal task 0801001a to delete, task 24 ending. + TEST3 : signal task 0801001b to delete, task 25 ending. + TEST3 : signal task 0801001c to delete, task 26 ending. + TEST3 : signal task 0801001d to delete, task 27 ending. + TEST3 : signal task 0801001e to delete, task 28 ending. + TEST3 : signal task 0801001f to delete, task 29 ending. + TEST3 : signal task 08010020 to delete, task 30 ending. + TEST3 : signal task 08010021 to delete, task 31 ending. + TEST3 : signal task 08010022 to delete, task 32 ending. + TEST3 : signal task 08010023 to delete, task 33 ending. + TEST3 : signal task 08010024 to delete, task 34 ending. + TEST3 : signal task 08010025 to delete, task 35 ending. + TEST3 : signal task 08010026 to delete, task 36 ending. + TEST3 : signal task 08010027 to delete, task 37 ending. + TEST3 : signal task 08010028 to delete, task 38 ending. + TEST3 : signal task 08010029 to delete, task 39 ending. + TEST3 : signal task 0801002a to delete, task 40 ending. + TEST3 : signal task 0801002b to delete, task 41 ending. + TEST3 : signal task 0801002c to delete, task 42 ending. + TEST3 : signal task 0801002d to delete, task 43 ending. + TEST3 : signal task 0801002e to delete, task 44 ending. + TEST3 : signal task 0801002f to delete, task 45 ending. + TEST3 : signal task 08010030 to delete, task 46 ending. + TEST3 : signal task 08010031 to delete, task 47 ending. + TEST3 : signal task 08010032 to delete, task 48 ending. + TEST3 : signal task 08010033 to delete, task 49 ending. + TEST3 : signal task 08010034 to delete, task 50 ending. + TEST3 : signal task 08010035 to delete, task 51 ending. + TEST3 : signal task 08010036 to delete, task 52 ending. + TEST3 : signal task 08010037 to delete, task 53 ending. + TEST3 : signal task 08010038 to delete, task 54 ending. + TEST3 : signal task 08010039 to delete, task 55 ending. + TEST3 : signal task 0801003a to delete, task 56 ending. + TEST3 : signal task 0801003b to delete, task 57 ending. + TEST3 : signal task 0801003c to delete, task 58 ending. + TEST3 : signal task 0801003d to delete, task 59 ending. + TEST3 : signal task 0801003e to delete, task 60 ending. + TEST3 : signal task 0801003f to delete, task 61 ending. + TEST3 : signal task 08010040 to delete, task 62 ending. + TEST3 : signal task 08010041 to delete, task 63 ending. + TEST3 : signal task 08010042 to delete, task 64 ending. + TEST3 : signal task 08010043 to delete, task 65 ending. + TEST3 : signal task 08010044 to delete, task 66 ending. + TEST3 : signal task 08010045 to delete, task 67 ending. + TEST3 : signal task 08010046 to delete, task 68 ending. + TEST3 : signal task 08010047 to delete, task 69 ending. + TEST3 : signal task 08010048 to delete, task 70 ending. + TEST3 : signal task 08010049 to delete, task 71 ending. + TEST3 : signal task 0801004a to delete, task 72 ending. + TEST3 : signal task 0801004b to delete, task 73 ending. + TEST3 : signal task 0801004c to delete, task 74 ending. + TEST3 : signal task 0801004d to delete, task 75 ending. + TEST3 : signal task 0801004e to delete, task 76 ending. + TEST3 : signal task 0801004f to delete, task 77 ending. + TEST3 : signal task 08010050 to delete, task 78 ending. + TEST3 : signal task 08010051 to delete, task 79 ending. + TEST3 : signal task 08010052 to delete, task 80 ending. + TEST3 : signal task 08010053 to delete, task 81 ending. + TEST3 : signal task 08010054 to delete, task 82 ending. + TEST3 : signal task 08010055 to delete, task 83 ending. + TEST3 : signal task 08010056 to delete, task 84 ending. + TEST3 : signal task 08010057 to delete, task 85 ending. + TEST3 : signal task 08010058 to delete, task 86 ending. + TEST3 : signal task 08010059 to delete, task 87 ending. + TEST3 : signal task 0801005a to delete, task 88 ending. + TEST3 : signal task 0801005b to delete, task 89 ending. + TEST3 : signal task 0801005c to delete, task 90 ending. + TEST3 : signal task 0801005d to delete, task 91 ending. + TEST3 : signal task 0801005e to delete, task 92 ending. + TEST3 : signal task 0801005f to delete, task 93 ending. + TEST3 : signal task 08010060 to delete, task 94 ending. + TEST3 : signal task 08010061 to delete, task 95 ending. + TEST3 : signal task 08010062 to delete, task 96 ending. + TEST3 : signal task 08010063 to delete, task 97 ending. + TEST3 : signal task 08010064 to delete, task 98 ending. + TEST3 : signal task 08010065 to delete, task 99 ending. + TEST3 : signal task 08010066 to delete, task 100 ending. + TEST3 : signal task 08010067 to delete, task 101 ending. + TEST3 : signal task 08010068 to delete, task 102 ending. + TEST3 : signal task 08010069 to delete, task 103 ending. + TEST3 : signal task 0801006a to delete, task 104 ending. + TEST3 : signal task 0801006b to delete, task 105 ending. + TEST3 : signal task 0801006c to delete, task 106 ending. + TEST3 : signal task 0801006d to delete, task 107 ending. + TEST3 : signal task 0801006e to delete, task 108 ending. + TEST3 : signal task 0801006f to delete, task 109 ending. + TEST3 : signal task 08010070 to delete, task 110 ending. + TEST3 : signal task 08010071 to delete, task 111 ending. + TEST3 : signal task 08010072 to delete, task 112 ending. + TEST3 : signal task 08010073 to delete, task 113 ending. + TEST3 : signal task 08010074 to delete, task 114 ending. + TEST3 : signal task 08010075 to delete, task 115 ending. + TEST3 : signal task 08010076 to delete, task 116 ending. + TEST3 : signal task 08010077 to delete, task 117 ending. + TEST3 : signal task 08010078 to delete, task 118 ending. + TEST3 : signal task 08010079 to delete, task 119 ending. + TEST3 : signal task 0801007a to delete, task 120 ending. + TEST3 : completed + +*** END OF UNLIMITED TASK TEST *** + +NOTE: The failures are expected. This is the limiting factor, memory in the + work-space. +NOTE: The number of tasks may vary due to the size of the work-space. -- cgit v1.2.3