comparison packages/services/memalloc/common/current/include/mfiximpl.inl @ 115:6ed91473a1cd ecos-sw-2000-08-21

Merge from eCos master repository on 2000-08-21-22:40:54-BST
author jlarmour
date Fri, 25 Aug 2000 17:32:38 +0000
parents
children e0c0827131d1
comparison
equal deleted inserted replaced
114:5ad2b71d525e 115:6ed91473a1cd
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 //####COPYRIGHTBEGIN####
12 //
13 // -------------------------------------------
14 // The contents of this file are subject to the Red Hat eCos Public License
15 // Version 1.1 (the "License"); you may not use this file except in
16 // compliance with the License. You may obtain a copy of the License at
17 // http://www.redhat.com/
18 //
19 // Software distributed under the License is distributed on an "AS IS"
20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
21 // License for the specific language governing rights and limitations under
22 // the License.
23 //
24 // The Original Code is eCos - Embedded Configurable Operating System,
25 // released September 30, 1998.
26 //
27 // The Initial Developer of the Original Code is Red Hat.
28 // Portions created by Red Hat are
29 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
30 // All Rights Reserved.
31 // -------------------------------------------
32 //
33 //####COPYRIGHTEND####
34 //==========================================================================
35 //#####DESCRIPTIONBEGIN####
36 //
37 // Author(s): hmt
38 // Contributors: jlarmour
39 // Date: 2000-06-12
40 // Purpose: Define Mfiximpl class interface
41 // Description: Inline class for constructing a fixed block allocator
42 // Usage: #include <cyg/kernel/mfiximpl.hxx>
43 //
44 //
45 //####DESCRIPTIONEND####
46 //
47 //==========================================================================
48
49 #include <pkgconf/memalloc.h>
50 #include <cyg/hal/hal_arch.h> // HAL_LSBIT_INDEX magic asm code
51 #include <cyg/memalloc/mfiximpl.hxx>
52
53 // -------------------------------------------------------------------------
54
55 inline
56 Cyg_Mempool_Fixed_Implementation::Cyg_Mempool_Fixed_Implementation(
57 cyg_uint8 *base,
58 cyg_int32 size,
59 CYG_ADDRWORD alloc_unit )
60 {
61 cyg_int32 i;
62 bitmap = (cyg_uint32 *)base;
63 blocksize = alloc_unit;
64
65 CYG_ASSERT( blocksize > 0, "Bad blocksize" );
66 CYG_ASSERT( size > 2, "Bad blocksize" );
67 CYG_ASSERT( blocksize < size, "blocksize, size bad" );
68
69 numblocks = size / blocksize;
70 top = base + size;
71
72 CYG_ASSERT( numblocks >= 2, "numblocks bad" );
73
74 i = (numblocks + 31)/32; // number of words to map blocks
75 while ( (i * 4 + numblocks * blocksize) > size ) {
76 numblocks --; // steal one block for admin
77 i = (numblocks + 31)/32; // number of words to map blocks
78 }
79
80 CYG_ASSERT( 0 < i, "Bad word count for bitmap after fitment" );
81 CYG_ASSERT( 0 < numblocks, "Bad block count after fitment" );
82
83 maptop = i;
84 // this should leave space for the bitmap and maintain alignment
85 mempool = top - (numblocks * blocksize);
86 CYG_ASSERT( base < mempool && mempool < top, "mempool escaped" );
87 CYG_ASSERT( (cyg_uint8 *)(&bitmap[ maptop ]) <= mempool,
88 "mempool overwrites bitmap" );
89 CYG_ASSERT( &mempool[ numblocks * blocksize ] <= top,
90 "mempool overflows top" );
91 freeblocks = numblocks;
92 firstfree = 0;
93
94 // clear out the bitmap; no blocks allocated yet
95 for ( i = 0; i < maptop; i++ )
96 bitmap[ i ] = 0;
97 // apart from the non-existent ones at the top
98 for ( i = ((numblocks-1)&31) + 1; i < 32; i++ )
99 bitmap[ maptop - 1 ] |= ( 1 << i );
100 }
101
102 // -------------------------------------------------------------------------
103
104 inline
105 Cyg_Mempool_Fixed_Implementation::~Cyg_Mempool_Fixed_Implementation()
106 {
107 }
108
109 // -------------------------------------------------------------------------
110
111 inline cyg_uint8 *
112 Cyg_Mempool_Fixed_Implementation::try_alloc( cyg_int32 size )
113 {
114 // size parameter is not used
115 CYG_UNUSED_PARAM( cyg_int32, size );
116 if ( 0 >= freeblocks )
117 return NULL;
118 cyg_int32 i = firstfree;
119 cyg_uint8 *p = NULL;
120 do {
121 if ( 0xffffffff != bitmap[ i ] ) {
122 // then there is a free block in this bucket
123 register cyg_uint32 j, k;
124 k = ~bitmap[ i ]; // look for a 1 in complement
125 HAL_LSBIT_INDEX( j, k );
126 CYG_ASSERT( 0 <= j && j <= 31, "Bad bit index" );
127 CYG_ASSERT( 0 == (bitmap[ i ] & (1 << j)), "Found bit not clear" );
128 bitmap[ i ] |= (1 << j); // set it allocated
129 firstfree = i;
130 freeblocks--;
131 CYG_ASSERT( freeblocks >= 0, "allocated too many" );
132 p = &mempool[ ((32 * i) + j) * blocksize ];
133 break;
134 }
135 if ( ++i >= maptop )
136 i = 0; // wrap if at top
137 } while ( i != firstfree ); // prevent hang if internal error
138 CYG_ASSERT( NULL != p, "Should have a block here" );
139 CYG_ASSERT( mempool <= p && p <= top, "alloc mem escaped" );
140 return p;
141 }
142
143 // -------------------------------------------------------------------------
144 // supposedly resize existing allocation. This is defined in the
145 // fixed block allocator purely for API consistency. It will return
146 // an error (false) for all values, except for the blocksize
147 // returns true on success
148
149 inline cyg_uint8 *
150 Cyg_Mempool_Fixed_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
151 cyg_int32 newsize,
152 cyg_int32 *oldsize )
153 {
154 CYG_CHECK_DATA_PTRC( alloc_ptr );
155 if ( NULL != oldsize )
156 CYG_CHECK_DATA_PTRC( oldsize );
157
158 CYG_ASSERT( alloc_ptr >= mempool && alloc_ptr < top,
159 "alloc_ptr outside pool" );
160
161 if ( NULL != oldsize )
162 *oldsize = blocksize;
163
164 if (newsize == blocksize)
165 return alloc_ptr;
166 else
167 return NULL;
168 } // resize_alloc()
169
170
171 // -------------------------------------------------------------------------
172
173 inline cyg_bool
174 Cyg_Mempool_Fixed_Implementation::free( cyg_uint8 *p, cyg_int32 size )
175 {
176 // size parameter is not used
177 CYG_UNUSED_PARAM( cyg_int32, size );
178 if ( p < mempool || p >= top )
179 return false; // address way out of bounds
180 cyg_int32 i = p - mempool;
181 i = i / blocksize;
182 if ( &mempool[ i * blocksize ] != p )
183 return false; // address not aligned
184 cyg_int32 j = i / 32;
185 CYG_ASSERT( 0 <= j && j < maptop, "map index escaped" );
186 i = i - 32 * j;
187 CYG_ASSERT( 0 <= i && i < 32, "map bit index escaped" );
188 if ( ! ((1 << i) & bitmap[ j ] ) )
189 return false; // block was not allocated
190 bitmap[ j ] &=~(1 << i); // clear the bit
191 freeblocks++; // count the block
192 CYG_ASSERT( freeblocks <= numblocks, "freeblocks overflow" );
193 return true;
194 }
195
196 // -------------------------------------------------------------------------
197
198 inline void
199 Cyg_Mempool_Fixed_Implementation::get_status(
200 cyg_mempool_status_flag_t flags,
201 Cyg_Mempool_Status &status )
202 {
203 // as quick or quicker to just set it, rather than test flag first
204 status.arenabase = (const cyg_uint8 *)bitmap;
205 if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
206 status.arenasize = top - (cyg_uint8 *)bitmap;
207 if ( 0 != (flags & CYG_MEMPOOL_STAT_FREEBLOCKS) )
208 status.freeblocks = freeblocks;
209 if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
210 status.totalallocated = blocksize * numblocks;
211 if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALFREE) )
212 status.totalfree = blocksize * freeblocks;
213 if ( 0 != (flags & CYG_MEMPOOL_STAT_BLOCKSIZE) )
214 status.blocksize = blocksize;
215 if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
216 status.maxfree = freeblocks > 0 ? blocksize : 0;
217 }
218 // as quick or quicker to just set it, rather than test flag first
219 status.origbase = (const cyg_uint8 *)bitmap;
220 if ( 0 != (flags & CYG_MEMPOOL_STAT_ORIGSIZE) )
221 status.origsize = top - (cyg_uint8 *)bitmap;
222 // quicker to just set it, rather than test flag first
223 status.maxoverhead = 0;
224
225 } // get_status()
226
227 // -------------------------------------------------------------------------
228 #endif // ifndef CYGONCE_MEMALLOC_MFIXIMPL_INL
229 // EOF mfiximpl.inl