source: rtems/cpukit/score/src/objectextendinformation.c @ 8b0e752f

5
Last change on this file since 8b0e752f was 8b0e752f, checked in by Sebastian Huber <sebastian.huber@…>, on 12/10/18 at 12:44:53

score: Remove Objects_Information::auto_extend

Use Objects_Information::objects_per_block to provide this information.
Add and use _Objects_Is_auto_extend().

Update #3621.

  • Property mode set to 100644
File size: 6.9 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          index;
52  Objects_Maximum   extend_count;
53  Objects_Maximum   old_maximum;
54  uint32_t          new_maximum;
55  size_t            object_block_size;
56  Objects_Control  *new_object_block;
57  bool              do_extend;
58  Objects_Id        api_class_and_node;
59
60  _Assert(
61    _Objects_Allocator_is_owner()
62      || !_System_state_Is_up( _System_state_Get() )
63  );
64
65  api_class_and_node = information->maximum_id & ~OBJECTS_INDEX_MASK;
66
67  /*
68   *  Search for a free block of indexes. If we do NOT need to allocate or
69   *  extend the block table, then we will change do_extend.
70   */
71  do_extend     = true;
72  index_base    = 0;
73  block         = 0;
74
75  if ( information->object_blocks == NULL ) {
76    extend_count = _Objects_Get_maximum_index( information );
77    old_maximum = 0;
78    block_count = 0;
79  } else {
80    extend_count = information->objects_per_block;
81    old_maximum = _Objects_Get_maximum_index( information );
82    block_count = old_maximum / extend_count;
83
84    for ( ; block < block_count; block++ ) {
85      if ( information->object_blocks[ block ] == NULL ) {
86        do_extend = false;
87        break;
88      } else
89        index_base += extend_count;
90    }
91  }
92
93  new_maximum = (uint32_t) old_maximum + extend_count;
94  index_end = index_base + extend_count;
95
96  /*
97   *  We need to limit the number of objects to the maximum number
98   *  representable in the index portion of the object Id.  In the
99   *  case of 16-bit Ids, this is only 256 object instances.
100   */
101  if ( new_maximum > OBJECTS_ID_FINAL_INDEX ) {
102    return;
103  }
104
105  /*
106   * Allocate the name table, and the objects and if it fails either return or
107   * generate a fatal error depending on auto-extending being active.
108   */
109  object_block_size = extend_count * information->object_size;
110  if ( _Objects_Is_auto_extend( information ) ) {
111    new_object_block = _Workspace_Allocate( object_block_size );
112    if ( !new_object_block )
113      return;
114  } else {
115    new_object_block = _Workspace_Allocate_or_fatal_error( object_block_size );
116  }
117
118  /*
119   *  Do we need to grow the tables?
120   */
121  if ( do_extend ) {
122    ISR_lock_Context  lock_context;
123    Objects_Control **object_blocks;
124    Objects_Control **local_table;
125    Objects_Maximum  *inactive_per_block;
126    void             *old_tables;
127    size_t            table_size;
128    uintptr_t         object_blocks_size;
129    uintptr_t         local_table_size;
130
131    /*
132     *  Growing the tables means allocating a new area, doing a copy and
133     *  updating the information table.
134     *
135     *  If the maximum is minimum we do not have a table to copy. First
136     *  time through.
137     *
138     *  The allocation has:
139     *
140     *      Objects_Control *object_blocks[ block_count ];
141     *      Objects_Control *local_table[ maximum ];
142     *      Objects_Maximum  inactive_count[ block_count ];
143     *
144     *  This is the order in memory. Watch changing the order. See the memcpy
145     *  below.
146     */
147
148    /*
149     *  Up the block count and maximum.
150     */
151    block_count++;
152
153    /*
154     *  Allocate the tables and break it up.
155     */
156    object_blocks_size = block_count * sizeof( *object_blocks );
157    local_table_size =  new_maximum * sizeof( *local_table );
158    table_size = object_blocks_size
159      + local_table_size
160      + block_count * sizeof( *inactive_per_block );
161    if ( _Objects_Is_auto_extend( information ) ) {
162      object_blocks = _Workspace_Allocate( table_size );
163      if ( !object_blocks ) {
164        _Workspace_Free( new_object_block );
165        return;
166      }
167    } else {
168      object_blocks = _Workspace_Allocate_or_fatal_error( table_size );
169    }
170
171    /*
172     *  Break the block into the various sections.
173     */
174    local_table = _Addresses_Add_offset(
175      object_blocks,
176      object_blocks_size
177    );
178    inactive_per_block = _Addresses_Add_offset(
179      local_table,
180      local_table_size
181    );
182
183    /*
184     *  Take the block count down. Saves all the (block_count - 1)
185     *  in the copies.
186     */
187    block_count--;
188
189    if ( old_maximum > 0 ) {
190      /*
191       *  Copy each section of the table over. This has to be performed as
192       *  separate parts as size of each block has changed.
193       */
194      memcpy(
195        object_blocks,
196        information->object_blocks,
197        block_count * sizeof( *object_blocks )
198      );
199      memcpy(
200        inactive_per_block,
201        information->inactive_per_block,
202        block_count * sizeof( *inactive_per_block )
203      );
204      memcpy(
205        local_table,
206        information->local_table,
207        old_maximum * sizeof( *local_table )
208      );
209    }
210
211    /*
212     *  Initialise the new entries in the table.
213     */
214    for ( index = index_base ; index < index_end ; ++index ) {
215      local_table[ index ] = NULL;
216    }
217
218    /* FIXME: https://devel.rtems.org/ticket/2280 */
219    _ISR_lock_ISR_disable( &lock_context );
220
221    old_tables = information->object_blocks;
222
223    information->object_blocks = object_blocks;
224    information->inactive_per_block = inactive_per_block;
225    information->local_table = local_table;
226    information->maximum_id = api_class_and_node
227      | (new_maximum << OBJECTS_INDEX_START_BIT);
228
229    _ISR_lock_ISR_enable( &lock_context );
230
231    _Workspace_Free( old_tables );
232
233    block_count++;
234  }
235
236  /*
237   *  Assign the new object block to the object block table.
238   */
239  information->object_blocks[ block ] = new_object_block;
240  information->inactive_per_block[ block ] = information->objects_per_block;
241  information->inactive += information->objects_per_block;
242
243  /*
244   *  Append to inactive chain.
245   */
246  the_object = new_object_block;
247  for ( index = index_base ; index < index_end ; ++index ) {
248    the_object->id = api_class_and_node
249      | ( ( index + OBJECTS_INDEX_MINIMUM ) << OBJECTS_INDEX_START_BIT );
250
251    _Chain_Initialize_node( &the_object->Node );
252    _Chain_Append_unprotected( &information->Inactive, &the_object->Node );
253
254    the_object = _Addresses_Add_offset( the_object, information->object_size );
255  }
256}
Note: See TracBrowser for help on using the repository browser.