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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [score/] [src/] [objectextendinformation.c] - Blame information for rev 1026

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 *  objectextendinformation.c,v 1.4 2002/07/01 22:30:12 joel 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
#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
 
41
void _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
}

powered by: WebSVN 2.1.0

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