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

4.104.11
Last change on this file since f32c036 was f32c036, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 7, 2009 at 12:19:04 AM

2009-08-06 Joel Sherrill <joel.sherrill@…>

  • score/src/objectextendinformation.c: Minor rework to eliminate uncovered ranges introduced by Chris' patch.
  • Property mode set to 100644
File size: 7.0 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  uint32_t          maximum;
57  size_t            block_size;
58  void             *new_object_block;
59
60  /*
61   *  Search for a free block of indexes. The block variable ends up set
62   *  to block_count + 1 if the table needs to be extended.
63   */
64
65  minimum_index = _Objects_Get_index( information->minimum_id );
66  index_base    = minimum_index;
67  block         = 0;
68
69  if ( information->maximum < minimum_index )
70    block_count = 0;
71  else {
72    block_count = information->maximum / information->allocation_size;
73
74    for ( ; block < block_count; block++ ) {
75      if ( information->object_blocks[ block ] == NULL )
76        break;
77      else
78        index_base += information->allocation_size;
79    }
80  }
81
82  maximum = (uint32_t) information->maximum + information->allocation_size;
83
84  /*
85   *  We need to limit the number of objects to the maximum number
86   *  representable in the index portion of the object Id.  In the
87   *  case of 16-bit Ids, this is only 256 object instances.
88   */
89  if ( maximum > OBJECTS_ID_FINAL_INDEX ) {
90    return;
91  }
92
93  /*
94   * Allocate the name table, and the objects and if it fails either return or
95   * generate a fatal error depending on auto-extending being active.
96   */
97 
98  block_size = information->allocation_size * information->size;
99  if ( information->auto_extend ) {
100    new_object_block = _Workspace_Allocate( block_size );
101    if ( !new_object_block )
102      return;
103  } else {
104    new_object_block = _Workspace_Allocate_or_fatal_error( block_size );
105  }
106 
107  /*
108   *  If the index_base is the maximum we need to grow the tables.
109   */
110
111  if (index_base >= information->maximum ) {
112    ISR_Level         level;
113    void            **object_blocks;
114    uint32_t         *inactive_per_block;
115    Objects_Control **local_table;
116    void             *old_tables;
117    size_t            block_size;
118
119    /*
120     *  Growing the tables means allocating a new area, doing a copy and
121     *  updating the information table.
122     *
123     *  If the maximum is minimum we do not have a table to copy. First
124     *  time through.
125     *
126     *  The allocation has :
127     *
128     *      void            *objects[block_count];
129     *      uint32_t         inactive_count[block_count];
130     *      Objects_Control *local_table[maximum];
131     *
132     *  This is the order in memory. Watch changing the order. See the memcpy
133     *  below.
134     */
135
136    /*
137     *  Up the block count and maximum
138     */
139
140    block_count++;
141
142    /*
143     *  Allocate the tables and break it up.
144     */
145
146    block_size = block_count *
147           (sizeof(void *) + sizeof(uint32_t) + sizeof(Objects_Name *)) +
148          ((maximum + minimum_index) * sizeof(Objects_Control *));
149    object_blocks = (void**) _Workspace_Allocate( block_size );
150
151    if ( !object_blocks ) {
152      _Workspace_Free( new_object_block );
153      return;
154    }
155   
156    /*
157     *  Break the block into the various sections.
158     */
159
160    inactive_per_block = (uint32_t *) _Addresses_Add_offset(
161        object_blocks, block_count * sizeof(void*) );
162    local_table = (Objects_Control **) _Addresses_Add_offset(
163        inactive_per_block, block_count * sizeof(uint32_t) );
164
165    /*
166     *  Take the block count down. Saves all the (block_count - 1)
167     *  in the copies.
168     */
169
170    block_count--;
171
172    if ( information->maximum > minimum_index ) {
173
174      /*
175       *  Copy each section of the table over. This has to be performed as
176       *  separate parts as size of each block has changed.
177       */
178
179      memcpy( object_blocks,
180              information->object_blocks,
181              block_count * sizeof(void*) );
182      memcpy( inactive_per_block,
183              information->inactive_per_block,
184              block_count * sizeof(uint32_t) );
185      memcpy( local_table,
186              information->local_table,
187              (information->maximum + minimum_index) * sizeof(Objects_Control *) );
188    }
189    else {
190
191      /*
192       *  Deal with the special case of the 0 to minimum_index
193       */
194      for ( index = 0; index < minimum_index; index++ ) {
195        local_table[ index ] = NULL;
196      }
197    }
198
199    /*
200     *  Initialise the new entries in the table.
201     */
202
203    object_blocks[block_count] = NULL;
204    inactive_per_block[block_count] = 0;
205
206    for ( index=index_base ;
207          index < ( information->allocation_size + index_base );
208          index++ ) {
209      local_table[ index ] = NULL;
210    }
211
212    _ISR_Disable( level );
213
214    old_tables = information->object_blocks;
215
216    information->object_blocks = object_blocks;
217    information->inactive_per_block = inactive_per_block;
218    information->local_table = local_table;
219    information->maximum = (Objects_Maximum) maximum;
220    information->maximum_id = _Objects_Build_id(
221        information->the_api,
222        information->the_class,
223        _Objects_Local_node,
224        information->maximum
225      );
226
227    _ISR_Enable( level );
228
229    if ( old_tables )
230      _Workspace_Free( old_tables );
231
232    block_count++;
233  }
234
235  /*
236   *  Assign the new object block to the object block table.
237   */
238
239  information->object_blocks[ block ] = new_object_block;
240
241  /*
242   *  Initialize objects .. add to a local chain first.
243   */
244
245  _Chain_Initialize(
246    &Inactive,
247    information->object_blocks[ block ],
248    information->allocation_size,
249    information->size
250  );
251
252  /*
253   *  Move from the local chain, initialise, then append to the inactive chain
254   */
255
256  index = index_base;
257
258  while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
259
260    the_object->id = _Objects_Build_id(
261        information->the_api,
262        information->the_class,
263        _Objects_Local_node,
264        index
265      );
266
267    _Chain_Append( &information->Inactive, &the_object->Node );
268
269    index++;
270  }
271
272  information->inactive_per_block[ block ] = information->allocation_size;
273  information->inactive =
274    (Objects_Maximum)(information->inactive + information->allocation_size);
275}
Note: See TracBrowser for help on using the repository browser.