source: rtems/cpukit/score/src/objectextendinformation.c @ 2bc236ba

4.104.114.84.95
Last change on this file since 2bc236ba was a0ed4ed, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/18/04 at 06:13:55

Remove stray white spaces.

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