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

4.104.11
Last change on this file since d041e59 was d041e59, checked in by Joel Sherrill <joel.sherrill@…>, on Jan 8, 2009 at 3:01:52 PM

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

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