source: rtems/cpukit/score/src/objectextendinformation.c @ 878487b0

5
Last change on this file since 878487b0 was 878487b0, checked in by Sebastian Huber <sebastian.huber@…>, on 11/05/18 at 08:53:04

score: Optimize Objects_Information

Reduce structure internal padding. Group members used by _Objects_Get()
together. Reduce size of some members.

Format and simplify _Objects_Extend_information().

  • 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->allocation_size;
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->allocation_size;
84    }
85  }
86  index_end = index_base + information->allocation_size;
87
88  maximum = (uint32_t) information->maximum + information->allocation_size;
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->allocation_size * information->size;
104  if ( information->auto_extend ) {
105    new_object_block = _Workspace_Allocate( object_block_size );
106    if ( !new_object_block )
107      return;
108  } else {
109    new_object_block = _Workspace_Allocate_or_fatal_error( object_block_size );
110  }
111
112  /*
113   *  Do we need to grow the tables?
114   */
115  if ( do_extend ) {
116    ISR_lock_Context  lock_context;
117    Objects_Control **object_blocks;
118    Objects_Control **local_table;
119    Objects_Maximum  *inactive_per_block;
120    void             *old_tables;
121    size_t            table_size;
122    uintptr_t         object_blocks_size;
123    uintptr_t         local_table_size;
124
125    /*
126     *  Growing the tables means allocating a new area, doing a copy and
127     *  updating the information table.
128     *
129     *  If the maximum is minimum we do not have a table to copy. First
130     *  time through.
131     *
132     *  The allocation has:
133     *
134     *      Objects_Control *object_blocks[ block_count ];
135     *      Objects_Control *local_table[ maximum ];
136     *      Objects_Maximum  inactive_count[ block_count ];
137     *
138     *  This is the order in memory. Watch changing the order. See the memcpy
139     *  below.
140     */
141
142    /*
143     *  Up the block count and maximum.
144     */
145    block_count++;
146
147    /*
148     *  Allocate the tables and break it up.
149     */
150    object_blocks_size = block_count * sizeof( *object_blocks );
151    local_table_size = ( maximum + minimum_index ) * sizeof( *local_table );
152    table_size = object_blocks_size
153      + local_table_size
154      + block_count * sizeof( *inactive_per_block );
155    if ( information->auto_extend ) {
156      object_blocks = _Workspace_Allocate( table_size );
157      if ( !object_blocks ) {
158        _Workspace_Free( new_object_block );
159        return;
160      }
161    } else {
162      object_blocks = _Workspace_Allocate_or_fatal_error( table_size );
163    }
164
165    /*
166     *  Break the block into the various sections.
167     */
168    local_table = _Addresses_Add_offset(
169      object_blocks,
170      object_blocks_size
171    );
172    inactive_per_block = _Addresses_Add_offset(
173      local_table,
174      local_table_size
175    );
176
177    /*
178     *  Take the block count down. Saves all the (block_count - 1)
179     *  in the copies.
180     */
181    block_count--;
182
183    if ( information->maximum > minimum_index ) {
184      /*
185       *  Copy each section of the table over. This has to be performed as
186       *  separate parts as size of each block has changed.
187       */
188      memcpy(
189        object_blocks,
190        information->object_blocks,
191        block_count * sizeof( *object_blocks )
192      );
193      memcpy(
194        inactive_per_block,
195        information->inactive_per_block,
196        block_count * sizeof( *inactive_per_block )
197      );
198      memcpy(
199        local_table,
200        information->local_table,
201        ( information->maximum + minimum_index ) * sizeof( *local_table )
202      );
203    } else {
204      /*
205       *  Deal with the special case of the 0 to minimum_index
206       */
207      for ( index = 0; index < minimum_index; index++ ) {
208        local_table[ index ] = NULL;
209      }
210    }
211
212    /*
213     *  Initialise the new entries in the table.
214     */
215    for ( index = index_base ; index < index_end ; ++index ) {
216      local_table[ index ] = NULL;
217    }
218
219    /* FIXME: https://devel.rtems.org/ticket/2280 */
220    _ISR_lock_ISR_disable( &lock_context );
221
222    old_tables = information->object_blocks;
223
224    information->object_blocks = object_blocks;
225    information->inactive_per_block = inactive_per_block;
226    information->local_table = local_table;
227    information->maximum = (Objects_Maximum) maximum;
228    information->maximum_id = _Objects_Build_id(
229      information->the_api,
230      information->the_class,
231      _Objects_Local_node,
232      information->maximum
233    );
234
235    _ISR_lock_ISR_enable( &lock_context );
236
237    _Workspace_Free( old_tables );
238
239    block_count++;
240  }
241
242  /*
243   *  Assign the new object block to the object block table.
244   */
245  information->object_blocks[ block ] = new_object_block;
246  information->inactive_per_block[ block ] = information->allocation_size;
247  information->inactive += information->allocation_size;
248
249  /*
250   *  Append to inactive chain.
251   */
252  the_object = new_object_block;
253  for ( index = index_base ; index < index_end ; ++index ) {
254    the_object->id = _Objects_Build_id(
255      information->the_api,
256      information->the_class,
257      _Objects_Local_node,
258      index
259    );
260
261    _Chain_Initialize_node( &the_object->Node );
262    _Chain_Append_unprotected( &information->Inactive, &the_object->Node );
263
264    the_object = _Addresses_Add_offset( the_object, information->size );
265  }
266}
Note: See TracBrowser for help on using the repository browser.