source: SVN/cambria/redboot/packages/services/memalloc/common/current/include/mfiximpl.inl @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 8.9 KB
Line 
1#ifndef CYGONCE_MEMALLOC_MFIXIMPL_INL
2#define CYGONCE_MEMALLOC_MFIXIMPL_INL
3
4//==========================================================================
5//
6//      mfiximpl.inl
7//
8//      Memory pool with fixed block 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):    hmt
47// Contributors: jlarmour
48// Date:         2000-06-12
49// Purpose:      Define Mfiximpl class interface
50// Description:  Inline class for constructing a fixed block allocator
51// Usage:        #include <cyg/kernel/mfiximpl.hxx>
52//
53//
54//####DESCRIPTIONEND####
55//
56//==========================================================================
57
58#include <pkgconf/memalloc.h>
59#include <cyg/hal/hal_arch.h>          // HAL_LSBIT_INDEX magic asm code
60#include <cyg/memalloc/mfiximpl.hxx>
61
62
63// -------------------------------------------------------------------------
64
65inline
66Cyg_Mempool_Fixed_Implementation::Cyg_Mempool_Fixed_Implementation(
67        cyg_uint8 *base,
68        cyg_int32 size,
69        CYG_ADDRWORD alloc_unit )
70{
71    cyg_int32 i;
72    bitmap = (cyg_uint32 *)base;
73    blocksize = alloc_unit;
74
75    CYG_ASSERT( blocksize > 0, "Bad blocksize" );
76    CYG_ASSERT( size > 2, "Bad blocksize" );
77    CYG_ASSERT( blocksize < size, "blocksize, size bad" );
78
79    numblocks = size / blocksize;
80    top = base + size;
81
82    CYG_ASSERT( numblocks >= 2, "numblocks bad" );
83
84    i = (numblocks + 31)/32;        // number of words to map blocks
85    while ( (i * 4 + numblocks * blocksize) > size ) {
86        numblocks --;               // steal one block for admin
87        i = (numblocks + 31)/32;    // number of words to map blocks
88    }
89
90    CYG_ASSERT( 0 < i, "Bad word count for bitmap after fitment" );
91    CYG_ASSERT( 0 < numblocks, "Bad block count after fitment" );
92
93    maptop = i;
94    // this should leave space for the bitmap and maintain alignment
95    mempool = top - (numblocks * blocksize);
96    CYG_ASSERT( base < mempool && mempool < top, "mempool escaped" );
97    CYG_ASSERT( (cyg_uint8 *)(&bitmap[ maptop ]) <= mempool,
98                "mempool overwrites bitmap" );
99    CYG_ASSERT( &mempool[ numblocks * blocksize ] <= top,
100                "mempool overflows top" );
101    freeblocks = numblocks;
102    firstfree = 0;
103
104    // clear out the bitmap; no blocks allocated yet
105    for ( i = 0; i < maptop; i++ )
106        bitmap[ i ] = 0;
107    // apart from the non-existent ones at the top
108    for ( i = ((numblocks-1)&31) + 1; i < 32; i++ )
109        bitmap[ maptop - 1 ] |= ( 1 << i );
110}
111
112// -------------------------------------------------------------------------
113
114inline
115Cyg_Mempool_Fixed_Implementation::~Cyg_Mempool_Fixed_Implementation()
116{
117}
118
119// -------------------------------------------------------------------------
120
121inline cyg_uint8 *
122Cyg_Mempool_Fixed_Implementation::try_alloc( cyg_int32 size )
123{
124    // size parameter is not used
125    CYG_UNUSED_PARAM( cyg_int32, size );
126    if ( 0 >= freeblocks ) {
127        CYG_MEMALLOC_FAIL(size);
128        return NULL;
129    }
130    cyg_int32 i = firstfree;
131    cyg_uint8 *p = NULL;
132    do {
133        if ( 0xffffffff != bitmap[ i ] ) {
134            // then there is a free block in this bucket
135            register cyg_uint32 j, k;
136            k = ~bitmap[ i ];       // look for a 1 in complement
137            HAL_LSBIT_INDEX( j, k );
138            CYG_ASSERT( 0 <= j && j <= 31, "Bad bit index" );
139            CYG_ASSERT( 0 == (bitmap[ i ] & (1 << j)), "Found bit not clear" );
140            bitmap[ i ] |= (1 << j); // set it allocated
141            firstfree = i;
142            freeblocks--;
143            CYG_ASSERT( freeblocks >= 0, "allocated too many" );
144            p = &mempool[ ((32 * i) + j) * blocksize ];
145            break;
146        }
147        if ( ++i >= maptop )
148            i = 0;                  // wrap if at top
149    } while ( i != firstfree );     // prevent hang if internal error
150    CYG_ASSERT( NULL != p, "Should have a block here" );
151    CYG_ASSERT( mempool <= p  && p <= top, "alloc mem escaped" );
152    return p;
153}
154   
155// -------------------------------------------------------------------------
156// supposedly resize existing allocation. This is defined in the
157// fixed block allocator purely for API consistency. It will return
158// an error (false) for all values, except for the blocksize
159// returns true on success
160
161inline cyg_uint8 *
162Cyg_Mempool_Fixed_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
163                                                cyg_int32 newsize,
164                                                cyg_int32 *oldsize )
165{
166    CYG_CHECK_DATA_PTRC( alloc_ptr );
167    if ( NULL != oldsize )
168        CYG_CHECK_DATA_PTRC( oldsize );
169
170    CYG_ASSERT( alloc_ptr >= mempool && alloc_ptr < top,
171                "alloc_ptr outside pool" );
172   
173    if ( NULL != oldsize )
174        *oldsize = blocksize;
175
176    if (newsize == blocksize)
177        return alloc_ptr;
178    else {
179        CYG_MEMALLOC_FAIL(newsize);
180        return NULL;
181    }
182} // resize_alloc()
183
184
185// -------------------------------------------------------------------------
186
187inline cyg_bool
188Cyg_Mempool_Fixed_Implementation::free( cyg_uint8 *p, cyg_int32 size )
189{
190    // size parameter is not used
191    CYG_UNUSED_PARAM( cyg_int32, size );
192    if ( p < mempool || p >= top )
193        return false;               // address way out of bounds
194    cyg_int32 i = p - mempool;
195    i = i / blocksize;
196    if ( &mempool[ i * blocksize ] != p )
197        return false;               // address not aligned
198    cyg_int32 j = i / 32;
199    CYG_ASSERT( 0 <= j && j < maptop, "map index escaped" );
200    i = i - 32 * j;
201    CYG_ASSERT( 0 <= i && i < 32, "map bit index escaped" );
202    if ( ! ((1 << i) & bitmap[ j ] ) )
203        return false;               // block was not allocated
204    bitmap[ j ] &=~(1 << i);        // clear the bit
205    freeblocks++;                   // count the block
206    CYG_ASSERT( freeblocks <= numblocks, "freeblocks overflow" );
207    return true;
208}
209
210// -------------------------------------------------------------------------
211
212inline void
213Cyg_Mempool_Fixed_Implementation::get_status(
214    cyg_mempool_status_flag_t flags,
215    Cyg_Mempool_Status &status )
216{
217// as quick or quicker to just set it, rather than test flag first
218    status.arenabase = (const cyg_uint8 *)bitmap;
219    if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
220        status.arenasize = top - (cyg_uint8 *)bitmap;
221    if ( 0 != (flags & CYG_MEMPOOL_STAT_FREEBLOCKS) )
222        status.freeblocks = freeblocks;
223    if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
224        status.totalallocated = blocksize * numblocks;
225    if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALFREE) )
226        status.totalfree = blocksize * freeblocks;
227    if ( 0 != (flags & CYG_MEMPOOL_STAT_BLOCKSIZE) )
228        status.blocksize = blocksize;
229    if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
230        status.maxfree = freeblocks > 0 ? blocksize : 0;
231    }
232// as quick or quicker to just set it, rather than test flag first
233    status.origbase = (const cyg_uint8 *)bitmap;
234    if ( 0 != (flags & CYG_MEMPOOL_STAT_ORIGSIZE) )
235        status.origsize = top - (cyg_uint8 *)bitmap;
236// quicker to just set it, rather than test flag first
237    status.maxoverhead = 0;
238       
239} // get_status()
240
241// -------------------------------------------------------------------------
242#endif // ifndef CYGONCE_MEMALLOC_MFIXIMPL_INL
243// EOF mfiximpl.inl
Note: See TracBrowser for help on using the repository browser.