source: rtems/c/src/exec/score/src/objectextendinformation.c @ 317a5b5

4.104.114.84.95
Last change on this file since 317a5b5 was 317a5b5, checked in by Joel Sherrill <joel.sherrill@…>, on 11/02/99 at 19:43:52

Split object.c into multiple files.

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