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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [memalloc/] [common/] [v2_0/] [include/] [sepmetaimpl.inl] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#ifndef CYGONCE_MEMALLOC_SEPMETAIMPL_INL
2
#define CYGONCE_MEMALLOC_SEPMETAIMPL_INL
3
 
4
//==========================================================================
5
//
6
//      sepmetaimpl.inl
7
//
8
//      Variable block memory pool with separate metadata class declarations
9
//
10
//==========================================================================
11
//####ECOSGPLCOPYRIGHTBEGIN####
12
// -------------------------------------------
13
// This file is part of eCos, the Embedded Configurable Operating System.
14
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15
//
16
// eCos is free software; you can redistribute it and/or modify it under
17
// the terms of the GNU General Public License as published by the Free
18
// Software Foundation; either version 2 or (at your option) any later version.
19
//
20
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
22
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23
// for more details.
24
//
25
// You should have received a copy of the GNU General Public License along
26
// with eCos; if not, write to the Free Software Foundation, Inc.,
27
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28
//
29
// As a special exception, if other files instantiate templates or use macros
30
// or inline functions from this file, or you compile this file and link it
31
// with other works to produce a work based on this file, this file does not
32
// by itself cause the resulting work to be covered by the GNU General Public
33
// License. However the source code for this file must still be made available
34
// in accordance with section (3) of the GNU General Public License.
35
//
36
// This exception does not invalidate any other reasons why a work based on
37
// this file might be covered by the GNU General Public License.
38
//
39
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40
// at http://sources.redhat.com/ecos/ecos-license/
41
// -------------------------------------------
42
//####ECOSGPLCOPYRIGHTEND####
43
//==========================================================================
44
//#####DESCRIPTIONBEGIN####
45
//
46
// Author(s):    jlarmour
47
// Contributors: hmt
48
// Date:         2001-06-28
49
// Purpose:      Define Sepmetaimpl class interface
50
// Description:  Inline class for constructing a variable block allocator
51
//               with separate metadata.
52
// Usage:        #include 
53
//
54
//
55
//####DESCRIPTIONEND####
56
//
57
//==========================================================================
58
 
59
#include 
60
#ifdef CYGPKG_ISOINFRA
61
# include 
62
#endif
63
#include 
64
#include 
65
 
66
#include            // assertion support
67
#include           // tracing support
68
 
69
// Simple allocator
70
 
71
// The memory block lists are doubly linked lists. One for all alloced
72
// blocks, one for all free blocks. There's also a list of unused
73
// metadata from the metadata pool.  The head of the
74
// list has the same structure but its memnext/memprev fields are zero.
75
// Always having at least one item on the list simplifies the alloc and
76
// free code.
77
#ifdef CYGINT_ISO_STRING_MEMFUNCS
78
# include 
79
#endif
80
 
81
inline void
82
Cyg_Mempool_Sepmeta_Implementation::copy_data( cyg_uint8 *dst,
83
                                               cyg_uint8 *src,
84
                                               cyg_int32 nbytes )
85
{
86
#ifdef CYGINT_ISO_STRING_MEMFUNCS
87
    memmove( dst, src, nbytes );
88
#else
89
    if ((src < dst) && (dst < (src + nbytes))) {
90
        // Have to copy backwards
91
        src += nbytes;
92
        dst += nbytes;
93
        while (nbytes--) {
94
            *--dst = *--src;
95
        }
96
    } else {
97
        while (nbytes--) {
98
            *dst++ = *src++;
99
        }
100
    }
101
#endif
102
}
103
 
104
inline cyg_uint8 *
105
Cyg_Mempool_Sepmeta_Implementation::alignup( cyg_uint8 *addr )
106
{
107
    return (cyg_uint8 *)((cyg_int32)(addr + alignment-1) & -alignment);
108
}
109
 
110
inline cyg_uint8 *
111
Cyg_Mempool_Sepmeta_Implementation::aligndown( cyg_uint8 *addr )
112
{
113
    return (cyg_uint8 *)((cyg_int32)addr & -alignment);
114
}
115
 
116
inline cyg_uint8 *
117
Cyg_Mempool_Sepmeta_Implementation::alignmetaup( cyg_uint8 *addr )
118
{
119
    const size_t memdqalign = __alignof__ (struct memdq);
120
    return (cyg_uint8 *)((cyg_int32)(addr + memdqalign-1) & -memdqalign);
121
}
122
 
123
inline cyg_uint8 *
124
Cyg_Mempool_Sepmeta_Implementation::alignmetadown( cyg_uint8 *addr )
125
{
126
    const size_t memdqalign = __alignof__ (struct memdq);
127
    return (cyg_uint8 *)((cyg_int32)addr & -memdqalign);
128
}
129
 
130
// return the alloced dq at mem
131
inline struct Cyg_Mempool_Sepmeta_Implementation::memdq *
132
Cyg_Mempool_Sepmeta_Implementation::find_alloced_dq( cyg_uint8 *mem )
133
{
134
    struct memdq *dq=allocedhead.next;
135
 
136
    while (dq->mem != mem ) {
137
        CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
138
        CYG_ASSERT( dq->memnext->memprev==dq, "Bad link in mem dq");
139
        if (dq->next == &memend) // address not found!
140
            return NULL;
141
        dq = dq->next;
142
    }
143
    return dq;
144
}
145
 
146
// returns a free dq of at least size, or NULL if none
147
inline struct Cyg_Mempool_Sepmeta_Implementation::memdq *
148
Cyg_Mempool_Sepmeta_Implementation::find_free_dq( cyg_int32 size )
149
{
150
    struct memdq *dq = freehead.next;
151
 
152
    while ( (dq->memnext->mem - dq->mem) < size ) {
153
        CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
154
        CYG_ASSERT( dq->memnext->memprev==dq, "Bad link in mem dq");
155
        if (dq->next == &freehead) { // reached end of list
156
            return NULL;
157
        }
158
        dq = dq->next; // next on free list
159
    }
160
    return dq;
161
}
162
 
163
// returns the free dq following mem
164
inline struct Cyg_Mempool_Sepmeta_Implementation::memdq *
165
Cyg_Mempool_Sepmeta_Implementation::find_free_dq_slot( cyg_uint8 *mem )
166
{
167
    struct memdq *dq;
168
    for (dq = freehead.next; dq->mem < mem; dq = dq->next) {
169
        if ( dq == &freehead ) // wrapped round
170
            break;
171
    }
172
    return dq;
173
}
174
 
175
inline void
176
Cyg_Mempool_Sepmeta_Implementation::check_free_memdq( struct memdq *dq )
177
{
178
    if (dq == &freehead)
179
        return;
180
    CYG_ASSERT(dq->memnext->memprev == dq, "corrupted free dq #1");
181
    CYG_ASSERT(dq->next->prev == dq, "corrupted free dq #2");
182
    CYG_ASSERT(dq->memprev->memnext == dq, "corrupted free dq #3");
183
    CYG_ASSERT(dq->prev->next == dq, "corrupted free dq #4");
184
    CYG_ASSERT(dq->memnext->mem > dq->mem, "free dq mem not sorted #1");
185
    if (dq->memprev != &memend)
186
        CYG_ASSERT(dq->memprev->mem < dq->mem, "free dq mem not sorted #2");
187
}
188
 
189
inline void
190
Cyg_Mempool_Sepmeta_Implementation::check_alloced_memdq( struct memdq *dq )
191
{
192
    CYG_ASSERT(dq->memnext->memprev == dq, "corrupted alloced dq #1");
193
    CYG_ASSERT(dq->next->prev == dq, "corrupted alloced dq #2");
194
    CYG_ASSERT(dq->memprev->memnext == dq, "corrupted alloced dq #3");
195
    CYG_ASSERT(dq->prev->next == dq, "corrupted alloced dq #4");
196
    if (dq != &memend)
197
        CYG_ASSERT(dq->memnext->mem > dq->mem, "alloced dq mem not sorted #1");
198
    if (dq->memprev != &memhead)
199
        CYG_ASSERT(dq->memprev->mem < dq->mem, "alloced dq mem not sorted #2");
200
}
201
 
202
// -------------------------------------------------------------------------
203
 
204
inline void
205
Cyg_Mempool_Sepmeta_Implementation::insert_free_block( struct memdq *dq )
206
{
207
    // scan for correct slot in the sorted free list
208
    struct memdq *fdq = find_free_dq_slot( dq->mem );
209
 
210
    CYG_ASSERT(fdq != &freehead ? fdq->mem > dq->mem : 1,
211
               "Block address is already in freelist");
212
 
213
    check_free_memdq(fdq);
214
 
215
    if (dq->memnext == fdq) {
216
        // we can coalesce these two together
217
        // adjust fdq's mem address backwards to include dq
218
        fdq->mem = dq->mem;
219
        // and remove dq
220
        fdq->memprev = dq->memprev;
221
        fdq->memprev->memnext = fdq;
222
        // Don't need to adjust fdq's next/prev links as it stays in the
223
        // same place in the free list
224
 
225
        // dq is now redundant so return to metadata free list
226
        dq->next = freemetahead;
227
        freemetahead = dq;
228
 
229
        // reset dq
230
        dq = fdq;
231
    } else {
232
        // insert behind fdq
233
        dq->next = fdq;
234
        dq->prev = fdq->prev;
235
        fdq->prev = dq;
236
        dq->prev->next = dq;
237
    }
238
 
239
    check_free_memdq(dq);
240
 
241
    // maybe also coalesce backwards
242
    if (dq->memprev == dq->prev) {
243
        // adjust dq's mem address backwards to include dq->prev
244
        dq->mem = dq->prev->mem;
245
 
246
        // return dq->prev to metadata free list
247
        dq->prev->next = freemetahead;
248
        freemetahead = dq->prev;
249
 
250
        // and remove dq->prev from mem list
251
        dq->memprev = dq->prev->memprev;
252
        dq->memprev->memnext = dq;
253
        // and free list
254
        dq->prev = dq->prev->prev;
255
        dq->prev->next = dq;
256
 
257
        check_free_memdq(dq);
258
    }
259
}
260
 
261
// -------------------------------------------------------------------------
262
#include 
263
inline
264
Cyg_Mempool_Sepmeta_Implementation::Cyg_Mempool_Sepmeta_Implementation(
265
        cyg_uint8 *base,
266
        cyg_int32 size,
267
        CYG_ADDRWORD consargs)
268
{
269
    CYG_REPORT_FUNCTION();
270
    struct constructorargs *args = (struct constructorargs *)consargs;
271
    CYG_CHECK_DATA_PTRC( args );
272
 
273
    alignment = args->alignment;
274
 
275
    CYG_ASSERT( alignment > 0, "Bad alignment" );
276
    CYG_ASSERT( 0!=alignment, "alignment is zero" );
277
    CYG_ASSERT( 0==(alignment & alignment-1), "alignment not a power of 2" );
278
 
279
    obase=base;
280
    osize=size;
281
    metabase = args->metabase;
282
    metasize = args->metasize;
283
 
284
    // bottom is set to the lowest available address given the alignment.
285
    bottom = alignup( base );
286
    cyg_uint8 *metabottom = alignmetaup( metabase );
287
 
288
    // because we split free blocks by allocating memory from the end, not
289
    // the beginning, then to preserve alignment, the *top* must also be
290
    // aligned
291
    top = aligndown( base+size );
292
    cyg_uint8 *metatop = metabottom +
293
        sizeof(struct memdq)*(metasize/sizeof(struct memdq));
294
 
295
    CYG_ASSERT( top > bottom , "heap too small" );
296
    CYG_ASSERT( top <= (base+size), "top too large" );
297
    CYG_ASSERT( (((cyg_int32)(top)) & alignment-1)==0,
298
                "top badly aligned" );
299
    CYG_ASSERT( (((cyg_int32)(bottom)) & alignment-1)==0,
300
                "bottom badly aligned" );
301
 
302
    CYG_ASSERT( metatop > metabottom , "meta space too small" );
303
    CYG_ASSERT( metatop <= (metabase+metasize), "metatop too large" );
304
 
305
    // Initialize list of unused metadata blocks. Only need to do next
306
    // pointers - can ignore prev and size
307
    struct memdq *fq = freemetahead = (struct memdq *)metabottom;
308
 
309
    while ((cyg_uint8 *)fq < metatop) {
310
        fq->next = fq+1;
311
        fq++;
312
    }
313
 
314
    CYG_ASSERT((cyg_uint8 *)fq == metatop, "traversed metadata not aligned");
315
 
316
    // set final pointer to NULL;
317
    --fq; fq->next = NULL;
318
 
319
    // initialize the free list. memhead is the initial free block occupying
320
    // all of free memory.
321
    memhead.next = memhead.prev = &freehead;
322
    // The mem list is circular for consistency.
323
    memhead.memprev = memhead.memnext = &memend;
324
    memhead.mem = bottom;
325
 
326
    // initialize block that indicates end of memory. This pretends to
327
    // be an allocated block
328
    memend.next = memend.prev = &allocedhead;
329
    memend.memnext = memend.memprev = &memhead;
330
    memend.mem = top;
331
 
332
    // initialize alloced list memdq. memend pretends to be allocated memory
333
    // at the end
334
    allocedhead.next = allocedhead.prev = &memend;
335
    freehead.next = freehead.prev = &memhead;
336
    // Since allocedhead and freehead are placeholders, not real blocks,
337
    // assign addresses which can't match list searches
338
    allocedhead.memnext = allocedhead.memprev = NULL;
339
    freehead.memnext = freehead.memprev = NULL;
340
    freehead.mem = allocedhead.mem = NULL;
341
 
342
    freemem = top - bottom;
343
}
344
 
345
// -------------------------------------------------------------------------
346
 
347
inline
348
Cyg_Mempool_Sepmeta_Implementation::~Cyg_Mempool_Sepmeta_Implementation()
349
{
350
}
351
 
352
// -------------------------------------------------------------------------
353
// allocation is mostly simple
354
// First we look down the free list for a large enough block
355
// If we find a block the right size, we unlink the block from
356
//    the free list and return a pointer to it.
357
// If we find a larger block, we chop a piece off the end
358
//    and return that
359
// Otherwise we reach the end of the list and return NULL
360
 
361
inline cyg_uint8 *
362
Cyg_Mempool_Sepmeta_Implementation::try_alloc( cyg_int32 size )
363
{
364
    struct memdq *alloced;
365
 
366
    CYG_REPORT_FUNCTION();
367
 
368
    //  Allow uninitialised (zero sized) heaps because they could exist as a
369
    //  quirk of the MLT setup where a dynamically sized heap is at the top of
370
    //  memory.
371
    if (NULL == bottom || NULL==metabase)
372
        return NULL;
373
 
374
    size = (size + alignment - 1) & -alignment;
375
 
376
    struct memdq *dq = find_free_dq( size );
377
    if (NULL == dq)
378
        return NULL;
379
 
380
    cyg_int32 dqsize = dq->memnext->mem - dq->mem;
381
 
382
    if( size == dqsize ) {
383
        // exact fit -- unlink from free list
384
        dq->prev->next = dq->next;
385
        dq->next->prev = dq->prev;
386
 
387
        // set up this block for insertion into alloced list
388
        dq->next = dq->memnext; // since dq was free, dq->memnext must
389
                                // be allocated otherwise it would have
390
                                // been coalesced
391
        dq->prev = dq->next->prev;
392
 
393
        alloced = dq;
394
    } else {
395
 
396
        CYG_ASSERT( dqsize > size, "block found is too small");
397
 
398
        // Split into two memdq's, returning the second one
399
 
400
        // first get a memdq
401
 
402
        if ( NULL == freemetahead ) // out of metadata.
403
            return NULL;
404
 
405
        // FIXME: since we don't search all the way for an exact fit
406
        // first we may be able to find an exact fit later and therefore
407
        // not need more metadata. We don't do this yet though.
408
 
409
        alloced = freemetahead;
410
        freemetahead = alloced->next;
411
 
412
        // now set its values
413
        alloced->memnext = dq->memnext;
414
        alloced->next = dq->memnext; // since dq was free, dq->memnext must
415
                                     // be allocated otherwise it would have
416
                                     // been coalesced
417
        alloced->memprev = dq;
418
        alloced->prev = alloced->next->prev;
419
 
420
        alloced->mem = alloced->next->mem - size;
421
 
422
        // now set up dq (the portion that remains a free block)
423
        // dq->next and dq->prev are unchanged as we still end up pointing
424
        // at the same adjacent free blocks
425
        // dq->memprev obviously doesn't change
426
 
427
        dq->memnext = alloced;
428
 
429
        // finish inserting into memory block list
430
        alloced->memnext->memprev = alloced;
431
    alloced->next->prev = alloced->prev->next = alloced;
432
 
433
        check_free_memdq(dq);
434
    }
435
 
436
    CYG_ASSERT( bottom <= alloced->mem && alloced->mem <= top,
437
                "alloced outside pool" );
438
 
439
    // Insert block into alloced list.
440
    alloced->next->prev = alloced->prev->next = alloced;
441
 
442
    check_alloced_memdq(alloced);
443
 
444
    freemem -=size;
445
 
446
    CYG_ASSERT( ((CYG_ADDRESS)alloced->mem & (alignment-1)) == 0,
447
                "returned memory not aligned" );
448
    return alloced->mem;
449
}
450
 
451
// -------------------------------------------------------------------------
452
// resize existing allocation, if oldsize is non-NULL, previous
453
// allocation size is placed into it. If previous size not available,
454
// it is set to 0. NB previous allocation size may have been rounded up.
455
// Occasionally the allocation can be adjusted *backwards* as well as,
456
// or instead of forwards, therefore the address of the resized
457
// allocation is returned, or NULL if no resizing was possible.
458
// Note that this differs from ::realloc() in that no attempt is
459
// made to call malloc() if resizing is not possible - that is left
460
// to higher layers. The data is copied from old to new though.
461
// The effects of alloc_ptr==NULL or newsize==0 are undefined
462
 
463
inline cyg_uint8 *
464
Cyg_Mempool_Sepmeta_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
465
                                                   cyg_int32 newsize,
466
                                                   cyg_int32 *oldsize )
467
{
468
    cyg_int32 currsize, origsize;
469
 
470
    CYG_REPORT_FUNCTION();
471
 
472
    CYG_CHECK_DATA_PTRC( alloc_ptr );
473
    if ( NULL != oldsize )
474
        CYG_CHECK_DATA_PTRC( oldsize );
475
 
476
    CYG_ASSERT( (bottom <= alloc_ptr) && (alloc_ptr <= top),
477
                "alloc_ptr outside pool" );
478
 
479
    struct memdq *dq=find_alloced_dq( alloc_ptr );
480
    CYG_ASSERT( dq != NULL, "passed address not previously alloced");
481
 
482
    currsize = origsize = dq->memnext->mem - dq->mem;
483
    if ( NULL != oldsize )
484
        *oldsize = currsize;
485
 
486
    if ( newsize > currsize ) {
487
        cyg_int32 nextmemsize=0, prevmemsize=0;
488
 
489
        // see if we can increase the allocation size. Don't change anything
490
        // so we don't have to undo it later if it wouldn't fit
491
        if ( dq->next != dq->memnext ) { // if not equal, memnext must
492
                                         // be on free list
493
            nextmemsize = dq->memnext->memnext->mem - dq->memnext->mem;
494
        }
495
        if ( dq->prev != dq->memprev) { // ditto
496
            prevmemsize = dq->mem - dq->memprev->mem;
497
        }
498
        if (nextmemsize + prevmemsize + currsize < newsize)
499
            return NULL; // can't fit it
500
 
501
        // expand forwards
502
        if ( nextmemsize != 0 ) {
503
            if (nextmemsize <= (newsize - currsize)) { // taking all of it
504
                struct memdq *fblk = dq->memnext;
505
 
506
                // fix up mem list ptrs
507
                dq->memnext = fblk->memnext;
508
                dq->memnext->memprev=dq;
509
                // fix up free list ptrs
510
                fblk->next->prev = fblk->prev;
511
                fblk->prev->next = fblk->next;
512
 
513
                // return to meta list
514
                fblk->next = freemetahead;
515
                freemetahead = fblk->next;
516
                currsize += nextmemsize;
517
            } else { // only needs some
518
                dq->memnext->mem += (newsize - currsize);
519
                currsize = newsize;
520
            }
521
        }
522
 
523
        // expand backwards
524
        if ( currsize < newsize && prevmemsize != 0 ) {
525
            cyg_uint8 *oldmem = dq->mem;
526
 
527
            CYG_ASSERT( prevmemsize >= newsize - currsize,
528
                        "miscalculated expansion" );
529
            if (prevmemsize == (newsize - currsize)) { // taking all of it
530
                struct memdq *fblk = dq->memprev;
531
 
532
                // fix up mem list ptrs
533
                dq->memprev = fblk->memprev;
534
                dq->memprev->memnext=dq;
535
                dq->mem = fblk->mem;
536
                // fix up free list ptrs
537
                fblk->next->prev = fblk->prev;
538
                fblk->prev->next = fblk->next;
539
 
540
                // return to meta list
541
                fblk->next = freemetahead;
542
                freemetahead = fblk->next;
543
            } else { // only needs some
544
                dq->mem -= (newsize - currsize);
545
            }
546
 
547
            // move data into place
548
            copy_data( dq->mem, oldmem, origsize );
549
        }
550
    }
551
 
552
    if (newsize < currsize) {
553
        // shrink allocation
554
 
555
        // easy if the next block is already a free block
556
        if ( dq->memnext != dq->next ) {
557
            dq->memnext->mem -= currsize - newsize;
558
            CYG_ASSERT( dq->memnext->mem > dq->mem,
559
                        "moving next block back corruption" );
560
        } else {
561
            // if its already allocated we need to create a new free list
562
            // entry
563
            if (NULL == freemetahead)
564
                return NULL;  // can't do it
565
 
566
            struct memdq *fdq = freemetahead;
567
            freemetahead = fdq->next;
568
 
569
            fdq->memprev = dq;
570
            fdq->memnext = dq->memnext;
571
            fdq->mem = dq->mem + newsize;
572
 
573
            insert_free_block( fdq );
574
        }
575
    }
576
 
577
    freemem += origsize - newsize;
578
 
579
    return dq->mem;
580
} // resize_alloc()
581
 
582
 
583
// -------------------------------------------------------------------------
584
// When no coalescing is done, free is simply a matter of using the
585
// freed memory as an element of the free list linking it in at the
586
// start. When coalescing, the free list is sorted
587
 
588
inline cyg_bool
589
Cyg_Mempool_Sepmeta_Implementation::free( cyg_uint8 *p, cyg_int32 size )
590
{
591
    CYG_REPORT_FUNCTION();
592
 
593
    CYG_CHECK_DATA_PTRC( p );
594
 
595
    if (!((bottom <= p) && (p <= top)))
596
        return false;
597
 
598
    struct memdq *dq = find_alloced_dq( p );
599
    if (NULL == dq)
600
        return false;
601
 
602
    if (0 == size)
603
        size = dq->memnext->mem - dq->mem;
604
    else {
605
        size = (size + alignment - 1) & -alignment;
606
        if( (dq->memnext->mem - dq->mem) != size )
607
            return false;
608
    }
609
 
610
    check_alloced_memdq( dq );
611
 
612
    // Remove dq from alloced list
613
    dq->prev->next = dq->next;
614
    dq->next->prev = dq->prev;
615
 
616
    insert_free_block( dq );
617
 
618
    freemem += size;
619
 
620
    return true;
621
}
622
 
623
// -------------------------------------------------------------------------
624
 
625
inline void
626
Cyg_Mempool_Sepmeta_Implementation::get_status(
627
    cyg_mempool_status_flag_t flags,
628
    Cyg_Mempool_Status &status )
629
{
630
    CYG_REPORT_FUNCTION();
631
 
632
// as quick or quicker to just set it, rather than test flag first
633
    status.arenabase = obase;
634
    if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
635
        status.arenasize = top - bottom;
636
    if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
637
        status.totalallocated = (top-bottom) - freemem;
638
// as quick or quicker to just set it, rather than test flag first
639
    status.totalfree = freemem;
640
    if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
641
        struct memdq *dq = &freehead;
642
        cyg_int32 mf = 0;
643
 
644
        do {
645
            CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
646
            dq = dq->next;
647
            if (dq == &freehead) // wrapped round
648
                break;
649
            if(dq->memnext->mem - dq->mem > mf)
650
                mf = dq->memnext->mem - dq->mem;
651
        } while(1);
652
        status.maxfree = mf;
653
    }
654
// as quick or quicker to just set it, rather than test flag first
655
    status.origbase = obase;
656
// as quick or quicker to just set it, rather than test flag first
657
    status.origsize = osize;
658
 
659
    CYG_REPORT_RETURN();
660
 
661
} // get_status()
662
 
663
 
664
// -------------------------------------------------------------------------
665
#endif // ifndef CYGONCE_MEMALLOC_SEPMETAIMPL_INL
666
// EOF sepmetaimpl.inl

powered by: WebSVN 2.1.0

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