source: rtems/cpukit/score/src/objectextendinformation.c @ 21275b58

Last change on this file since 21275b58 was 21275b58, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 22, 2018 at 6:14:51 PM

score: Static Objects_Information initialization

Statically allocate the objects information together with the initial
set of objects either via <rtems/confdefs.h>. Provide default object
informations with zero objects via librtemscpu.a. This greatly
simplifies the workspace size estimate. RTEMS applications which do not
use the unlimited objects option are easier to debug since all objects
reside now in statically allocated objects of the right types.

Close #3621.

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