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

4.115
Last change on this file since d7c3883 was a0323a9f, checked in by Joel Sherrill <joel.sherrill@…>, on 02/16/11 at 00:24:49

2011-02-15 Joel Sherrill <joel.sherrilL@…>

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