File indexing completed on 2025-05-11 08:24:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include <rtems/score/objectimpl.h>
0043 #include <rtems/score/address.h>
0044 #include <rtems/score/assert.h>
0045 #include <rtems/score/chainimpl.h>
0046 #include <rtems/score/isrlevel.h>
0047 #include <rtems/score/sysstate.h>
0048 #include <rtems/score/wkspace.h>
0049
0050 #include <string.h> /* for memcpy() */
0051
0052 Objects_Maximum _Objects_Extend_information(
0053 Objects_Information *information
0054 )
0055 {
0056 Objects_Control *the_object;
0057 uint32_t block_count;
0058 uint32_t block;
0059 uint32_t index_base;
0060 uint32_t index_end;
0061 uint32_t index;
0062 uint32_t extend_count;
0063 Objects_Maximum old_maximum;
0064 uint32_t new_maximum;
0065 size_t object_block_size;
0066 Objects_Control *new_object_block;
0067 bool do_extend;
0068 Objects_Id api_class_and_node;
0069
0070 _Assert(
0071 _Objects_Allocator_is_owner()
0072 || !_System_state_Is_up( _System_state_Get() )
0073 );
0074 _Assert( _Objects_Is_auto_extend( information ) );
0075
0076 extend_count = _Objects_Extend_size( information );
0077 old_maximum = _Objects_Get_maximum_index( information );
0078 new_maximum = (uint32_t) old_maximum + extend_count;
0079 api_class_and_node = information->maximum_id & ~OBJECTS_INDEX_MASK;
0080
0081
0082
0083
0084
0085 do_extend = true;
0086 index_base = extend_count;
0087 block = 1;
0088
0089 if ( information->object_blocks == NULL ) {
0090 block_count = 1;
0091 } else {
0092 block_count = old_maximum / extend_count;
0093
0094 for ( ; block < block_count; block++ ) {
0095 if ( information->object_blocks[ block ] == NULL ) {
0096 do_extend = false;
0097 break;
0098 } else
0099 index_base += extend_count;
0100 }
0101 }
0102
0103 index_end = index_base + extend_count;
0104
0105
0106
0107
0108
0109
0110 if ( new_maximum > OBJECTS_ID_FINAL_INDEX ) {
0111 return 0;
0112 }
0113
0114
0115
0116
0117
0118 object_block_size = extend_count * information->object_size;
0119 new_object_block = _Workspace_Allocate( object_block_size );
0120 if ( new_object_block == NULL ) {
0121 return 0;
0122 }
0123
0124
0125
0126
0127 if ( do_extend ) {
0128 ISR_lock_Context lock_context;
0129 Objects_Control **object_blocks;
0130 Objects_Control **local_table;
0131 Objects_Maximum *inactive_per_block;
0132 void *old_tables;
0133 size_t table_size;
0134 uintptr_t object_blocks_size;
0135 uintptr_t local_table_size;
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 block_count++;
0158
0159
0160
0161
0162 object_blocks_size = block_count * sizeof( *object_blocks );
0163 local_table_size = new_maximum * sizeof( *local_table );
0164 table_size = object_blocks_size
0165 + local_table_size
0166 + block_count * sizeof( *inactive_per_block );
0167 object_blocks = _Workspace_Allocate( table_size );
0168 if ( object_blocks == NULL ) {
0169 _Workspace_Free( new_object_block );
0170 return 0;
0171 }
0172
0173
0174
0175
0176 local_table = _Addresses_Add_offset(
0177 object_blocks,
0178 object_blocks_size
0179 );
0180 inactive_per_block = _Addresses_Add_offset(
0181 local_table,
0182 local_table_size
0183 );
0184
0185
0186
0187
0188
0189 block_count--;
0190
0191 if ( old_maximum > extend_count ) {
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 _Assert(information->object_blocks != NULL);
0202
0203
0204
0205
0206
0207 memcpy(
0208 object_blocks,
0209 information->object_blocks,
0210 block_count * sizeof( *object_blocks )
0211 );
0212 memcpy(
0213 inactive_per_block,
0214 information->inactive_per_block,
0215 block_count * sizeof( *inactive_per_block )
0216 );
0217 } else {
0218 object_blocks[ 0 ] = NULL;
0219 inactive_per_block[ 0 ] = 0;
0220 }
0221
0222 memcpy(
0223 local_table,
0224 information->local_table,
0225 old_maximum * sizeof( *local_table )
0226 );
0227
0228
0229
0230
0231 for ( index = index_base ; index < index_end ; ++index ) {
0232 local_table[ index ] = NULL;
0233 }
0234
0235
0236 _ISR_lock_ISR_disable( &lock_context );
0237
0238 old_tables = information->object_blocks;
0239
0240 information->object_blocks = object_blocks;
0241 information->inactive_per_block = inactive_per_block;
0242 information->local_table = local_table;
0243 information->maximum_id = api_class_and_node
0244 | (new_maximum << OBJECTS_INDEX_START_BIT);
0245
0246 _ISR_lock_ISR_enable( &lock_context );
0247
0248 _Workspace_Free( old_tables );
0249
0250 block_count++;
0251 }
0252
0253
0254
0255
0256 information->object_blocks[ block ] = new_object_block;
0257 information->inactive_per_block[ block ] = information->objects_per_block;
0258 information->inactive += information->objects_per_block;
0259
0260
0261
0262
0263 the_object = new_object_block;
0264 for ( index = index_base ; index < index_end ; ++index ) {
0265 the_object->id = api_class_and_node
0266 | ( ( index + OBJECTS_INDEX_MINIMUM ) << OBJECTS_INDEX_START_BIT );
0267
0268 _Chain_Initialize_node( &the_object->Node );
0269 _Chain_Append_unprotected( &information->Inactive, &the_object->Node );
0270
0271 the_object = _Addresses_Add_offset( the_object, information->object_size );
0272 }
0273
0274 return block;
0275 }