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

4.104.115
Last change on this file since b028e725 was b028e725, checked in by Joel Sherrill <joel.sherrill@…>, on 01/05/09 at 20:09:02

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

  • score/include/rtems/score/object.h, score/src/objectallocatebyindex.c: Object index should be int. Fix bug when index is negative.
  • score/src/objectextendinformation.c: Do not allow maximum number of allocated objects to exceed maximum representable in index field of Object Id.
  • score/src/objectgetisr.c: Use same code that is in _Objects_Get to extract index field of Object Id.
  • Property mode set to 100644
File size: 6.9 KB
RevLine 
[317a5b5]1/*
2 *  Object Handler
3 *
4 *
[08311cc3]5 *  COPYRIGHT (c) 1989-1999.
[317a5b5]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
[dd687d97]10 *  http://www.rtems.com/license/LICENSE.
[317a5b5]11 *
12 *  $Id$
13 */
14
[a8eed23]15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
[317a5b5]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
[a76e2b4]31#include <string.h>  /* for memcpy() */
32
[317a5b5]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;
[3127180]51  uint32_t          block_count;
52  uint32_t          block;
53  uint32_t          index_base;
54  uint32_t          minimum_index;
55  uint32_t          index;
[317a5b5]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;
[05279b84]65
[317a5b5]66  if ( information->maximum < minimum_index )
67    block_count = 0;
68  else {
69    block_count = information->maximum / information->allocation_size;
[05279b84]70
[317a5b5]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;
[3127180]86    uint32_t         *inactive_per_block;
[317a5b5]87    Objects_Control **local_table;
[3127180]88    uint32_t          maximum;
[a0ed4ed]89    void             *old_tables;
[05279b84]90
[317a5b5]91    /*
92     *  Growing the tables means allocating a new area, doing a copy and
93     *  updating the information table.
94     *
95     *  If the maximum is minimum we do not have a table to copy. First
96     *  time through.
97     *
98     *  The allocation has :
99     *
100     *      void            *objects[block_count];
[3127180]101     *      uint32_t         inactive_count[block_count];
[317a5b5]102     *      Objects_Control *local_table[maximum];
103     *
104     *  This is the order in memory. Watch changing the order. See the memcpy
105     *  below.
106     */
107
108    /*
109     *  Up the block count and maximum
110     */
111
112    block_count++;
[05279b84]113
[317a5b5]114    maximum = information->maximum + information->allocation_size;
115
[b028e725]116    /*
117     *  We need to limit the number of objects to the maximum number
118     *  representable in the index portion of the object Id.  In the
119     *  case of 16-bit Ids, this is only 256 object instances.
120     */
121    if ( maximum > OBJECTS_ID_FINAL_INDEX )
122      return;
123
[317a5b5]124    /*
125     *  Allocate the tables and break it up.
126     */
[05279b84]127
[317a5b5]128    if ( information->auto_extend ) {
129      object_blocks = (void**)
130        _Workspace_Allocate(
131          block_count *
[a5b6cdd]132             (sizeof(void *) + sizeof(uint32_t) + sizeof(Objects_Name *)) +
[317a5b5]133          ((maximum + minimum_index) * sizeof(Objects_Control *))
134          );
135
136      if ( !object_blocks )
137        return;
138    }
139    else {
140      object_blocks = (void**)
141        _Workspace_Allocate_or_fatal_error(
[a0ed4ed]142          block_count *
[2345d61b]143             (sizeof(void *) + sizeof(uint32_t) + sizeof(Objects_Name *)) +
[317a5b5]144          ((maximum + minimum_index) * sizeof(Objects_Control *))
145        );
146    }
147
148    /*
149     *  Break the block into the various sections.
150     *
151     */
[05279b84]152
[a5b6cdd]153    inactive_per_block = (uint32_t *) _Addresses_Add_offset(
[317a5b5]154        object_blocks, block_count * sizeof(void*) );
155    local_table = (Objects_Control **) _Addresses_Add_offset(
[2345d61b]156        inactive_per_block, block_count * sizeof(uint32_t) );
[05279b84]157
[317a5b5]158    /*
159     *  Take the block count down. Saves all the (block_count - 1)
160     *  in the copies.
161     */
162
163    block_count--;
[05279b84]164
[317a5b5]165    if ( information->maximum > minimum_index ) {
[05279b84]166
[317a5b5]167      /*
168       *  Copy each section of the table over. This has to be performed as
169       *  separate parts as size of each block has changed.
170       */
[05279b84]171
[317a5b5]172      memcpy( object_blocks,
173              information->object_blocks,
174              block_count * sizeof(void*) );
175      memcpy( inactive_per_block,
176              information->inactive_per_block,
[a5b6cdd]177              block_count * sizeof(uint32_t) );
[317a5b5]178      memcpy( local_table,
179              information->local_table,
180              (information->maximum + minimum_index) * sizeof(Objects_Control *) );
181    }
182    else {
183
184      /*
185       *  Deal with the special case of the 0 to minimum_index
186       */
187      for ( index = 0; index < minimum_index; index++ ) {
188        local_table[ index ] = NULL;
189      }
190    }
[05279b84]191
[317a5b5]192    /*
193     *  Initialise the new entries in the table.
194     */
[05279b84]195
[317a5b5]196    object_blocks[block_count] = NULL;
197    inactive_per_block[block_count] = 0;
198
199    for ( index=index_base ;
200          index < ( information->allocation_size + index_base );
201          index++ ) {
202      local_table[ index ] = NULL;
203    }
[05279b84]204
[317a5b5]205    _ISR_Disable( level );
206
207    old_tables = information->object_blocks;
[05279b84]208
[317a5b5]209    information->object_blocks = object_blocks;
210    information->inactive_per_block = inactive_per_block;
211    information->local_table = local_table;
212    information->maximum = maximum;
[ef9505a9]213    information->maximum_id = _Objects_Build_id(
[a0ed4ed]214        information->the_api,
[ef9505a9]215        information->the_class,
216        _Objects_Local_node,
217        information->maximum
[317a5b5]218      );
219
220    _ISR_Enable( level );
221
222    if ( old_tables )
223      _Workspace_Free( old_tables );
[05279b84]224
[317a5b5]225    block_count++;
226  }
[05279b84]227
[317a5b5]228  /*
229   *  Allocate the name table, and the objects
230   */
231
232  if ( information->auto_extend ) {
[a0ed4ed]233    information->object_blocks[ block ] =
[317a5b5]234      _Workspace_Allocate(
235        (information->allocation_size * information->size)
236      );
237
238    if ( !information->object_blocks[ block ] )
239      return;
240  }
241  else {
[a0ed4ed]242    information->object_blocks[ block ] =
[317a5b5]243      _Workspace_Allocate_or_fatal_error(
244        (information->allocation_size * information->size)
245      );
246  }
[05279b84]247
[317a5b5]248  /*
249   *  Initialize objects .. add to a local chain first.
250   */
251
252  _Chain_Initialize(
253    &Inactive,
254    information->object_blocks[ block ],
255    information->allocation_size,
256    information->size
257  );
258
259  /*
260   *  Move from the local chain, initialise, then append to the inactive chain
261   */
262
263  index = index_base;
[05279b84]264
[317a5b5]265  while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
[05279b84]266
[ef9505a9]267    the_object->id = _Objects_Build_id(
[a0ed4ed]268        information->the_api,
[ef9505a9]269        information->the_class,
270        _Objects_Local_node,
271        index
[317a5b5]272      );
[05279b84]273
[317a5b5]274    _Chain_Append( &information->Inactive, &the_object->Node );
275
276    index++;
277  }
[05279b84]278
[317a5b5]279  information->inactive_per_block[ block ] = information->allocation_size;
280  information->inactive += information->allocation_size;
281}
Note: See TracBrowser for help on using the repository browser.