source: rtems/c/src/exec/score/src/objectextendinformation.c @ df49c60

4.104.114.84.95
Last change on this file since df49c60 was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

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