1 /******************************************************************************
2 *
3 * Copyright (C) 2006-08, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexey Krivonogov
11 *
12 ******************************************************************************/
13
14 /*-----------------------------------------------------------------------------
15 * Id: memory L "Memory"
16 *
17 * Desc: Functions for memory management.
18 * Summary: Gentee has own memory manager. This overview describes the memory
19 management provided by Gentee. You can allocate and use memory with
20 these functions.
21 *
22 * List: *, malloc, mcmp, mcopy, mfree, mlen, mmove, mzero
23 *
24 -----------------------------------------------------------------------------*/
25
26 #include "../os/user/defines.h"
27 #include "memory.h"
28
29 memory _memory;
30 pubyte _lower;
31 pubyte _bin;
32 pubyte _hex;
33 pubyte _dec;
34 pubyte _name;
35 OS_CRL _crlmem; // Critical section for multi-thread calling
36
37 //uint memnum = 0;
38 //uint bufnum = 0;
39
40 /*--------------------------------------------------------------------------
41 *
42 * Locale functions
43 *
44 */
45
46 uint STDCALL _mem_heapalloc( uint id )
47 {
48 uint size;
49 pheap p_heap;
50
51 size = ( MEM_HEAPSIZE << ( id >> 5 ));
52
53 p_heap = _memory.heaps + id;
54
55 p_heap->ptr = os_alloc( size + MAX_BYTE * sizeof( uint ));
56 // p_heap->ptr = VirtualAlloc( NULL, size + MAX_BYTE * sizeof( uint ),
57 // MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
58 if ( !p_heap->ptr )
59 return FALSE;
60 p_heap->chain = p_heap->ptr;
61 p_heap->size = size;
62 p_heap->remain = size;
63 p_heap->free = 0;
64 mem_zeroui( p_heap->chain, MAX_BYTE );
65
66 // printf(".\n");
67 return TRUE;
68 }
69
70 //--------------------------------------------------------------------------
71
72 uint STDCALL _mem_heapfree( uint id )
73 {
74 pheap p_heap;
75
76 p_heap = _memory.heaps + id;
77 if ( p_heap->ptr )
78 // VirtualFree( p_heap->ptr, 0, MEM_RELEASE );
79 os_free( p_heap->ptr );
80 p_heap->ptr = 0;
81
82 return TRUE;
83 }
84
85 //--------------------------------------------------------------------------
86
87 uint STDCALL _mem_size2sid( uint size )
88 {
89 uint middle, right = 255;
90 uint left = 0;
91
92 while ( right > left )
93 {
94 middle = ( right + left ) >> 1;
95 if ( size > _memory.sid[ middle ] )
96 left = middle + 1;
97 else
98 right = middle;
99 }
100 return left;
101 }
102
103 /*-----------------------------------------------------------------------------
104 * Id: malloc F
105 *
106 * Summary: Allocate the memory. The function allocates the memory of the
107 specified size.
108 *
109 * Params: size - The size of memory space to be allocated.
110 *
111 * Return: The pointer to the allocated memory space or 0 in case of an error.
112 *
113 * Define: func uint malloc( uint size )
114 *
115 -----------------------------------------------------------------------------*/
116
117 pvoid STDCALL mem_alloc( uint size )
118 {
119 uint sid, ih;
120 pvoid result = 0;
121 pheap p_heap;
122
123 os_crlsection_enter( &_crlmem );
124 // memnum++;
125 if ( size > MEM_EDGE )
126 {
127 result = ( pubyte )os_alloc( size + 8 ) + 2;
128 *(( pubyte )result + 5 ) = MAX_BYTE;
129 *( puint )result = size;
130 result = ( pubyte )result + 6;
131 goto end;
132 }
133 sid = _mem_size2sid( size );
134
135 ih = _memory.last;
136 size = _memory.sid[ sid ] + 2;
137
138 again:
139 p_heap = _memory.heaps + ih;
140 if ( !p_heap->ptr && !_mem_heapalloc( ih ))
141 {
142 result = 0;
143 goto end;
144 }
145 if ( p_heap->chain[ sid ] )
146 {
147 p_heap->free -= size;
148 result = ( pvoid )p_heap->chain[ sid ];
149 p_heap->chain[ sid ] = *( puint )result;
150 }
151 else
152 {
153 if ( size <= p_heap->remain )
154 {
155 result = ( pubyte )p_heap->ptr + MAX_BYTE * sizeof( uint ) +
156 p_heap->size - p_heap->remain;
157 *(( pubyte )result)++ = ( byte )ih;
158 *(( pubyte )result)++ = ( byte )sid;
159 p_heap->remain -= size;
160 }
161 else
162 {
163 if ( _memory.last )
164 {
165 _memory.last = 0;
166 ih = 0;
167 }
168 else
169 ih++;
170 goto again;
171 }
172 }
173 _memory.last = ih;
174
175 end:
176 os_crlsection_leave( &_crlmem );
177
178 return result;
179 }
180
181 //--------------------------------------------------------------------------
182
183 pvoid STDCALL mem_allocz( uint size )
184 {
185 pvoid result = NULL;
186
187 result = mem_alloc( size );
188 if ( result )
189 mem_zero( result, size );
190
191 return result;
192 }
193
194 /*-----------------------------------------------------------------------------
195 * Id: mcopy F
196 *
197 * Summary: Copying memory. The function copies data from one memory space
198 into another.
199 *
200 * Params: dest - The pointer for the data being copied.
201 src - The pointer to the source of the data being copied.
202 len - The size of the data being copied.
203 *
204 * Return: The pointer to the copied data.
205 *
206 * Define: func uint mcopy( uint dest, uint src, uint len )
207 *
208 -----------------------------------------------------------------------------*/
209
210 pvoid STDCALL mem_copy( pvoid dest, pvoid src, uint len )
211 {
212 puint psrc = ( puint )src;
213 puint pdest = ( puint )dest;
214 uint ilen = len >> 2;
215
216 while ( ilen-- )
217 *pdest++ = *psrc++;
218
219 len &= 0x3;
220 while ( len-- )
221 *((pubyte)pdest)++ = *((pubyte)psrc)++;
222
223 return dest;
224 }
225
226 //--------------------------------------------------------------------------
227
228 uint STDCALL mem_deinit( void )
229 {
230 uint i;
231
232 mem_free( _lower );
233
234 for ( i = 0; i <= MAX_BYTE; i++ )
235 _mem_heapfree( i );
236
237 os_free( _memory.sid );
238 os_free( _memory.heaps );
239
240 os_crlsection_delete( &_crlmem );
241
242 return TRUE;
243 }
244
245 /*-----------------------------------------------------------------------------
246 * Id: mfree F
247 *
248 * Summary: Memory deallocation. The function deallocates memory.
249 *
250 * Params: ptr - The pointer to the memory space to be deallocated.
251 *
252 * Return: #lng/retf#
253 *
254 * Define: func uint mfree( uint ptr )
255 *
256 -----------------------------------------------------------------------------*/
257
258 uint STDCALL mem_free( pvoid ptr )
259 {
260 pubyte p_id;
261 uint sid;
262 pheap p_heap;
263
264 if ( !ptr ) return TRUE;
265
266 // memnum--;
267 os_crlsection_enter( &_crlmem );
268
269 sid = *(( pubyte )ptr - 1 );
270 p_id = ( pubyte )ptr - 2;
271
272 if ( sid == MAX_BYTE )
273 {
274 os_free( ( pubyte )ptr - 8 );
275 goto end;
276 }
277 p_heap = _memory.heaps + *p_id;
278 *( puint )ptr = p_heap->chain[ sid ];
279 p_heap->chain[ sid ] = ( uint )ptr;
280
281 p_heap->free += _memory.sid[ sid ] + 2;
282
283 if ( p_heap->free + p_heap->remain == p_heap->size )
284 _mem_heapfree( *p_id );
285
286 end:
287 os_crlsection_leave( &_crlmem );
288
289 return TRUE;
290 }
291
292 //--------------------------------------------------------------------------
293
294 uint STDCALL mem_getsize( pvoid ptr )
295 {
296 uint sid;
297
298 if (( sid = *((pubyte)ptr - 1 )) == MAX_BYTE )
299 return *( puint )((pubyte)ptr - 6 );
300 return _memory.sid[ sid ];
301 }
302
303 //--------------------------------------------------------------------------
304
305 uint STDCALL mem_init( void )
306 {
307 uint i, size, step = 8;
308
309 _memory.sid = os_alloc(( MAX_BYTE + 1 ) * sizeof( uint ));
310 _memory.sid[ 0 ] = step;
311 for ( i = 1; i < MAX_BYTE - 1; i++ )
312 {
313 if ( !( i & 0xF ))
314 step <<= 1;
315 _memory.sid[ i ] = _memory.sid[ i - 1 ] + step;
316 }
317 _memory.sid[ MAX_BYTE ] = MAX_UINT;
318
319 _memory.heaps = os_alloc( size = ( MAX_BYTE + 1 ) * sizeof( heap ));
320 mem_zero( _memory.heaps, size );
321
322 os_crlsection_init( &_crlmem );
323 _memory.last = 0;
324
325 _lower = mem_alloc( ABC_COUNT * 5 );
326 _bin = _lower + ABC_COUNT;
327 _dec = _bin + ABC_COUNT;
328 _hex = _dec + ABC_COUNT;
329 _name = _hex + ABC_COUNT;
330
331 for ( i = 0; i < ABC_COUNT; i++ )
332 {
333 _lower[i] = ( ubyte )os_lower( ( pubyte )i );
334 _bin[i] = 0xFF;
335 if ( i >= '0' && i <= '9' )
336 _name[i] = 1;
337 else
338 if ( i >= 0x80 || ( i >= 'A' && i <= 'Z' ) || ( i >= 'a' && i <= 'z' ) ||
339 i == '_' )
340 _name[i] = 2;
341 else
342 _name[i] = 0;
343 }
344 _bin[ '0' ] = 0;
345 _bin[ '1' ] = 1;
346
347 for ( i = 0; i < ABC_COUNT; i++ )
348 if ( i > '1' && i <= '9' )
349 _dec[i] = (ubyte)( 1 + i - '1' );
350 else
351 _dec[i] = _bin[i];
352
353 for ( i = 0; i < ABC_COUNT; i++ )
354 if ( _lower[i] >= 'a' && _lower[i] <= 'f' )
355 _hex[i] = 10 + _lower[i] - 'a';
356 else
357 _hex[i] = _dec[i];
358
359 return TRUE;
360 }
361
362 /*-----------------------------------------------------------------------------
363 * Id: mlen F
364 *
365 * Summary: Size till zero. Determines the number of bytes till zero.
366 *
367 * Params: data - The pointer to a memory space.
368 *
369 * Return: The number of bytes till the zero character.
370 *
371 * Define: func uint mlen( uint data )
372 *
373 -----------------------------------------------------------------------------*/
374
375 uint STDCALL mem_len( pvoid data )
376 {
377 pubyte temp = ( pubyte )data;
378
379 while ( *temp++ );
380
381 return ( uint )( temp - ( pubyte )data - 1 );
382 }
383
384 //--------------------------------------------------------------------------
385
386 uint STDCALL mem_lensh( pvoid data )
387 {
388 pushort temp = ( pushort )data;
389
390 while ( *temp++ );
391
392 return ( uint )( temp - ( pushort )data - 1 );
393 }
394
395 /*-----------------------------------------------------------------------------
396 * Id: mmove F
397 *
398 * Summary: Move memory. The function moves the specified space. The initial and
399 final data may overlap.
400 *
401 * Params: dest - The pointer for the data being copied.
402 src - The pointer to the source of the data being copied.
403 len - The size of the data being copied.
404 *
405 * Define: func mmove( uint dest, uint src, uint len )
406 *
407 -----------------------------------------------------------------------------*/
408
409 void STDCALL mem_move( pvoid dest, pvoid src, uint len )
410 {
411 puint psrc;
412 puint pdest;
413 uint ilen;
414
415 if ( ( pubyte )dest <= ( pubyte )src ||
416 ( pubyte )dest >= ( pubyte )src + len )
417 mem_copy( dest, src, len );
418 else
419 {
420 ilen = len >> 2;
421 // области памяти пересекаются и надо копировать с конца
422 pdest = ( puint )( ( pubyte )dest + len - sizeof( uint ));
423 psrc = ( puint )(( pubyte )src + len - sizeof( uint ));
424 while ( ilen-- )
425 *pdest-- = *psrc--;
426
427 len &= 0x3;
428 while ( len-- )
429 *( ( pubyte )dest + len ) = *( ( pubyte )src + len );
430 }
431 }
432
433 /*-----------------------------------------------------------------------------
434 * Id: mzero F
435 *
436 * Summary: Filling memory with zeros. The functions zeroes the memory space.
437 *
438 * Params: dest - The pointer to a memory space.
439 len - The size of the data being zeroed.
440 *
441 * Return: The pointer to the zeroed data.
442 *
443 * Define: func uint mzero( uint dest, uint len )
444 *
445 -----------------------------------------------------------------------------*/
446
447 pvoid STDCALL mem_zero( pvoid dest, uint len )
448 {
449 puint p_dest = ( puint )dest;
450 uint ilen = len >> 2;
451
452 while ( ilen-- )
453 *p_dest++ = 0;
454
455 len &= 0x3;
456 while ( len-- )
457 *((pubyte)p_dest)++ = 0;
458
459 return dest;
460 }
461
462 /*-----------------------------------------------------------------------------
463 ** Id: mcmp F
464 *
465 * Summary: Comparison memory. The function compares two memory spaces.
466 *
467 * Params: dest - The pointer to the first memory space.
468 src - The pointer to the second memory space.
469 len - The size being compared.
470 *
471 * Return: #tblparam[0|The spaces are equal.$#
472 <0|The first space is smaller.$#
473 >0|The second space is smaller.]
474 *
475 * Define: func int mcmp( uint dest, uint src, uint len )
476 *
477 -----------------------------------------------------------------------------*/
478
479 int STDCALL mem_cmp( pvoid dest, pvoid src, uint len )
480 {
481 puint dsrc = ( puint )src;
482 puint ddest = ( puint )dest;
483 uint ilen = len >> 2;
484 int i;
485
486 while ( ilen-- )
487 if ( *ddest++ != *dsrc++ )
488 {
489 ddest--;
490 dsrc--;
491 for ( i = 0; i < 4; i++ )
492 {
493 if ( *((pubyte)ddest) > *((pubyte)dsrc) )
494 return 1;
495 if ( *((pubyte)ddest)++ < *((pubyte)dsrc)++ )
496 return -1;
497 }
498 }
499
500 len &= 0x3;
501 while ( len-- )
502 {
503 if ( *((pubyte)ddest) > *((pubyte)dsrc) )
504 return 1;
505 if ( *((pubyte)ddest)++ < *((pubyte)dsrc)++ )
506 return -1;
507 }
508
509 return 0;
510 }
511
512 //--------------------------------------------------------------------------
513
514 int STDCALL mem_cmpign( pvoid dest, pvoid src, uint len )
515 {
516 pubyte psrc = ( pubyte )src;
517 pubyte pdest = ( pubyte )dest;
518
519 while ( len-- )
520 {
521 if ( _lower[ *pdest++ ] != _lower[ *psrc++ ] )
522 {
523 return *--pdest > *--psrc ? 1 : -1;
524 }
525 }
526 return 0;
527 }
528
529 //--------------------------------------------------------------------------
530
531 uint STDCALL mem_iseqzero( pvoid dest, pvoid src )
532 {
533 uint len = mem_len( dest );
534
535 return !mem_cmp( dest, src, len ) &&
536 (( pubyte )dest)[ len ] == (( pubyte )src)[ len ];
537 }
538
539 //--------------------------------------------------------------------------
540
541 void STDCALL mem_zeroui( puint dest, uint len )
542 {
543 while ( len-- )
544 *dest++ = 0;
545 }
546
547 //--------------------------------------------------------------------------
548
549 void STDCALL mem_copyui( puint dest, puint src, uint len )
550 {
551 while ( len-- )
552 *dest++ = *src++;
553 }
554
555 //--------------------------------------------------------------------------
556
557 uint STDCALL mem_index( pubyte dest, uint number )
558 {
559 return ( uint )( dest + number );
560 }
561
562 //--------------------------------------------------------------------------
563
564 uint STDCALL mem_copyuntilzero( pubyte dest, pubyte src )
565 {
566 pubyte temp = dest;
567
568 while ( *src )
569 *temp++ = *src++;
570 *temp = 0;
571 return ( uint )( temp - dest + 1 );
572 }
573
574 //--------------------------------------------------------------------------
575
576 void STDCALL mem_swap( pubyte left, pubyte right, uint len )
577 {
578 /* register byte temp;
579
580 if ( left != right )
581 {
582 while ( len-- )
583 {
584 temp = *left;
585 *left++ = *right;
586 *right++ = temp;
587 }
588 }*/
589
590 register uint temp;
591 register uint dwlen = len >> 2;
592
593 if ( left != right )
594 {
595 while ( dwlen-- )
596 {
597 temp = *( puint )left;
598 *(( puint )left)++ = *( puint )right;
599 *(( puint )right)++ = temp;
600 }
601 len &= 0x3;
602 while ( len-- )
603 {
604 temp = *left;
605 *left++ = *right;
606 *right++ = ( ubyte )temp;
607 }
608 }
609 }
610 /*
611 #include "msg.h"
612
613 uint STDCALL memstat()
614 {
615 print("Memnum=%i buf=%i\n", memnum, bufnum );
616 return 0;
617 }*/