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

4.104.114.84.95
Last change on this file since ef9505a9 was ef9505a9, checked in by Joel Sherrill <joel.sherrill@…>, on 07/01/02 at 22:30:12

2002-07-01 Joel Sherrill <joel@…>

  • Mega patch merge to change the format of the object IDs to loosen the dependency between the SCORE and the various APIs. There was considerable work to simplify the object name management and it appears that the name_table field is no longer needed. This patch also includes the addition of the internal mutex which is currently only used to protect some types of allocation and deallocation. This significantly can reduce context switch latency under certain circumstances. In particular, some heap/region operations were O(n) and had dispatching disabled. This should help enormously. With this merge, the patch is not as clean as it should be. In particular, the documentation has not been modified to reflect the new object ID layout, the IDs in the test screens are not updated, and _Objects_Get_information needs to be a real routine not inlined. As part of this patch a lot of MP code for thread/proxy blocking was made conditional and cleaned up.
  • include/Makefile.am, include/rtems/score/coremsg.h, include/rtems/score/coremutex.h, include/rtems/score/coresem.h, include/rtems/score/object.h, include/rtems/score/threadq.h, inline/rtems/score/object.inl, inline/rtems/score/thread.inl, macros/rtems/score/object.inl, src/Makefile.am, src/coremsg.c, src/coremutex.c, src/coresem.c, src/mpci.c, src/objectcomparenameraw.c, src/objectextendinformation.c, src/objectinitializeinformation.c, src/objectnametoid.c, src/thread.c, src/threadclose.c, src/threadget.c, src/threadq.c, src/threadqextractwithproxy.c: Modified as part of above.
  • include/rtems/score/apimutex.h, src/objectgetnoprotection.c: New files.
  • Property mode set to 100644
File size: 7.6 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#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  unsigned32        block_count;
49  unsigned32        block;
50  unsigned32        index_base;
51  unsigned32        minimum_index;
52  unsigned32        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    unsigned32       *inactive_per_block;
85    Objects_Control **local_table;
86    unsigned32        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     *      unsigned32       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(unsigned32) + 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(unsigned32) + 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 = (unsigned32 *) _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(unsigned32) );
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(unsigned32) );
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.