source: rtems/cpukit/score/src/objectextendinformation.c @ 877048c

5
Last change on this file since 877048c was f70079c, checked in by Sebastian Huber <sebastian.huber@…>, on 11/25/18 at 19:26:02

score: Remove Objects_Information::the_api

Remove Objects_Information::the_class. This information is already
contained in Objects_Information::maximum_id.

Update #3621.

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