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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [services/] [memalloc/] [common/] [current/] [include/] [sepmetaimpl.inl] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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