summaryrefslogtreecommitdiff
path: root/firmware/test/memory/memory-page.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/test/memory/memory-page.c')
-rw-r--r--firmware/test/memory/memory-page.c209
1 files changed, 96 insertions, 113 deletions
diff --git a/firmware/test/memory/memory-page.c b/firmware/test/memory/memory-page.c
index a9b9707fd9..1327cf57c9 100644
--- a/firmware/test/memory/memory-page.c
+++ b/firmware/test/memory/memory-page.c
@@ -16,86 +16,70 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#ifndef __LIBRARY_MEMORY_C__ 19#include <memory.h>
20# error "This header file must be included ONLY from memory.c." 20#include "memory-page.h"
21#if 0
22#include "memory-slab.h"
21#endif 23#endif
22#ifndef __LIBRARY_MEMORY_PAGE_H__
23# define __LIBRARY_MEMORY_PAGE_H__
24
25struct memory_free_page
26 {
27 struct memory_free_page
28 *less,*more;
29 char
30 reserved[MEMORY_PAGE_MINIMAL_SIZE - 2*sizeof (struct memory_free_page *)];
31 };
32
33#define LESS -1
34#define MORE +1
35 24
36#ifdef TEST 25#ifdef TEST
37 26
38struct memory_free_page free_page[MEMORY_TOTAL_PAGES];
39
40static inline unsigned int get_offset (int order)
41 {
42 return (2 << order);
43 }
44
45// IA32 has no problem with shift operation 27// IA32 has no problem with shift operation
46static inline unsigned int get_size (int order) 28static inline unsigned int __memory_get_size (int order)
47 { 29 {
48 return (MEMORY_PAGE_MINIMAL_SIZE << order); 30 return (MEMORY_PAGE_MINIMAL_SIZE << order);
49 } 31 }
50 32
51// Arghhhh ! I cannot align 'free_page' on 512-byte boundary (max is 16-byte for Cygwin) 33// Arghhhh ! I cannot align 'free_page' on 512-byte boundary (max is 16-byte for Cygwin)
52static inline struct memory_free_page *get_neighbour (struct memory_free_page *node,unsigned int size) 34static inline struct memory_free_page *__memory_get_neighbour (struct memory_free_page *node,unsigned int size)
53 { 35 {
54 return ((struct memory_free_page *)((unsigned)free_page + (((unsigned)node - (unsigned)free_page) ^ size))); 36 return ((struct memory_free_page *)((unsigned)__memory_free_page + (((unsigned)node - (unsigned)__memory_free_page) ^ size)));
55 } 37 }
56 38
57#else 39#else
58 40
59extern struct memory_free_page free_page[MEMORY_TOTAL_PAGES] asm("dram");
60
61static inline unsigned int get_offset (int order)
62 {
63 static unsigned short offset [MEMORY_TOTAL_ORDERS] =
64 { 2,4,8,16,32,64,128,256,512,1024,2048,4096,8192 };
65 return offset[order];
66 }
67
68// SH1 has very poor shift instructions (only <<1,>>1,<<2,>>2,<<8,>>8,<<16 and >>16). 41// SH1 has very poor shift instructions (only <<1,>>1,<<2,>>2,<<8,>>8,<<16 and >>16).
69// so we should use a lookup table to speedup. 42// so we should use a lookup table to speedup.
70static inline unsigned int get_size (int order) 43static inline unsigned int __memory_get_size (int order)
71 { 44 {
72 return (get_offset (order))<<8; 45 static unsigned short size [MEMORY_TOTAL_ORDERS] =
46 {
47 1<<MEMORY_PAGE_MINIMAL_ORDER,
48 2<<MEMORY_PAGE_MINIMAL_ORDER,
49 4<<MEMORY_PAGE_MINIMAL_ORDER,
50 8<<MEMORY_PAGE_MINIMAL_ORDER,
51 16<<MEMORY_PAGE_MINIMAL_ORDER,
52 32<<MEMORY_PAGE_MINIMAL_ORDER,
53 64<<MEMORY_PAGE_MINIMAL_ORDER,
54 128<<MEMORY_PAGE_MINIMAL_ORDER,
55 256<<MEMORY_PAGE_MINIMAL_ORDER,
56 512<<MEMORY_PAGE_MINIMAL_ORDER,
57 1024<<MEMORY_PAGE_MINIMAL_ORDER,
58 2048<<MEMORY_PAGE_MINIMAL_ORDER,
59 4096<<MEMORY_PAGE_MINIMAL_ORDER
60 };
61 return size[order];
73 } 62 }
74 63
75static inline struct memory_free_page *get_neighbour (struct memory_free_page *node,unsigned int size) 64static inline struct memory_free_page *__memory_get_neighbour (struct memory_free_page *node,unsigned int size)
76 { 65 {
77 return ((struct memory_free_page *)((unsigned)node ^ size)); 66 return ((struct memory_free_page *)((unsigned)node ^ size));
78 } 67 }
79 68
80#endif 69#endif
81 70
82static char free_page_order[MEMORY_TOTAL_PAGES]; 71static inline int __memory_get_order (struct memory_free_page *node)
83static struct memory_free_page *free_page_bin[MEMORY_TOTAL_ORDERS];
84
85static inline int get_order (struct memory_free_page *node)
86 { 72 {
87 return free_page_order[node - free_page]; 73 return __memory_free_page_order[node - __memory_free_page];
88 } 74 }
89static inline void set_order (struct memory_free_page *node,int order) 75static inline void __memory_set_order (struct memory_free_page *node,int order)
90 { 76 {
91 free_page_order[node - free_page] = order; 77 __memory_free_page_order[node - __memory_free_page] = order;
92 } 78 }
93 79
94#if MEMORY_PAGE_USE_SPLAY_TREE 80#if MEMORY_PAGE_USE_SPLAY_TREE
95 81
96# include <stdio.h> 82static struct memory_free_page *__memory_splay_page (struct memory_free_page *root,struct memory_free_page *node)
97
98static struct memory_free_page *splay_page (struct memory_free_page *root,struct memory_free_page *node)
99 { 83 {
100 struct memory_free_page *down; 84 struct memory_free_page *down;
101 struct memory_free_page *less; 85 struct memory_free_page *less;
@@ -153,15 +137,15 @@ static struct memory_free_page *splay_page (struct memory_free_page *root,struct
153 return root; 137 return root;
154 } 138 }
155 139
156static inline void insert_page (int order,struct memory_free_page *node) 140static inline void __memory_insert_page (int order,struct memory_free_page *node)
157 { 141 {
158 struct memory_free_page *root = free_page_bin[order]; 142 struct memory_free_page *root = __memory_free_page_bin[order];
159 if (!root) 143 if (!root)
160 { 144 {
161 node->less = 145 node->less =
162 node->more = 0; 146 node->more = 0;
163 } 147 }
164 else if (node < (root = splay_page (root,node))) 148 else if (node < (root = __memory_splay_page (root,node)))
165 { 149 {
166 node->less = root->less; 150 node->less = root->less;
167 node->more = root; 151 node->more = root;
@@ -173,91 +157,91 @@ static inline void insert_page (int order,struct memory_free_page *node)
173 node->more = root->more; 157 node->more = root->more;
174 node->more = 0; 158 node->more = 0;
175 } 159 }
176 free_page_bin[order] = node; 160 __memory_free_page_bin[order] = node;
177 set_order (node,order); 161 __memory_set_order (node,order);
178 return; 162 return;
179 } 163 }
180 164
181static inline struct memory_free_page *pop_page (int order,int want) 165static inline struct memory_free_page *__memory_pop_page (int order,int want)
182 { 166 {
183 struct memory_free_page *root = free_page_bin[order]; 167 struct memory_free_page *root = __memory_free_page_bin[order];
184 if (root) 168 if (root)
185 { 169 {
186 root = splay_page (root,free_page); 170 root = __memory_splay_page (root,__memory_free_page);
187 free_page_bin[order] = root->more; 171 __memory_free_page_bin[order] = root->more;
188 set_order (root,~want); 172 __memory_set_order (root,~want);
189 } 173 }
190 return root; 174 return root;
191 } 175 }
192 176
193static inline void remove_page (int order,struct memory_free_page *node) 177static inline void __memory_remove_page (int order,struct memory_free_page *node)
194 { 178 {
195 struct memory_free_page *root = free_page_bin[order]; 179 struct memory_free_page *root = __memory_free_page_bin[order];
196 root = splay_page (root,node); 180 root = __memory_splay_page (root,node);
197 if (root->less) 181 if (root->less)
198 { 182 {
199 node = splay_page (root->less,node); 183 node = __memory_splay_page (root->less,node);
200 node->more = root->more; 184 node->more = root->more;
201 } 185 }
202 else 186 else
203 node = root->more; 187 node = root->more;
204 free_page_bin[order] = node; 188 __memory_free_page_bin[order] = node;
205 } 189 }
206 190
207#else 191#else
208 192
209static inline void insert_page (int order,struct memory_free_page *node) 193static inline void __memory_insert_page (int order,struct memory_free_page *node)
210 { 194 {
211 struct memory_free_page *head = free_page_bin[order]; 195 struct memory_free_page *head = __memory_free_page_bin[order];
212 node->less = 0; 196 node->less = 0;
213 node->more = head; 197 node->more = head;
214 if (head) 198 if (head)
215 head->less = node; 199 head->less = node;
216 free_page_bin[order] = node; 200 __memory_free_page_bin[order] = node;
217 set_order (node,order); 201 __memory_set_order (node,order);
218 } 202 }
219 203
220static inline struct memory_free_page *pop_page (int order,int want) 204static inline struct memory_free_page *pop_page (int order,int want)
221 { 205 {
222 struct memory_free_page *node = free_page_bin[order]; 206 struct memory_free_page *node = __memory_free_page_bin[order];
223 if (node) 207 if (node)
224 { 208 {
225 free_page_bin[order] = node->more; 209 __memory_free_page_bin[order] = node->more;
226 if (node->more) 210 if (node->more)
227 node->more->less = 0; 211 node->more->less = 0;
228 set_order (node,~want); 212 __memory_set_order (node,~want);
229 } 213 }
230 return node; 214 return node;
231 } 215 }
232 216
233static inline void remove_page (int order,struct memory_free_page *node) 217static inline void __memory_remove_page (int order,struct memory_free_page *node)
234 { 218 {
235 if (node->less) 219 if (node->less)
236 node->less->more = node->more; 220 node->less->more = node->more;
237 else 221 else
238 free_page_bin[order] = node->more; 222 __memory_free_page_bin[order] = node->more;
239 if (node->more) 223 if (node->more)
240 node->more->less = node->less; 224 node->more->less = node->less;
241 } 225 }
242 226
243#endif 227#endif
244 228
245static inline void push_page (int order,struct memory_free_page *node) 229static inline void __memory_push_page (int order,struct memory_free_page *node)
246 { 230 {
247 node->less = 0; 231 node->less = 0;
248 node->more = 0; 232 node->more = 0;
249 free_page_bin[order] = node; 233 __memory_free_page_bin[order] = node;
250 set_order (node,order); 234 __memory_set_order (node,order);
251 } 235 }
252 236
253static struct memory_free_page *allocate_page (unsigned int size,int order) 237static struct memory_free_page *__memory_allocate_page (unsigned int size,int order)
254 { 238 {
255 struct memory_free_page *node; 239 struct memory_free_page *node;
256 int min = order; 240 int min = order;
257 while ((unsigned)order <= (MEMORY_TOTAL_ORDERS - 1)) 241 while ((unsigned)order <= (MEMORY_TOTAL_ORDERS - 1))
258 // order is valid ? 242 // order is valid ?
259 { 243 {
260 if (!(node = pop_page (order,min))) 244 if (!(node = __memory_pop_page (order,min)))
261 // no free page of this order ? 245 // no free page of this order ?
262 { 246 {
263 ++order; size <<= 1; 247 ++order; size <<= 1;
@@ -267,39 +251,39 @@ static struct memory_free_page *allocate_page (unsigned int size,int order)
267 // split our larger page in smaller pages 251 // split our larger page in smaller pages
268 { 252 {
269 --order; size >>= 1; 253 --order; size >>= 1;
270 push_page (order,(struct memory_free_page *)((unsigned int)node + size)); 254 __memory_push_page (order,(struct memory_free_page *)((unsigned int)node + size));
271 } 255 }
272 return node; 256 return node;
273 } 257 }
274 return MEMORY_RETURN_FAILURE; 258 return MEMORY_RETURN_FAILURE;
275 } 259 }
276 260
277static inline void release_page (struct memory_free_page *node,unsigned int size,int order) 261static inline void __memory_release_page (struct memory_free_page *node,unsigned int size,int order)
278 { 262 {
279 struct memory_free_page *neighbour; 263 struct memory_free_page *neighbour;
280 while ((order <= (MEMORY_TOTAL_ORDERS - 1)) && 264 while ((order <= (MEMORY_TOTAL_ORDERS - 1)) &&
281 ((neighbour = get_neighbour (node,size)), 265 ((neighbour = __memory_get_neighbour (node,size)),
282 (get_order (neighbour) == order))) 266 (__memory_get_order (neighbour) == order)))
283 // merge our released page with its contiguous page into a larger page 267 // merge our released page with its contiguous page into a larger page
284 { 268 {
285 remove_page (order,neighbour); 269 __memory_remove_page (order,neighbour);
286 ++order; size <<= 1; 270 ++order; size <<= 1;
287 if (neighbour < node) 271 if (neighbour < node)
288 node = neighbour; 272 node = neighbour;
289 } 273 }
290 insert_page (order,node); 274 __memory_insert_page (order,node);
291 } 275 }
292 276
293 277
294/*****************************************************************************/ 278/*****************************************************************************/
295/* PUBLIC FUNCTIONS */ 279/* PUBLIC FUNCTIONS */
296/*****************************************************************************/ 280/*****************************************************************************/
297 281
298void *memory_allocate_page (int order) 282void *memory_allocate_page (int order)
299 { 283 {
300 if (order < 0) 284 if (order < 0)
301 return MEMORY_RETURN_FAILURE; 285 return MEMORY_RETURN_FAILURE;
302 return allocate_page (get_size (order),order); 286 return __memory_allocate_page (__memory_get_size (order),order);
303 } 287 }
304 288
305// release a page : 289// release a page :
@@ -309,10 +293,10 @@ void *memory_allocate_page (int order)
309int memory_release_page (void *address) 293int memory_release_page (void *address)
310 { 294 {
311 struct memory_free_page *node = (struct memory_free_page *)address; 295 struct memory_free_page *node = (struct memory_free_page *)address;
312 int order = ~get_order (node); 296 int order = ~__memory_get_order (node);
313 if (order < 0) 297 if (order < 0)
314 return MEMORY_RETURN_FAILURE; 298 return MEMORY_RETURN_FAILURE;
315 release_page (node,get_size (order),order); 299 __memory_release_page (node,__memory_get_size (order),order);
316 return MEMORY_RETURN_SUCCESS; 300 return MEMORY_RETURN_SUCCESS;
317 } 301 }
318 302
@@ -322,58 +306,58 @@ int memory_release_page (void *address)
322# include <stdlib.h> 306# include <stdlib.h>
323# if MEMORY_PAGE_USE_SPLAY_TREE 307# if MEMORY_PAGE_USE_SPLAY_TREE
324 308
325static void dump_splay_node (struct memory_free_page *node,int level) 309void __memory_dump_splay_node (struct memory_free_page *node,int level)
326 { 310 {
327 if (!node) 311 if (!node)
328 return; 312 return;
329 dump_splay_node (node->less,level+1); 313 __memory_dump_splay_node (node->less,level+1);
330 printf ("\n%*s[%d-%d]",level,"",(node - free_page),(node - free_page) + (1 << get_order (node)) - 1); 314 printf ("\n%*s[%d-%d]",level,"",(node - __memory_free_page),(node - __memory_free_page) + (1 << __memory_get_order (node)) - 1);
331 dump_splay_node (node->more,level+1); 315 __memory_dump_splay_node (node->more,level+1);
332 } 316 }
333 317
334static void dump_splay_tree (struct memory_free_page *root) 318void __memory_dump_splay_tree (struct memory_free_page *root)
335 { 319 {
336 dump_splay_node (root,2); fflush (stdout); 320 __memory_dump_splay_node (root,2); fflush (stdout);
337 } 321 }
338 322
339# endif 323# endif
340 324
341void memory_spy_page (void *address) 325void __memory_spy_page (void *address)
342 { 326 {
343 struct memory_free_page *node = (struct memory_free_page *)address; 327 struct memory_free_page *node = (struct memory_free_page *)address;
344 int order,used; 328 int order,used;
345 if (node) 329 if (node)
346 { 330 {
347 order = get_order (node); 331 order = __memory_get_order (node);
348 used = order < 0; 332 used = order < 0;
349 if (used) 333 if (used)
350 order = ~order; 334 order = ~order;
351 printf("\n(%s,%2d,%7d)",(used ? "used" : "free"),order,get_size (order)); 335 printf("\n(%s,%2d,%7d)",(used ? "used" : "free"),order,__memory_get_size (order));
352 } 336 }
353 } 337 }
354 338
355void memory_dump (int order) 339void __memory_dump (int order)
356 { 340 {
357 struct memory_free_page *node = free_page_bin[order]; 341 struct memory_free_page *node = __memory_free_page_bin[order];
358 printf("\n(%s,%2d,%7d)",node ? "free" : "none",order,get_size (order)); 342 printf("\n(%s,%2d,%7d)",node ? "free" : "none",order,__memory_get_size (order));
359# if MEMORY_PAGE_USE_SPLAY_TREE 343# if MEMORY_PAGE_USE_SPLAY_TREE
360 dump_splay_tree (node); 344 __memory_dump_splay_tree (node);
361# else 345# else
362 while (node) 346 while (node)
363 { 347 {
364 printf("[%d-%d]",(node - free_page),(node - free_page) + (1<<order) - 1); 348 printf("[%d-%d]",(node - __memory_free_page),(node - __memory_free_page) + (1<<order) - 1);
365 node = node->more; 349 node = node->more;
366 } 350 }
367# endif 351# endif
368 352
369 } 353 }
370 354
371void memory_check (int order) 355void __memory_check (int order)
372 { 356 {
373 struct memory_free_page *node[4096],*swap; 357 struct memory_free_page *node[4096],*swap;
374 unsigned int i = 0,j = 0; 358 unsigned int i = 0,j = 0;
375 while (i <= 12) 359 while (i <= 12)
376 memory_dump (i++); 360 __memory_dump (i++);
377 i = 0; 361 i = 0;
378 printf ("\nallocating...\n"); 362 printf ("\nallocating...\n");
379 while (order >= 0) 363 while (order >= 0)
@@ -382,31 +366,31 @@ void memory_check (int order)
382 while ((swap = memory_allocate_page (j))) 366 while ((swap = memory_allocate_page (j)))
383 { 367 {
384 node[i++] = swap; 368 node[i++] = swap;
385 printf("[%d-%d]",(swap - free_page),(swap - free_page) + ((1 << j)-1)); 369 printf("[%d-%d]",(swap - __memory_free_page),(swap - __memory_free_page) + ((1 << j)-1));
386 for (j += (rand () & 15); j > (unsigned int)order; j -= order); 370 for (j += (rand () & 15); j > (unsigned int)order; j -= order);
387 } 371 }
388 --order; 372 --order;
389 } 373 }
390 node[i] = 0; 374 node[i] = 0;
391 while (j <= 12) 375 while (j <= 12)
392 memory_dump (j++); 376 __memory_dump (j++);
393 j = 0; 377 j = 0;
394 printf ("\nreleasing..."); 378 printf ("\nreleasing...");
395 --i; 379 --i;
396 while (i > 0) 380 while (i > 0)
397 { 381 {
398 unsigned int k = 0; 382 unsigned int k = 0;
399#if 0 383# if 0
400 printf ("\n"); 384 printf ("\n");
401#endif 385# endif
402 swap = node[k++]; 386 swap = node[k++];
403#if 0 387# if 0
404 while (swap) 388 while (swap)
405 { 389 {
406 printf("[%d-%d]",(swap - free_page),(swap - free_page) + ((1 << ~get_order (swap))-1)); 390 printf("[%d-%d]",(swap - __memory_free_page),(swap - __memory_free_page) + ((1 << ~__memory_get_order (swap))-1));
407 swap = node[k++]; 391 swap = node[k++];
408 } 392 }
409#endif 393# endif
410 for (j += 1 + (rand () & 15); j >= i; j -= i); 394 for (j += 1 + (rand () & 15); j >= i; j -= i);
411 swap = node[j]; 395 swap = node[j];
412 node[j] = node[i]; 396 node[j] = node[i];
@@ -417,9 +401,8 @@ void memory_check (int order)
417 memory_release_page (node[0]); 401 memory_release_page (node[0]);
418 i = 0; 402 i = 0;
419 while (i <= 12) 403 while (i <= 12)
420 memory_dump (i++); 404 __memory_dump (i++);
421 printf("\n\n%s !",(get_order (free_page) == 12) ? "SUCCESS" : "FAILURE"); 405 printf("\n\n%s !",(__memory_get_order (__memory_free_page) == 12) ? "SUCCESS" : "FAILURE");
422 } 406 }
423 407
424#endif 408#endif
425#endif