| 1 | // ============================================================= |
|---|
| 2 | /* */ |
|---|
| 3 | // File : mem.c |
|---|
| 4 | // Purpose : |
|---|
| 5 | /* */ |
|---|
| 6 | // Institute of Microbiology (Technical University Munich) |
|---|
| 7 | // http://www.arb-home.de/ |
|---|
| 8 | /* */ |
|---|
| 9 | // ============================================================= |
|---|
| 10 | |
|---|
| 11 | #include "mem.h" |
|---|
| 12 | #include <stdio.h> |
|---|
| 13 | #include <attributes.h> |
|---|
| 14 | #include <cxxforward.h> |
|---|
| 15 | |
|---|
| 16 | #define MINSIZE 72 // >= sizeof(Node) |
|---|
| 17 | |
|---|
| 18 | static void *M=NULp,*D=NULp; |
|---|
| 19 | static size_t A=0; |
|---|
| 20 | |
|---|
| 21 | // ========================================================================== |
|---|
| 22 | |
|---|
| 23 | static void clearUp(void) { void *v; |
|---|
| 24 | while(D) {v=D; D=((void **)v)[0]; free(v);} |
|---|
| 25 | while(M) {v=M; M=((void **)v)[0]; free(v);} |
|---|
| 26 | } |
|---|
| 27 | |
|---|
| 28 | // ========================================================================== |
|---|
| 29 | |
|---|
| 30 | __ATTR__NORETURN static void outOfMemory(void) { |
|---|
| 31 | fprintf(stdout,"\n!!! Out of Memory\n"); |
|---|
| 32 | clearUp(); |
|---|
| 33 | exit(EXIT_FAILURE); |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | // ========================================================================== |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | void *newBlock(size_t s) { |
|---|
| 40 | void *v; size_t S; |
|---|
| 41 | |
|---|
| 42 | if(D&&s<=MINSIZE) { |
|---|
| 43 | v=D; D=((void **)v)[0]; |
|---|
| 44 | } |
|---|
| 45 | else { |
|---|
| 46 | S=((s<=MINSIZE)?MINSIZE:s)+3*sizeof(void *); |
|---|
| 47 | v=malloc(S); |
|---|
| 48 | if(!v) outOfMemory(); |
|---|
| 49 | A+=S; |
|---|
| 50 | } |
|---|
| 51 | |
|---|
| 52 | if(M) ((void **)M)[1]=v; |
|---|
| 53 | ((void **)v)[0]=M; M=v; |
|---|
| 54 | ((void **)v)[1]=NULp; |
|---|
| 55 | ((void **)v)[2]=(void *)s; |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | return(((void **)v)+3); |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | //........ |
|---|
| 62 | |
|---|
| 63 | void freeBlock_(void **vv) { |
|---|
| 64 | void *v; size_t s; |
|---|
| 65 | |
|---|
| 66 | v=(void *)(((void **)(*vv))-3); |
|---|
| 67 | |
|---|
| 68 | if(((void **)v)[0]) ((void ***)v)[0][1]=((void **)v)[1]; |
|---|
| 69 | if(((void **)v)[1]) ((void ***)v)[1][0]=((void **)v)[0]; |
|---|
| 70 | else M=((void **)v)[0]; |
|---|
| 71 | |
|---|
| 72 | s=(size_t)(((void **)v)[2]); |
|---|
| 73 | |
|---|
| 74 | if(s<=MINSIZE) { |
|---|
| 75 | ((void **)v)[0]=D; D=v; |
|---|
| 76 | } |
|---|
| 77 | else { |
|---|
| 78 | A-=s+3*sizeof(void *); |
|---|
| 79 | free(v); |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | *vv=NULp; |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | // ========================================================================== |
|---|
| 86 | |
|---|
| 87 | void **newMatrix(size_t nrow,size_t ncol,size_t s) { |
|---|
| 88 | size_t i,p; |
|---|
| 89 | void **m; |
|---|
| 90 | |
|---|
| 91 | m=(void **)newBlock(nrow*sizeof(void *)); |
|---|
| 92 | |
|---|
| 93 | p=ncol*s; for(i=0;i<nrow;i++) m[i]=newBlock(p); |
|---|
| 94 | |
|---|
| 95 | return(m); |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | //........ |
|---|
| 99 | |
|---|
| 100 | void freeMatrix_(void ***mm) { |
|---|
| 101 | void **m; size_t i,rows; |
|---|
| 102 | |
|---|
| 103 | m=*mm; |
|---|
| 104 | rows=((size_t)m[-1])/sizeof(void *); |
|---|
| 105 | for(i=0;i<rows;i++) freeBlock(m+i); |
|---|
| 106 | freeBlock((void **)mm); |
|---|
| 107 | |
|---|
| 108 | } |
|---|