ecere/gfx/newFonts: Initial eC port of font engine by Alexis Naveros
[sdk] / ecere / src / gfx / newFonts / cc / mm.h
1 /* *****************************************************************************
2  * Copyright (c) 2007-2014 Alexis Naveros.
3  *
4  * Ecere Corporation has unlimited/unrestricted rights.
5  * *****************************************************************************/
6 /**
7  * @file
8  *
9  * Global memory management header.
10  */
11
12 #ifndef MM_H
13 #define MM_H
14
15 #include <stdio.h>
16
17 #define OFFSET(s, m) ((unsigned int)(uintptr_t) (&((s *) 0)->m))
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23
24
25 #define MM_DEBUG 0
26
27 #define MM_INLINE_LIST_FUNCTIONS
28
29 #define MM_ALLOC_CHECK
30
31
32 #define MM_DEBUG_GUARD_BYTES (32)
33 #define MM_DEBUG_MMAP (1)
34 /* Enabling this will lead to ever growing memory usage! Strictly for debugging. */
35 #define MM_DEBUG_MMAP_LINGERING (0)
36
37
38
39 ////
40
41
42 #ifdef MM_NUMA
43  #include <numa.h>
44 #endif
45
46
47 #if defined(__linux__) || defined(__gnu_linux__) || defined(__linux) || defined(__linux)
48  #define MM_LINUX (1)
49  #define MM_UNIX (1)
50 #elif defined(__APPLE__)
51  #define MM_OSX (1)
52  #define MM_UNIX (1)
53 #elif defined(__unix__) || defined(__unix) || defined(unix)
54  #define MM_UNIX (1)
55 #elif defined(_WIN64) || defined(__WIN64__) || defined(WIN64)
56  #define MM_WIN64 (1)
57  #define MM_WIN32 (1)
58  #define MM_WINDOWS (1)
59 #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
60  #define MM_WIN32 (1)
61  #define MM_WINDOWS (1)
62 #endif
63
64 #if __MINGW64__
65  #define MM_MINGW32 (1)
66  #define MM_MINGW64 (1)
67 #elif __MINGW32__
68  #define MM_MINGW32 (1)
69 #endif
70
71
72 #if !MM_UNIX
73  #undef MM_DEBUG_MMAP
74  #define MM_DEBUG_MMAP (0)
75 #endif
76
77
78 #define MM_CPU_COUNT_MAXIMUM (1024)
79 #define MM_NODE_COUNT_MAXIMUM (256)
80
81
82 #ifndef CPUCONF_CACHE_LINE_SIZE
83  #define CPUCONF_CACHE_LINE_SIZE 64
84 #endif
85
86
87 #if defined(__GNUC__)
88  #define MM_CACHE_ALIGN __attribute__((aligned(CPUCONF_CACHE_LINE_SIZE)))
89  #define MM_RESTRICT __restrict
90  #define MM_NOINLINE __attribute__((noinline))
91 #else
92  #define MM_CACHE_ALIGN
93  #define MM_RESTRICT
94  #define MM_NOINLINE
95 #endif
96
97
98 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
99  #define MM_ALIGN16 __attribute__((aligned(16)))
100  #define MM_ALIGN16_SAFE (1)
101 #elif defined(_MSC_VER)
102  #define MM_ALIGN16 __declspec(align(16))
103  #define MM_ALIGN16_SAFE (1)
104 #else
105  #define MM_ALIGN16
106  #define MM_ALIGN16_SAFE (0)
107 #endif
108
109
110
111 #define MM_ERROR()  {printf("MM Error at %s:%d\n",file,line);exit(1)}
112
113 #ifndef ADDRESS
114  #define ADDRESS(p,o) ((void *)(((char *)p)+(o)))
115 #endif
116
117 #ifndef ADDRESSDIFF
118  #define ADDRESSDIFF(a,b) (((char *)a)-((char *)b))
119 #endif
120
121
122 #include <sys/time.h>
123
124 #ifdef __WIN32__
125 int mmGetTimeOfDay( struct timeval *tv );
126 #define gettimeofday(a,b) mmGetTimeOfDay(a)
127 #endif
128
129
130 typedef struct
131 {
132   int numaflag;
133   int pagesize;
134   int cpucount;
135   int nodecount;
136   int cpunode[MM_CPU_COUNT_MAXIMUM];
137   int64_t nodesize[MM_NODE_COUNT_MAXIMUM];
138   int nodecpucount[MM_NODE_COUNT_MAXIMUM];
139   int64_t sysmemory;
140 } mmContext;
141
142 extern mmContext mmcontext;
143
144
145 #include "mmatomic.h"
146 #include "mmthread.h"
147
148
149 #if MM_DEBUG
150  #define MM_FUNC(n) mm##n##Debug
151  #define MM_PARAMS , const char *file, int line
152 #else
153  #define MM_FUNC(n) mm##n
154  #define MM_PARAMS
155 #endif
156
157
158 ////
159
160
161 void mmInit();
162 void mmEnd();
163
164
165 void mmThreadBindToNode( int nodeindex );
166 void mmThreadBindToNode( int nodeindex );
167 void mmThreadBindToCpu( int cpuindex );
168 int mmCpuGetNode( int cpuindex );
169
170 void *mmNodeAlloc( int nodeindex, size_t size );
171 void mmNodeFree( int nodeindex, void *v, size_t size );
172 void mmNodeMap( int nodeindex, void *start, size_t bytes );
173
174 void *mmNodeAlignAlloc( int nodeindex, size_t size, intptr_t align );
175 void mmNodeAlignFree( int nodeindex, void *v, size_t size );
176
177
178
179 ////
180
181
182
183 typedef struct
184 {
185   void **prev;
186   void *next;
187 } mmListNode;
188
189 typedef struct
190 {
191   void *first;
192   void **last;
193 } mmListDualHead;
194
195 typedef struct
196 {
197   void *first;
198   void *last;
199 } mmListLoopHead;
200
201 #ifndef MM_INLINE_LIST_FUNCTIONS
202
203 void mmListAdd( void **list, void *item, intptr_t offset );
204 void mmListRemove( void *item, intptr_t offset );
205 void mmListMergeList( void **listdst, void **listsrc, intptr_t offset );
206 void mmListMoveList( void **listdst, void **listsrc, intptr_t offset );
207
208 void mmListDualInit( mmListDualHead *head );
209 void mmListDualAddFirst( mmListDualHead *head, void *item, intptr_t offset );
210 void mmListDualAddLast( mmListDualHead *head, void *item, intptr_t offset );
211 void mmListDualInsertAfter( mmListDualHead *head, void **prevnext, void *item, intptr_t offset );
212 void mmListDualRemove( mmListDualHead *head, void *item, intptr_t offset );
213 void *mmListDualLast( mmListDualHead *head, intptr_t offset );
214 void *mmListDualPrevious( mmListDualHead *head, void *item, intptr_t offset );
215
216 #else
217
218 static inline void mmListAdd( void **list, void *item, intptr_t offset )
219 {
220   mmListNode *node, *next;
221   node = ADDRESS( item, offset );
222   node->prev = list;
223   node->next = *list;
224   if( *list )
225   {
226     next = ADDRESS( *list, offset );
227     next->prev = &(node->next);
228   }
229   *list = item;
230   return;
231 }
232
233 static inline void mmListRemove( void *item, intptr_t offset )
234 {
235   mmListNode *node, *next;
236   node = ADDRESS( item, offset );
237   *(node->prev) = (void *)node->next;
238   if( node->next )
239   {
240     next = ADDRESS( node->next, offset );
241     next->prev = node->prev;
242   }
243   return;
244 }
245
246 static inline void mmListMergeList( void **listdst, void **listsrc, intptr_t offset )
247 {
248   void *item;
249   mmListNode *node;
250   if( !( *listsrc ) )
251     return;
252   for( item = *listdst ; item ; item = node->next )
253   {
254     node = ADDRESS( item, offset );
255     listdst = &node->next;
256   }
257   item = *listsrc;
258   node = ADDRESS( item, offset );
259   node->prev = listdst;
260   *listdst = item;
261   *listsrc = 0;
262   return;
263 }
264
265 static inline void mmListMoveList( void **listdst, void **listsrc, intptr_t offset )
266 {
267   void *item;
268   mmListNode *node;
269   if( !( *listsrc ) )
270   {
271     *listdst = 0;
272     return;
273   }
274   item = *listsrc;
275   node = ADDRESS( item, offset );
276   node->prev = listdst;
277   *listdst = item;
278   *listsrc = 0;
279   return;
280 }
281
282 static inline void mmListDualInit( mmListDualHead *head )
283 {
284   head->first = 0;
285   head->last = &head->first;
286   return;
287 }
288
289 static inline void mmListDualAddFirst( mmListDualHead *head, void *item, intptr_t offset )
290 {
291   mmListNode *node, *next;
292   node = ADDRESS( item, offset );
293   node->prev = &head->first;
294   node->next = head->first;
295   if( node->next )
296   {
297     next = ADDRESS( node->next, offset );
298     next->prev = &(node->next);
299   }
300   else
301     head->last = &(node->next);
302   head->first = item;
303   return;
304 }
305
306 static inline void mmListDualAddLast( mmListDualHead *head, void *item, intptr_t offset )
307 {
308   mmListNode *node;
309   void **prev;
310   prev = head->last;
311   *prev = item;
312   node = ADDRESS( item, offset );
313   node->prev = head->last;
314   head->last = &(node->next);
315   node->next = 0;
316   return;
317 }
318
319 static inline void mmListDualInsertAfter( mmListDualHead *head, void **prevnext, void *item, intptr_t offset )
320 {
321   mmListNode *node, *next;
322   node = ADDRESS( item, offset );
323   node->prev = prevnext;
324   node->next = *prevnext;
325   if( *prevnext )
326   {
327     next = ADDRESS( *prevnext, offset );
328     next->prev = &(node->next);
329   }
330   else
331     head->last = &(node->next);
332   *prevnext = item;
333   return;
334 }
335
336 static inline void mmListDualRemove( mmListDualHead *head, void *item, intptr_t offset )
337 {
338   mmListNode *node, *next;
339   node = ADDRESS( item, offset );
340   *(node->prev) = (void *)node->next;
341   if( node->next )
342   {
343     next = ADDRESS( node->next, offset );
344     next->prev = node->prev;
345   }
346   else
347     head->last = node->prev;
348   return;
349 }
350
351 static inline void *mmListDualLast( mmListDualHead *head, intptr_t offset )
352 {
353   if( !( head->first ) )
354     return 0;
355   return ADDRESS( head->last, -( offset + OFFSET(mmListNode,next) ) );
356 }
357
358 static inline void *mmListDualPrevious( mmListDualHead *head, void *item, intptr_t offset )
359 {
360   mmListNode *node;
361   if( item == head->first )
362     return 0;
363   node = ADDRESS( item, offset );
364   return ADDRESS( node->prev, -( offset + OFFSET(mmListNode,next) ) );
365 }
366
367 #endif
368
369 void mmListLoopInit( mmListLoopHead *head );
370 void mmListLoopAddFirst( mmListLoopHead *head, void *item, intptr_t offset );
371 void mmListLoopAddLast( mmListLoopHead *head, void *item, intptr_t offset );
372 void mmListLoopInsert( mmListLoopHead *head, void *previtem, void *item, intptr_t offset );
373 void mmListLoopRemove( mmListLoopHead *head, void *item, intptr_t offset );
374 void *mmListLoopLast( mmListLoopHead *head, intptr_t offset );
375
376
377
378 ////
379
380
381
382 typedef struct
383 {
384   void *child[2];
385   void *parent;
386   int flags;
387 } mmBTreeNode;
388
389 #define MM_BTREE_FLAGS_LEFT (0)
390 #define MM_BTREE_FLAGS_RIGHT (1)
391 #define MM_BTREE_FLAGS_DIRECTION_MASK (1)
392 #define MM_BTREE_FLAGS_STEP (2)
393
394 void mmBTreeInsert( void *item, void *parent, int itemflag, intptr_t offset, void **root );
395 void mmBTreeRemove( void *item, intptr_t offset, void **root );
396
397 void *mmBtreeMostLeft( void *root, intptr_t offset );
398 void *mmBtreeMostRight( void *root, intptr_t offset );
399 void *mmBtreeNeighbourLeft( void *item, intptr_t offset );
400 void *mmBtreeNeighbourRight( void *item, intptr_t offset );
401 intptr_t mmBtreeItemCount( void *root, intptr_t offset );
402 int mmBtreeListOrdered( void *root, intptr_t offset, int (*callback)( void *item, void *v ), void *v );
403 int mmBtreeListBalanced( void *root, intptr_t offset, int (*callback)( void *item, void *v ), void *v );
404
405
406
407 ////
408
409
410
411 typedef struct
412 {
413   mmListNode listnode;
414   mmBTreeNode node;
415   int freecount;
416   int blockindex;
417 } mmBlock;
418
419 typedef struct
420 {
421   void *blocklist;
422   void *freelist;
423   size_t chunksize;
424   int chunkperblock;
425   int alignment;
426   size_t allocsize;
427   int keepfreecount;
428   int chunkfreecount;
429   void *treeroot;
430   void *(*relayalloc)( void *head, size_t bytes MM_PARAMS );
431   void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS );
432   void *relayvalue;
433   mtSpin spinlock;
434 } mmBlockHead;
435
436 void MM_FUNC(BlockInit)( mmBlockHead *head, size_t chunksize, int chunkperblock, int keepfreecount, int alignment MM_PARAMS );
437 void MM_FUNC(BlockNodeInit)( mmBlockHead *head, int nodeindex, size_t chunksize, int chunkperblock, int keepfreecount, int alignment MM_PARAMS );
438 void *MM_FUNC(BlockAlloc)( mmBlockHead *head MM_PARAMS );
439 void MM_FUNC(BlockRelease)( mmBlockHead *head, void *v MM_PARAMS );
440 void MM_FUNC(BlockFree)( mmBlockHead *head, void *v MM_PARAMS );
441 void MM_FUNC(BlockFreeAll)( mmBlockHead *head MM_PARAMS );
442 void MM_FUNC(BlockProcessList)( mmBlockHead *head, void *userpointer, int (*processchunk)( void *chunk, void *userpointer ) MM_PARAMS );
443 int MM_FUNC(BlockUseCount)( mmBlockHead *head MM_PARAMS );
444 int MM_FUNC(BlockFreeCount)( mmBlockHead *head MM_PARAMS );
445
446 #if MM_DEBUG
447  #define mmBlockInit(v,w,x,y,z) MM_FUNC(BlockInit)(v,w,x,y,z,__FILE__,__LINE__)
448  #define mmBlockNodeInit(u,v,w,x,y,z) MM_FUNC(BlockNodeInit)(u,v,w,x,y,z,__FILE__,__LINE__)
449  #define mmBlockAlloc(x) MM_FUNC(BlockAlloc)(x,__FILE__,__LINE__)
450  #define mmBlockRelease(x,y) MM_FUNC(BlockRelease)(x,y,__FILE__,__LINE__)
451  #define mmBlockFree(x,y) MM_FUNC(BlockFree)(x,y,__FILE__,__LINE__)
452  #define mmBlockFreeAll(x) MM_FUNC(BlockFreeAll)(x,__FILE__,__LINE__)
453  #define mmBlockProcessList(x,y,z) MM_FUNC(BlockProcessList)(x,y,z,__FILE__,__LINE__)
454  #define mmBlockUseCount(x) MM_FUNC(BlockProcessList)(x,__FILE__,__LINE__)
455  #define mmBlockFreeCount(x) MM_FUNC(BlockProcessList)(x,__FILE__,__LINE__)
456 #endif
457
458 /*
459 void mmBlockRelayByVolume( mmBlockHead *head, void *volumehead );
460 void mmBlockRelayByZone( mmBlockHead *head, void *zonehead );
461 */
462
463
464
465 ////
466
467
468
469 typedef struct
470 {
471   mmBlockHead indexblock;
472   void *indextree;
473   intptr_t indexlimit;
474   mtSpin spinlock;
475 } mmIndexHead;
476
477 void mmIndexInit( mmIndexHead *head, int indexesperblock );
478 void mmIndexFreeAll( mmIndexHead *head );
479 void mmIndexAdd( mmIndexHead *head, intptr_t index );
480 intptr_t mmIndexGet( mmIndexHead *head );
481 int mmIndexRemove( mmIndexHead *head, intptr_t index );
482 size_t mmIndexCount( mmIndexHead *head );
483
484
485
486 ////
487
488
489
490 typedef struct
491 {
492   uintptr_t bitmask;
493   int bitshift;
494   uintptr_t countalign;
495   uintptr_t indexshift;
496   uintptr_t indexmask;
497   uintptr_t initmask;
498   size_t mapsize;
499   uintptr_t *map;
500   mtSpin spinlock;
501 } mmBitTableHead;
502
503 void mmBitTableInit( mmBitTableHead *head, int bitsperentry, int chunksize, int initmask );
504 void mmBitTableFreeAll( mmBitTableHead *head );
505 void mmBitTableSet( mmBitTableHead *head, uintptr_t index, int flags, int editmask );
506 uintptr_t mmBitTableGet( mmBitTableHead *head, uintptr_t index );
507
508
509
510 ////
511
512
513
514 typedef struct
515 {
516   size_t size;
517   size_t used;
518   void *next;
519 } mmGrowNode;
520
521 typedef struct
522 {
523   mmGrowNode *first;
524   size_t nodesize;
525   mtSpin spinlock;
526 } mmGrow;
527
528 int MM_FUNC(GrowInit)( mmGrow *mgrow, size_t nodesize MM_PARAMS );
529 void MM_FUNC(GrowFreeAll)( mmGrow *mgrow MM_PARAMS );
530 void *MM_FUNC(GrowAlloc)( mmGrow *mgrow, size_t bytes MM_PARAMS );
531 void MM_FUNC(GrowRewindLast)( mmGrow *mgrow, size_t rewind MM_PARAMS );
532
533 #if MM_DEBUG
534  #define mmGrowInit(x,y) MM_FUNC(GrowInit)(x,y,__FILE__,__LINE__)
535  #define mmGrowFreeAll(x) MM_FUNC(GrowFreeAll)(x,__FILE__,__LINE__)
536  #define mmGrowAlloc(x,y) MM_FUNC(GrowAlloc)(x,y,__FILE__,__LINE__)
537  #define mmGrowRewindLast(x) MM_FUNC(GrowRewindLast)(x,__FILE__,__LINE__)
538 #endif
539
540
541
542 ////
543
544
545 #if 0
546
547 typedef struct
548 {
549   void ***table;
550   intptr_t pagecount;
551   intptr_t pagesize;
552   intptr_t pagemask;
553   intptr_t pageshift;
554   mtSpin spinlock;
555 } mmDirectory;
556
557 #define MM_DIR_ENTRY(dir,index) ( (dir)->table[ index >> (dir)->pageshift ][ index & (dir)->pagemask ] )
558
559 int MM_FUNC(DirInit)( mmDirectory *dir, intptr_t pageshift, intptr_t pagecount MM_PARAMS );
560 void MM_FUNC(DirSize)( mmDirectory *dir, intptr_t size MM_PARAMS );
561 void MM_FUNC(DirSet)( mmDirectory *dir, intptr_t index, void *entry MM_PARAMS );
562 void *MM_FUNC(DirGet)( mmDirectory *dir, intptr_t index MM_PARAMS );
563 void MM_FUNC(DirSetFast)( mmDirectory *dir, intptr_t index, void *entry MM_PARAMS );
564 void *MM_FUNC(DirGetFast)( mmDirectory *dir, intptr_t index MM_PARAMS );
565 void MM_FUNC(DirFree)( mmDirectory *dir MM_PARAMS );
566
567 #if MM_DEBUG
568  #define mmDirInit(x,y,z) MM_FUNC(DirInit)(x,y,z,__FILE__,__LINE__)
569  #define mmDirSize(x,y) MM_FUNC(DirSize)(x,y,__FILE__,__LINE__)
570  #define mmDirSet(x,y,z) MM_FUNC(DirSet)(x,y,z,__FILE__,__LINE__)
571  #define mmDirGet(x,y) MM_FUNC(DirGet)(x,y,__FILE__,__LINE__)
572  #define mmDirSetFast(x,y,z) MM_FUNC(DirSetFast)(x,y,z,__FILE__,__LINE__)
573  #define mmDirGetFast(x,y) MM_FUNC(DirGetFast)(x,y,__FILE__,__LINE__)
574  #define mmDirFree(x) MM_FUNC(DirFree)(x,__FILE__,__LINE__)
575 #endif
576
577 #endif
578
579
580 ////
581
582
583
584 void *MM_FUNC(AlignAlloc)( size_t bytes, intptr_t align MM_PARAMS );
585 void MM_FUNC(AlignFree)( void *v MM_PARAMS );
586 void *MM_FUNC(AlignGrow)( void *v, size_t bytes, size_t copybytes, intptr_t align MM_PARAMS );
587 void *MM_FUNC(AlignRelayAlloc)( void *(*relayalloc)( void *head, size_t bytes MM_PARAMS ), void *relayvalue, size_t bytes, intptr_t align, size_t displacement MM_PARAMS );
588 void MM_FUNC(AlignRelayFree)( void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS ), void *relayvalue, void *v, size_t bytes MM_PARAMS );
589
590 #if MM_DEBUG
591  #define mmAlignAlloc(x,y) MM_FUNC(AlignAlloc)(x,y,__FILE__,__LINE__)
592  #define mmAlignFree(x) MM_FUNC(AlignFree)(x,__FILE__,__LINE__)
593  #define mmAlignGrow(x) MM_FUNC(AlignGrow)(x,__FILE__,__LINE__)
594  #define mmAlignRelayAlloc(v,w,x,y,z) MM_FUNC(AlignRelayAlloc)(v,w,x,y,z,__FILE__,__LINE__)
595  #define mmAlignRelayFree(w,x,y,z) MM_FUNC(AlignRelayFree)(w,x,y,z,__FILE__,__LINE__)
596 #endif
597
598
599
600 ////
601
602
603
604 typedef struct
605 {
606   size_t volumesize;
607   size_t volumeblocksize;
608   size_t minchunksize;
609   size_t volumechunksize;
610   size_t keepfreesize;
611   size_t totalfreesize;
612   size_t alignment;
613   void *freeroot;
614   void *volumelist;
615   void *(*relayalloc)( void *head, size_t bytes MM_PARAMS );
616   void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS );
617   void *relayvalue;
618   mtSpin spinlock;
619 } mmVolumeHead;
620
621 void MM_FUNC(VolumeInit)( mmVolumeHead *head, size_t volumesize, size_t minchunksize, size_t keepfreesize, size_t alignment MM_PARAMS );
622 void MM_FUNC(VolumeNodeInit)( mmVolumeHead *head, int nodeindex, size_t volumesize, size_t minchunksize, size_t keepfreesize, size_t alignment MM_PARAMS );
623 void *MM_FUNC(VolumeAlloc)( mmVolumeHead *head, size_t bytes MM_PARAMS );
624 void MM_FUNC(VolumeRelease)( mmVolumeHead *head, void *v MM_PARAMS );
625 void MM_FUNC(VolumeFree)( mmVolumeHead *head, void *v MM_PARAMS );
626 void MM_FUNC(VolumeShrink)( mmVolumeHead *head, void *v, size_t bytes MM_PARAMS );
627 size_t MM_FUNC(VolumeGetAllocSize)( mmVolumeHead *head, void *v );
628 void MM_FUNC(VolumeClean)( mmVolumeHead *head MM_PARAMS );
629 void MM_FUNC(VolumeFreeAll)( mmVolumeHead *head MM_PARAMS );
630 void *MM_FUNC(VolumeRealloc)( mmVolumeHead *head, void *v, size_t bytes MM_PARAMS );
631
632 #if MM_DEBUG
633  #define mmVolumeInit(w,x,y,z,a) MM_FUNC(VolumeInit)(w,x,y,z,a,__FILE__,__LINE__);
634  #define mmVolumeNodeInit(v,w,x,y,z) MM_FUNC(VolumeNodeInit)(v,w,x,y,z,__FILE__,__LINE__);
635  #define mmVolumeAlloc(x,y) MM_FUNC(VolumeAlloc)(x,y,__FILE__,__LINE__);
636  #define mmVolumeRelease(x,y) MM_FUNC(VolumeRelease)(x,y,__FILE__,__LINE__);
637  #define mmVolumeFree(x,y) MM_FUNC(VolumeFree)(x,y,__FILE__,__LINE__);
638  #define mmVolumeShrink(x,y,z) MM_FUNC(VolumeShrink)(x,y,z,__FILE__,__LINE__);
639  #define mmVolumeGetAllocSize(x) MM_FUNC(VolumeGetAllocSize)(x,y,__FILE__,__LINE__);
640  #define mmVolumeClean(x) MM_FUNC(VolumeClean)(x,__FILE__,__LINE__);
641  #define mmVolumeFreeAll(x) MM_FUNC(VolumeFreeAll)(x,__FILE__,__LINE__);
642  #define mmVolumeRealloc(x) MM_FUNC(VolumeRealloc)(x,y,z,__FILE__,__LINE__);
643
644  #define mmVolumeAlloc MM_FUNC(VolumeAlloc)
645  #define mmVolumeRelease MM_FUNC(VolumeRelease)
646  #define mmVolumeFree MM_FUNC(VolumeFree)
647
648 #endif
649
650 /*
651 void mmVolumeRelayByZone( mmVolumeHead *head, void *zonehead );
652 */
653
654
655
656 ////
657
658
659
660 typedef struct
661 {
662   void *address;
663   size_t pagesize;
664   size_t pagealignment;
665   size_t zonesize;
666   size_t alignment;
667   size_t chunkheadersize;
668   void *chunklist;
669   mtSpin spinlock;
670 } mmZoneHead;
671
672 int MM_FUNC(ZoneInit)( mmZoneHead *head, size_t zonesize, intptr_t alignment MM_PARAMS );
673 void *MM_FUNC(ZoneAlloc)( mmZoneHead *head, size_t bytes MM_PARAMS );
674 void MM_FUNC(ZoneFree)( mmZoneHead *head, void *v MM_PARAMS );
675 void MM_FUNC(ZoneFreeAll)( mmZoneHead *head MM_PARAMS );
676
677 #if MM_DEBUG
678  #define mmZoneInit(x,y,z) MM_FUNC(ZoneInit)(x,y,z,__FILE__,__LINE__);
679  #define mmZoneAlloc(x,y) MM_FUNC(ZoneAlloc)(x,y,__FILE__,__LINE__);
680  #define mmZoneFree(x,y) MM_FUNC(ZoneFree)(x,y,__FILE__,__LINE__);
681  #define mmZoneFreeAll(x) MM_FUNC(ZoneFreeAll)(x,__FILE__,__LINE__);
682 #endif
683
684
685
686 ////
687
688
689
690 void *mmAlloc( void *unused, size_t bytes MM_PARAMS );
691 void *mmRealloc( void *unused, void *v, size_t bytes MM_PARAMS );
692 void mmFree( void *unused, void *v, size_t bytes MM_PARAMS );
693
694 void *mmDebugAlloc( size_t bytes, const char *file, int line );
695 void *mmDebugRealloc( void *v, size_t bytes, const char *file, int line );
696 void mmDebugFree( void *v, const char *file, int line );
697 #define mmDebugAlloc(x) mmDebugAlloc(x,__FILE__,__LINE__)
698 #define mmDebugFree(x) mmDebugFree(x,__FILE__,__LINE__)
699 #define mmDebugRealloc(x,y) mmDebugRealloc(x,y,__FILE__,__LINE__)
700
701 void mmListUses( const char *file, int line );
702 #define mmListUses() mmListUses(__FILE__,__LINE__);
703
704
705 ////
706
707
708 #if MM_DEBUG
709  #define malloc(x) mmAlloc(0,(x),__FILE__,__LINE__)
710  #define realloc(x,y) mmRealloc(0,(x),(y),__FILE__,__LINE__)
711  #define free(x) mmFree(0,(x),0,__FILE__,__LINE__)
712 #elif defined(MM_ALLOC_CHECK)
713
714 static inline void *mmAllocCheck( size_t size, const char *file, int line )
715 {
716   void *p;
717   p = malloc( size );
718 #if MM_WINDOWS
719   if( !( p ) )
720     fprintf( stderr, "WARNING : Denied memory allocation ( %ld bytes ) at %s:%d\n", (long)size, file, line );
721 #else
722   if( !( p ) )
723     fprintf( stderr, "WARNING : Denied memory allocation ( %lld bytes ) at %s:%d\n", (long long)size, file, line );
724 #endif
725   return p;
726 }
727
728 static inline void *mmReallocCheck( void *p, size_t size, const char *file, int line )
729 {
730   p = realloc( p, size );
731 #if MM_WINDOWS
732   if( !( p ) )
733     fprintf( stderr, "WARNING : Denied memory allocation ( %ld bytes ) at %s:%d\n", (long)size, file, line );
734 #else
735   if( !( p ) )
736     fprintf( stderr, "WARNING : Denied memory allocation ( %lld bytes ) at %s:%d\n", (long long)size, file, line );
737 #endif
738   return p;
739 }
740
741  #define malloc(x) mmAllocCheck((x),__FILE__,__LINE__)
742  #define realloc(x,y) mmReallocCheck((x),(y),__FILE__,__LINE__)
743 #endif
744
745
746
747
748 ////
749
750
751
752 static inline uint64_t mmGetMillisecondsTime()
753 {
754   struct timeval lntime;
755   gettimeofday( &lntime, 0 );
756   return ( (uint64_t)lntime.tv_sec * 1000 ) + ( (uint64_t)lntime.tv_usec / 1000 );
757 }
758
759
760 static inline uint64_t mmGetMicrosecondsTime()
761 {
762   struct timeval lntime;
763   gettimeofday( &lntime, 0 );
764   return ( (uint64_t)lntime.tv_sec * 1000000 ) + (uint64_t)lntime.tv_usec;
765 }
766
767
768 static inline uint64_t mmGetNanosecondsTime()
769 {
770   struct timeval lntime;
771   gettimeofday( &lntime, 0 );
772   return ( (uint64_t)lntime.tv_sec * 1000000000 ) + ( (uint64_t)lntime.tv_usec * 1000 );
773 }
774
775
776
777 ////
778
779
780
781 #ifdef __cplusplus
782 }
783 #endif
784
785
786 #endif