source: rtems/cpukit/score/src/objectextendinformation.c @ 684e243d

4.104.115
Last change on this file since 684e243d was 684e243d, checked in by Joel Sherrill <joel.sherrill@…>, on 08/06/09 at 20:39:27

Revert.

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