source: rtems/cpukit/score/src/objectextendinformation.c @ 359a3a3

5
Last change on this file since 359a3a3 was 359a3a3, checked in by Sebastian Huber <sebastian.huber@…>, on 11/22/18 at 05:38:42

score: Rename Objects_Information::allocation_size

Rename Objects_Information::allocation_size in
Objects_Information::objects_per_block. Adjust integer types in
_Objects_Shrink_information() and _Objects_Free().

Update #3621.

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/**
2 * @file
3 *
4 * @brief Extend Set of Objects
5 * @ingroup ScoreObject
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/objectimpl.h>
22#include <rtems/score/address.h>
23#include <rtems/score/assert.h>
24#include <rtems/score/chainimpl.h>
25#include <rtems/score/isrlevel.h>
26#include <rtems/score/sysstate.h>
27#include <rtems/score/wkspace.h>
28
29#include <string.h>  /* for memcpy() */
30
31/*
32 *  _Objects_Extend_information
33 *
34 *  This routine extends all object information related data structures.
35 *
36 *  Input parameters:
37 *    information     - object information table
38 *
39 *  Output parameters:  NONE
40 */
41
42void _Objects_Extend_information(
43  Objects_Information *information
44)
45{
46  Objects_Control  *the_object;
47  uint32_t          block_count;
48  uint32_t          block;
49  uint32_t          index_base;
50  uint32_t          index_end;
51  uint32_t          minimum_index;
52  uint32_t          index;
53  uint32_t          maximum;
54  size_t            object_block_size;
55  Objects_Control  *new_object_block;
56  bool              do_extend;
57
58  _Assert(
59    _Objects_Allocator_is_owner()
60      || !_System_state_Is_up( _System_state_Get() )
61  );
62
63  /*
64   *  Search for a free block of indexes. If we do NOT need to allocate or
65   *  extend the block table, then we will change do_extend.
66   */
67  do_extend     = true;
68  minimum_index = _Objects_Get_index( information->minimum_id );
69  index_base    = minimum_index;
70  block         = 0;
71
72  /* if ( information->maximum < minimum_index ) */
73  if ( information->object_blocks == NULL )
74    block_count = 0;
75  else {
76    block_count = information->maximum / information->objects_per_block;
77
78    for ( ; block < block_count; block++ ) {
79      if ( information->object_blocks[ block ] == NULL ) {
80        do_extend = false;
81        break;
82      } else
83        index_base += information->objects_per_block;
84    }
85  }
86  index_end = index_base + information->objects_per_block;
87
88  maximum = (uint32_t) information->maximum + information->objects_per_block;
89
90  /*
91   *  We need to limit the number of objects to the maximum number
92   *  representable in the index portion of the object Id.  In the
93   *  case of 16-bit Ids, this is only 256 object instances.
94   */
95  if ( maximum > OBJECTS_ID_FINAL_INDEX ) {
96    return;
97  }
98
99  /*
100   * Allocate the name table, and the objects and if it fails either return or
101   * generate a fatal error depending on auto-extending being active.
102   */
103  object_block_size = information->objects_per_block
104    * information->object_size;
105  if ( information->auto_extend ) {
106    new_object_block = _Workspace_Allocate( object_block_size );
107    if ( !new_object_block )
108      return;
109  } else {
110    new_object_block = _Workspace_Allocate_or_fatal_error( object_block_size );
111  }
112
113  /*
114   *  Do we need to grow the tables?
115   */
116  if ( do_extend ) {
117    ISR_lock_Context  lock_context;
118    Objects_Control **object_blocks;
119    Objects_Control **local_table;
120    Objects_Maximum  *inactive_per_block;
121    void             *old_tables;
122    size_t            table_size;
123    uintptr_t         object_blocks_size;
124    uintptr_t         local_table_size;
125
126    /*
127     *  Growing the tables means allocating a new area, doing a copy and
128     *  updating the information table.
129     *
130     *  If the maximum is minimum we do not have a table to copy. First
131     *  time through.
132     *
133     *  The allocation has:
134     *
135     *      Objects_Control *object_blocks[ block_count ];
136     *      Objects_Control *local_table[ maximum ];
137     *      Objects_Maximum  inactive_count[ block_count ];
138     *
139     *  This is the order in memory. Watch changing the order. See the memcpy
140     *  below.
141     */
142
143    /*
144     *  Up the block count and maximum.
145     */
146    block_count++;
147
148    /*
149     *  Allocate the tables and break it up.
150     */
151    object_blocks_size = block_count * sizeof( *object_blocks );
152    local_table_size = ( maximum + minimum_index ) * sizeof( *local_table );
153    table_size = object_blocks_size
154      + local_table_size
155      + block_count * sizeof( *inactive_per_block );
156    if ( information->auto_extend ) {
157      object_blocks = _Workspace_Allocate( table_size );
158      if ( !object_blocks ) {
159        _Workspace_Free( new_object_block );
160        return;
161      }
162    } else {
163      object_blocks = _Workspace_Allocate_or_fatal_error( table_size );
164    }
165
166    /*
167     *  Break the block into the various sections.
168     */
169    local_table = _Addresses_Add_offset(
170      object_blocks,
171      object_blocks_size
172    );
173    inactive_per_block = _Addresses_Add_offset(
174      local_table,
175      local_table_size
176    );
177
178    /*
179     *  Take the block count down. Saves all the (block_count - 1)
180     *  in the copies.
181     */
182    block_count--;
183
184    if ( information->maximum > minimum_index ) {
185      /*
186       *  Copy each section of the table over. This has to be performed as
187       *  separate parts as size of each block has changed.
188       */
189      memcpy(
190        object_blocks,
191        information->object_blocks,
192        block_count * sizeof( *object_blocks )
193      );
194      memcpy(
195        inactive_per_block,
196        information->inactive_per_block,
197        block_count * sizeof( *inactive_per_block )
198      );
199      memcpy(
200        local_table,
201        information->local_table,
202        ( information->maximum + minimum_index ) * sizeof( *local_table )
203      );
204    } else {
205      /*
206       *  Deal with the special case of the 0 to minimum_index
207       */
208      for ( index = 0; index < minimum_index; index++ ) {
209        local_table[ index ] = NULL;
210      }
211    }
212
213    /*
214     *  Initialise the new entries in the table.
215     */
216    for ( index = index_base ; index < index_end ; ++index ) {
217      local_table[ index ] = NULL;
218    }
219
220    /* FIXME: https://devel.rtems.org/ticket/2280 */
221    _ISR_lock_ISR_disable( &lock_context );
222
223    old_tables = information->object_blocks;
224
225    information->object_blocks = object_blocks;
226    information->inactive_per_block = inactive_per_block;
227    information->local_table = local_table;
228    information->maximum = (Objects_Maximum) maximum;
229    information->maximum_id = _Objects_Build_id(
230      information->the_api,
231      information->the_class,
232      _Objects_Local_node,
233      information->maximum
234    );
235
236    _ISR_lock_ISR_enable( &lock_context );
237
238    _Workspace_Free( old_tables );
239
240    block_count++;
241  }
242
243  /*
244   *  Assign the new object block to the object block table.
245   */
246  information->object_blocks[ block ] = new_object_block;
247  information->inactive_per_block[ block ] = information->objects_per_block;
248  information->inactive += information->objects_per_block;
249
250  /*
251   *  Append to inactive chain.
252   */
253  the_object = new_object_block;
254  for ( index = index_base ; index < index_end ; ++index ) {
255    the_object->id = _Objects_Build_id(
256      information->the_api,
257      information->the_class,
258      _Objects_Local_node,
259      index
260    );
261
262    _Chain_Initialize_node( &the_object->Node );
263    _Chain_Append_unprotected( &information->Inactive, &the_object->Node );
264
265    the_object = _Addresses_Add_offset( the_object, information->object_size );
266  }
267}
Note: See TracBrowser for help on using the repository browser.