OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [exec/] [score/] [src/] [objectextendinformation.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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: objectextendinformation.c,v 1.2 2001-09-27 11:59:34 chris Exp $
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
 
39
void _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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.