This is the open source Pawn interpreter ported to mbed. See here: http://www.compuphase.com/pawn/pawn.htm and here: http://code.google.com/p/pawnscript/
Some instructions:
- Put the attached include folder next to your source, so when you compile you get all the proper definitions
- Use the attached main.p as a starting point if you wish
- Compile your main.p into main.amx - Put your main.amx on the mbed 'drive'
- Reset and be amazed.
Important Compile Notes:
- You should use the -S# option to define a smaller default stack size. Start with -S64 and go up from there if needed.
- To use on the Cortex-M0 version of the mbed (LPC11U24), you MUST include the TARGET=3 command-line option as well, so the pin names are properly defined. In the future this may be handled on the native code side.
Known Issues:
At the moment it appears the kbhit() function is not working right - at least on my mac. Will continue testing on Windows.Working fine.
Todo:
- Add more wrappers for the mbed peripherals
- Add Pawn overlay support, to allow much larger scripts to run (even on the LPC11U24)
amxpool.c@0:3ab1d2d14eb3, 2012-11-15 (annotated)
- Committer:
- tylerwilson
- Date:
- Thu Nov 15 17:41:21 2012 +0000
- Revision:
- 0:3ab1d2d14eb3
Initial Pawn 4.x interpreter for mbed check-in
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tylerwilson | 0:3ab1d2d14eb3 | 1 | /* Simple allocation from a memory pool, with automatic release of |
tylerwilson | 0:3ab1d2d14eb3 | 2 | * least-recently used blocks (LRU blocks). |
tylerwilson | 0:3ab1d2d14eb3 | 3 | * |
tylerwilson | 0:3ab1d2d14eb3 | 4 | * These routines are as simple as possible, and they are neither re-entrant |
tylerwilson | 0:3ab1d2d14eb3 | 5 | * nor thread-safe. Their purpose is to have a standard implementation for |
tylerwilson | 0:3ab1d2d14eb3 | 6 | * systems where overlays are used and malloc() is not available. |
tylerwilson | 0:3ab1d2d14eb3 | 7 | * |
tylerwilson | 0:3ab1d2d14eb3 | 8 | * The algorithm uses a first-fit strategy. It keeps all blocks in a single |
tylerwilson | 0:3ab1d2d14eb3 | 9 | * list (both used blocks and free blocks are in the same list). Every memory |
tylerwilson | 0:3ab1d2d14eb3 | 10 | * block must have a unique number that identifies the block. This unique |
tylerwilson | 0:3ab1d2d14eb3 | 11 | * number allows to search for the presence of the block in the pool and for |
tylerwilson | 0:3ab1d2d14eb3 | 12 | * "conditional allocation". |
tylerwilson | 0:3ab1d2d14eb3 | 13 | * |
tylerwilson | 0:3ab1d2d14eb3 | 14 | * |
tylerwilson | 0:3ab1d2d14eb3 | 15 | * Copyright (c) ITB CompuPhase, 2007-2012 |
tylerwilson | 0:3ab1d2d14eb3 | 16 | * |
tylerwilson | 0:3ab1d2d14eb3 | 17 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
tylerwilson | 0:3ab1d2d14eb3 | 18 | * use this file except in compliance with the License. You may obtain a copy |
tylerwilson | 0:3ab1d2d14eb3 | 19 | * of the License at |
tylerwilson | 0:3ab1d2d14eb3 | 20 | * |
tylerwilson | 0:3ab1d2d14eb3 | 21 | * http://www.apache.org/licenses/LICENSE-2.0 |
tylerwilson | 0:3ab1d2d14eb3 | 22 | * |
tylerwilson | 0:3ab1d2d14eb3 | 23 | * Unless required by applicable law or agreed to in writing, software |
tylerwilson | 0:3ab1d2d14eb3 | 24 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
tylerwilson | 0:3ab1d2d14eb3 | 25 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
tylerwilson | 0:3ab1d2d14eb3 | 26 | * License for the specific language governing permissions and limitations |
tylerwilson | 0:3ab1d2d14eb3 | 27 | * under the License. |
tylerwilson | 0:3ab1d2d14eb3 | 28 | * |
tylerwilson | 0:3ab1d2d14eb3 | 29 | * Version: $Id: amxpool.c 4731 2012-06-21 11:11:18Z thiadmer $ |
tylerwilson | 0:3ab1d2d14eb3 | 30 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 31 | #include <assert.h> |
tylerwilson | 0:3ab1d2d14eb3 | 32 | #include "amx.h" |
tylerwilson | 0:3ab1d2d14eb3 | 33 | #include "amxpool.h" |
tylerwilson | 0:3ab1d2d14eb3 | 34 | |
tylerwilson | 0:3ab1d2d14eb3 | 35 | #if !defined NULL |
tylerwilson | 0:3ab1d2d14eb3 | 36 | #define NULL ((void*)0) |
tylerwilson | 0:3ab1d2d14eb3 | 37 | #endif |
tylerwilson | 0:3ab1d2d14eb3 | 38 | |
tylerwilson | 0:3ab1d2d14eb3 | 39 | #define MIN_BLOCKSIZE 32 |
tylerwilson | 0:3ab1d2d14eb3 | 40 | #define PROTECT_LRU 0xffff |
tylerwilson | 0:3ab1d2d14eb3 | 41 | |
tylerwilson | 0:3ab1d2d14eb3 | 42 | typedef struct tagARENA { |
tylerwilson | 0:3ab1d2d14eb3 | 43 | unsigned blocksize; |
tylerwilson | 0:3ab1d2d14eb3 | 44 | short index; /* overlay index, -1 if free */ |
tylerwilson | 0:3ab1d2d14eb3 | 45 | unsigned short lru; |
tylerwilson | 0:3ab1d2d14eb3 | 46 | } ARENA; |
tylerwilson | 0:3ab1d2d14eb3 | 47 | |
tylerwilson | 0:3ab1d2d14eb3 | 48 | static void *pool_base; |
tylerwilson | 0:3ab1d2d14eb3 | 49 | static unsigned pool_size; |
tylerwilson | 0:3ab1d2d14eb3 | 50 | static unsigned short pool_lru; |
tylerwilson | 0:3ab1d2d14eb3 | 51 | |
tylerwilson | 0:3ab1d2d14eb3 | 52 | static void touchblock(ARENA *hdr); |
tylerwilson | 0:3ab1d2d14eb3 | 53 | static ARENA *findblock(int index); |
tylerwilson | 0:3ab1d2d14eb3 | 54 | |
tylerwilson | 0:3ab1d2d14eb3 | 55 | /* amx_poolinit() initializes the memory pool for the allocated blocks. |
tylerwilson | 0:3ab1d2d14eb3 | 56 | * If parameter pool is NULL, the existing pool is cleared (without changing |
tylerwilson | 0:3ab1d2d14eb3 | 57 | * its position or size). |
tylerwilson | 0:3ab1d2d14eb3 | 58 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 59 | void amx_poolinit(void *pool, unsigned size) |
tylerwilson | 0:3ab1d2d14eb3 | 60 | { |
tylerwilson | 0:3ab1d2d14eb3 | 61 | assert(pool!=NULL || pool_base!=NULL); |
tylerwilson | 0:3ab1d2d14eb3 | 62 | if (pool!=NULL) { |
tylerwilson | 0:3ab1d2d14eb3 | 63 | assert(size>sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 64 | /* save parameters in global variables, then "free" the entire pool */ |
tylerwilson | 0:3ab1d2d14eb3 | 65 | pool_base=pool; |
tylerwilson | 0:3ab1d2d14eb3 | 66 | pool_size=size; |
tylerwilson | 0:3ab1d2d14eb3 | 67 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 68 | pool_lru=0; |
tylerwilson | 0:3ab1d2d14eb3 | 69 | amx_poolfree(NULL); |
tylerwilson | 0:3ab1d2d14eb3 | 70 | } |
tylerwilson | 0:3ab1d2d14eb3 | 71 | |
tylerwilson | 0:3ab1d2d14eb3 | 72 | /* amx_poolfree() releases a block allocated earlier. The parameter must have |
tylerwilson | 0:3ab1d2d14eb3 | 73 | * the same value as that returned by an earlier call to amx_poolalloc(). That |
tylerwilson | 0:3ab1d2d14eb3 | 74 | * is, the "block" parameter must point directly behind the arena header of the |
tylerwilson | 0:3ab1d2d14eb3 | 75 | * block. |
tylerwilson | 0:3ab1d2d14eb3 | 76 | * When parameter "block" is NULL, the pool is re-initialized (meaning that |
tylerwilson | 0:3ab1d2d14eb3 | 77 | * all blocks are freed). |
tylerwilson | 0:3ab1d2d14eb3 | 78 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 79 | void amx_poolfree(void *block) |
tylerwilson | 0:3ab1d2d14eb3 | 80 | { |
tylerwilson | 0:3ab1d2d14eb3 | 81 | ARENA *hdr,*hdr2; |
tylerwilson | 0:3ab1d2d14eb3 | 82 | unsigned sz; |
tylerwilson | 0:3ab1d2d14eb3 | 83 | |
tylerwilson | 0:3ab1d2d14eb3 | 84 | assert(pool_base!=NULL); |
tylerwilson | 0:3ab1d2d14eb3 | 85 | assert(pool_size>sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 86 | |
tylerwilson | 0:3ab1d2d14eb3 | 87 | /* special case: if "block" is NULL, create a single free space */ |
tylerwilson | 0:3ab1d2d14eb3 | 88 | if (block==NULL) { |
tylerwilson | 0:3ab1d2d14eb3 | 89 | /* store an arena header at the start of the pool */ |
tylerwilson | 0:3ab1d2d14eb3 | 90 | hdr=(ARENA*)pool_base; |
tylerwilson | 0:3ab1d2d14eb3 | 91 | hdr->blocksize=pool_size-sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 92 | hdr->index=-1; |
tylerwilson | 0:3ab1d2d14eb3 | 93 | hdr->lru=0; |
tylerwilson | 0:3ab1d2d14eb3 | 94 | } else { |
tylerwilson | 0:3ab1d2d14eb3 | 95 | hdr=(ARENA*)((char*)block-sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 96 | assert((char*)hdr>=(char*)pool_base && (char*)hdr<(char*)pool_base+pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 97 | assert(hdr->blocksize<pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 98 | |
tylerwilson | 0:3ab1d2d14eb3 | 99 | /* free this block */ |
tylerwilson | 0:3ab1d2d14eb3 | 100 | hdr->index=-1; |
tylerwilson | 0:3ab1d2d14eb3 | 101 | |
tylerwilson | 0:3ab1d2d14eb3 | 102 | /* try to coalesce with the next block */ |
tylerwilson | 0:3ab1d2d14eb3 | 103 | hdr2=(ARENA*)((char*)hdr+hdr->blocksize+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 104 | if (hdr2->index==-1) |
tylerwilson | 0:3ab1d2d14eb3 | 105 | hdr->blocksize+=hdr2->blocksize+sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 106 | |
tylerwilson | 0:3ab1d2d14eb3 | 107 | /* try to coalesce with the previous block */ |
tylerwilson | 0:3ab1d2d14eb3 | 108 | if ((void*)hdr!=pool_base) { |
tylerwilson | 0:3ab1d2d14eb3 | 109 | sz=pool_size; |
tylerwilson | 0:3ab1d2d14eb3 | 110 | hdr2=(ARENA*)pool_base; |
tylerwilson | 0:3ab1d2d14eb3 | 111 | while (sz>0 && (char*)hdr2+hdr2->blocksize+sizeof(ARENA)!=(char*)hdr) { |
tylerwilson | 0:3ab1d2d14eb3 | 112 | assert(sz<=pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 113 | sz-=hdr2->blocksize+sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 114 | hdr2=(ARENA*)((char*)hdr2+hdr2->blocksize+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 115 | } /* while */ |
tylerwilson | 0:3ab1d2d14eb3 | 116 | assert((char*)hdr2+hdr2->blocksize+sizeof(ARENA)==(char*)hdr); |
tylerwilson | 0:3ab1d2d14eb3 | 117 | if (hdr2->index==-1) |
tylerwilson | 0:3ab1d2d14eb3 | 118 | hdr2->blocksize+=hdr->blocksize+sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 119 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 120 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 121 | } |
tylerwilson | 0:3ab1d2d14eb3 | 122 | |
tylerwilson | 0:3ab1d2d14eb3 | 123 | /* amx_poolalloc() allocates the requested number of bytes from the pool and |
tylerwilson | 0:3ab1d2d14eb3 | 124 | * returns a header to the start of it. Every block in the pool is prefixed |
tylerwilson | 0:3ab1d2d14eb3 | 125 | * with an "arena header"; the return value of this function points just |
tylerwilson | 0:3ab1d2d14eb3 | 126 | * behind this arena header. |
tylerwilson | 0:3ab1d2d14eb3 | 127 | * |
tylerwilson | 0:3ab1d2d14eb3 | 128 | * The block with the specified "index" should not already exist in the pool. |
tylerwilson | 0:3ab1d2d14eb3 | 129 | * In other words, parameter "index" should be unique for every of memory block, |
tylerwilson | 0:3ab1d2d14eb3 | 130 | * and the block should not change in size. Use amx_poolfind() to verify whether |
tylerwilson | 0:3ab1d2d14eb3 | 131 | * a block is already in the pool (and optionally amx_poolfree() to remove it). |
tylerwilson | 0:3ab1d2d14eb3 | 132 | * |
tylerwilson | 0:3ab1d2d14eb3 | 133 | * If no block of sufficient size is available, the routine frees blocks until |
tylerwilson | 0:3ab1d2d14eb3 | 134 | * the requested amount of memory can be allocated. There is no intelligent |
tylerwilson | 0:3ab1d2d14eb3 | 135 | * algorithm involved: the routine just frees the least-recently used block at |
tylerwilson | 0:3ab1d2d14eb3 | 136 | * every iteration (without considering the size of the block or whether that |
tylerwilson | 0:3ab1d2d14eb3 | 137 | * block is adjacent to a free block). |
tylerwilson | 0:3ab1d2d14eb3 | 138 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 139 | void *amx_poolalloc(unsigned size,int index) |
tylerwilson | 0:3ab1d2d14eb3 | 140 | { |
tylerwilson | 0:3ab1d2d14eb3 | 141 | ARENA *hdr,*hdrlru; |
tylerwilson | 0:3ab1d2d14eb3 | 142 | unsigned sz; |
tylerwilson | 0:3ab1d2d14eb3 | 143 | unsigned short minlru; |
tylerwilson | 0:3ab1d2d14eb3 | 144 | |
tylerwilson | 0:3ab1d2d14eb3 | 145 | assert(size>0); |
tylerwilson | 0:3ab1d2d14eb3 | 146 | assert(index>=0 && index<=SHRT_MAX); |
tylerwilson | 0:3ab1d2d14eb3 | 147 | assert(findblock(index)==NULL); |
tylerwilson | 0:3ab1d2d14eb3 | 148 | |
tylerwilson | 0:3ab1d2d14eb3 | 149 | /* align the size to a cell boundary */ |
tylerwilson | 0:3ab1d2d14eb3 | 150 | if ((size % sizeof(cell))!=0) |
tylerwilson | 0:3ab1d2d14eb3 | 151 | size+=sizeof(cell)-(size % sizeof(cell)); |
tylerwilson | 0:3ab1d2d14eb3 | 152 | if (size+sizeof(ARENA)>pool_size) |
tylerwilson | 0:3ab1d2d14eb3 | 153 | return NULL; /* requested block does not fit in the pool */ |
tylerwilson | 0:3ab1d2d14eb3 | 154 | |
tylerwilson | 0:3ab1d2d14eb3 | 155 | /* find a block large enough to get the size plus an arena header; at |
tylerwilson | 0:3ab1d2d14eb3 | 156 | * the same time, detect the block with the lowest LRU |
tylerwilson | 0:3ab1d2d14eb3 | 157 | * if no block of sufficient size can be found, the routine then frees |
tylerwilson | 0:3ab1d2d14eb3 | 158 | * the block with the lowest LRU count and tries again |
tylerwilson | 0:3ab1d2d14eb3 | 159 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 160 | do { |
tylerwilson | 0:3ab1d2d14eb3 | 161 | sz=pool_size; |
tylerwilson | 0:3ab1d2d14eb3 | 162 | hdr=(ARENA*)pool_base; |
tylerwilson | 0:3ab1d2d14eb3 | 163 | hdrlru=hdr; |
tylerwilson | 0:3ab1d2d14eb3 | 164 | minlru=USHRT_MAX; |
tylerwilson | 0:3ab1d2d14eb3 | 165 | while (sz>0) { |
tylerwilson | 0:3ab1d2d14eb3 | 166 | assert(sz<=pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 167 | assert((char*)hdr>=(char*)pool_base && (char*)hdr<(char*)pool_base+pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 168 | if (hdr->index==-1 && hdr->blocksize>=size) |
tylerwilson | 0:3ab1d2d14eb3 | 169 | break; |
tylerwilson | 0:3ab1d2d14eb3 | 170 | if (hdr->index!=-1 && hdr->lru<minlru) { |
tylerwilson | 0:3ab1d2d14eb3 | 171 | minlru=hdr->lru; |
tylerwilson | 0:3ab1d2d14eb3 | 172 | hdrlru=hdr; |
tylerwilson | 0:3ab1d2d14eb3 | 173 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 174 | sz-=hdr->blocksize+sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 175 | hdr=(ARENA*)((char*)hdr+hdr->blocksize+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 176 | } /* while */ |
tylerwilson | 0:3ab1d2d14eb3 | 177 | assert(sz<=pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 178 | if (sz==0) { |
tylerwilson | 0:3ab1d2d14eb3 | 179 | /* free up memory and try again */ |
tylerwilson | 0:3ab1d2d14eb3 | 180 | assert(hdrlru->index!=-1); |
tylerwilson | 0:3ab1d2d14eb3 | 181 | amx_poolfree((char*)hdrlru+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 182 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 183 | } while (sz==0); |
tylerwilson | 0:3ab1d2d14eb3 | 184 | |
tylerwilson | 0:3ab1d2d14eb3 | 185 | /* see whether to allocate the entire free block, or to cut it in two blocks */ |
tylerwilson | 0:3ab1d2d14eb3 | 186 | if (hdr->blocksize>size+MIN_BLOCKSIZE+sizeof(ARENA)) { |
tylerwilson | 0:3ab1d2d14eb3 | 187 | /* cut the block in two */ |
tylerwilson | 0:3ab1d2d14eb3 | 188 | ARENA *next=(ARENA*)((char*)hdr+size+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 189 | next->blocksize=hdr->blocksize-size-sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 190 | next->index=-1; |
tylerwilson | 0:3ab1d2d14eb3 | 191 | next->lru=0; |
tylerwilson | 0:3ab1d2d14eb3 | 192 | } else { |
tylerwilson | 0:3ab1d2d14eb3 | 193 | size=hdr->blocksize; |
tylerwilson | 0:3ab1d2d14eb3 | 194 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 195 | hdr->blocksize=size; |
tylerwilson | 0:3ab1d2d14eb3 | 196 | hdr->index=(short)index; |
tylerwilson | 0:3ab1d2d14eb3 | 197 | touchblock(hdr); /* set LRU field */ |
tylerwilson | 0:3ab1d2d14eb3 | 198 | |
tylerwilson | 0:3ab1d2d14eb3 | 199 | return (void*)((char*)hdr+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 200 | } |
tylerwilson | 0:3ab1d2d14eb3 | 201 | |
tylerwilson | 0:3ab1d2d14eb3 | 202 | /* amx_poolfind() returns the address of the memory block with the given index, |
tylerwilson | 0:3ab1d2d14eb3 | 203 | * or NULL if no such block exists. Parameter "index" should not be -1, because |
tylerwilson | 0:3ab1d2d14eb3 | 204 | * -1 represents a free block (actually, only positive values are valid). |
tylerwilson | 0:3ab1d2d14eb3 | 205 | * When amx_poolfind() finds the block, it increments its LRU count. |
tylerwilson | 0:3ab1d2d14eb3 | 206 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 207 | void *amx_poolfind(int index) |
tylerwilson | 0:3ab1d2d14eb3 | 208 | { |
tylerwilson | 0:3ab1d2d14eb3 | 209 | ARENA *hdr=findblock(index); |
tylerwilson | 0:3ab1d2d14eb3 | 210 | if (hdr==NULL) |
tylerwilson | 0:3ab1d2d14eb3 | 211 | return NULL; |
tylerwilson | 0:3ab1d2d14eb3 | 212 | touchblock(hdr); |
tylerwilson | 0:3ab1d2d14eb3 | 213 | return (void*)((char*)hdr+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 214 | } |
tylerwilson | 0:3ab1d2d14eb3 | 215 | |
tylerwilson | 0:3ab1d2d14eb3 | 216 | int amx_poolprotect(int index) |
tylerwilson | 0:3ab1d2d14eb3 | 217 | { |
tylerwilson | 0:3ab1d2d14eb3 | 218 | ARENA *hdr=findblock(index); |
tylerwilson | 0:3ab1d2d14eb3 | 219 | if (hdr==NULL) |
tylerwilson | 0:3ab1d2d14eb3 | 220 | return AMX_ERR_GENERAL; |
tylerwilson | 0:3ab1d2d14eb3 | 221 | hdr->lru=PROTECT_LRU; |
tylerwilson | 0:3ab1d2d14eb3 | 222 | return AMX_ERR_NONE; |
tylerwilson | 0:3ab1d2d14eb3 | 223 | } |
tylerwilson | 0:3ab1d2d14eb3 | 224 | |
tylerwilson | 0:3ab1d2d14eb3 | 225 | static ARENA *findblock(int index) |
tylerwilson | 0:3ab1d2d14eb3 | 226 | { |
tylerwilson | 0:3ab1d2d14eb3 | 227 | ARENA *hdr; |
tylerwilson | 0:3ab1d2d14eb3 | 228 | unsigned sz; |
tylerwilson | 0:3ab1d2d14eb3 | 229 | |
tylerwilson | 0:3ab1d2d14eb3 | 230 | assert(index>=0); |
tylerwilson | 0:3ab1d2d14eb3 | 231 | sz=pool_size; |
tylerwilson | 0:3ab1d2d14eb3 | 232 | hdr=(ARENA*)pool_base; |
tylerwilson | 0:3ab1d2d14eb3 | 233 | while (sz>0 && hdr->index!=index) { |
tylerwilson | 0:3ab1d2d14eb3 | 234 | assert(sz<=pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 235 | assert((char*)hdr>=(char*)pool_base && (char*)hdr<(char*)pool_base+pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 236 | sz-=hdr->blocksize+sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 237 | hdr=(ARENA*)((char*)hdr+hdr->blocksize+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 238 | } /* while */ |
tylerwilson | 0:3ab1d2d14eb3 | 239 | assert(sz<=pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 240 | return (sz>0 && hdr->index==index) ? hdr : NULL; |
tylerwilson | 0:3ab1d2d14eb3 | 241 | } |
tylerwilson | 0:3ab1d2d14eb3 | 242 | |
tylerwilson | 0:3ab1d2d14eb3 | 243 | static void touchblock(ARENA *hdr) |
tylerwilson | 0:3ab1d2d14eb3 | 244 | { |
tylerwilson | 0:3ab1d2d14eb3 | 245 | assert(hdr!=NULL); |
tylerwilson | 0:3ab1d2d14eb3 | 246 | if (++pool_lru >= PROTECT_LRU) |
tylerwilson | 0:3ab1d2d14eb3 | 247 | pool_lru=0; |
tylerwilson | 0:3ab1d2d14eb3 | 248 | hdr->lru=pool_lru; |
tylerwilson | 0:3ab1d2d14eb3 | 249 | |
tylerwilson | 0:3ab1d2d14eb3 | 250 | /* special case: if the overlay LRU count wrapped back to zero, set the |
tylerwilson | 0:3ab1d2d14eb3 | 251 | * LRU count of all blocks to zero, but set the count of the block just |
tylerwilson | 0:3ab1d2d14eb3 | 252 | * touched to 1 (skip blocks marked as protected, too) |
tylerwilson | 0:3ab1d2d14eb3 | 253 | */ |
tylerwilson | 0:3ab1d2d14eb3 | 254 | if (pool_lru==0) { |
tylerwilson | 0:3ab1d2d14eb3 | 255 | ARENA *hdr2; |
tylerwilson | 0:3ab1d2d14eb3 | 256 | unsigned sz=pool_size; |
tylerwilson | 0:3ab1d2d14eb3 | 257 | hdr2=(ARENA*)pool_base; |
tylerwilson | 0:3ab1d2d14eb3 | 258 | while (sz>0) { |
tylerwilson | 0:3ab1d2d14eb3 | 259 | assert(sz<=pool_size); |
tylerwilson | 0:3ab1d2d14eb3 | 260 | if (hdr2->lru!=PROTECT_LRU) |
tylerwilson | 0:3ab1d2d14eb3 | 261 | hdr2->lru=0; |
tylerwilson | 0:3ab1d2d14eb3 | 262 | sz-=hdr2->blocksize+sizeof(ARENA); |
tylerwilson | 0:3ab1d2d14eb3 | 263 | hdr2=(ARENA*)((char*)hdr2+hdr2->blocksize+sizeof(ARENA)); |
tylerwilson | 0:3ab1d2d14eb3 | 264 | } /* while */ |
tylerwilson | 0:3ab1d2d14eb3 | 265 | assert(sz==0); |
tylerwilson | 0:3ab1d2d14eb3 | 266 | hdr->lru=++pool_lru; |
tylerwilson | 0:3ab1d2d14eb3 | 267 | } /* if */ |
tylerwilson | 0:3ab1d2d14eb3 | 268 | } |