source: abuse/tags/pd/imlib/jmalloc.c @ 161

Last change on this file since 161 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 22.0 KB
Line 
1#include <stdlib.h>
2#include <string.h>
3#include <stdio.h>
4//#include <new.h>
5
6//#ifdef MEM_CHECK
7//#define MEM_CLEAR
8//#endif
9
10#ifdef __WATCOMC__
11#include "doscall.hpp"
12#endif
13#include "jmalloc.hpp"
14#define uchar unsigned char
15#define JM_SMALL_SIZE 128      // above 128 bytes is considered to be a big block and no hashing is done
16int alloc_space=ALLOC_SPACE_STATIC;
17
18extern void free_up_memory();
19
20#ifdef MEM_CHECK
21long break_mem_point=0;       // can be set in debugger, break mem fun will be called when this address is allocated
22void break_mem_fun()
23{
24  printf("memory breakpoint\n");
25}
26#endif
27
28struct memory_node
29{
30  long size;
31#ifdef MEM_CHECK
32  char *name;                     // name is allocated on regular heap
33#endif                            // because it is used for debugging purposes
34                                  // and will probably be run on my linux box with VMM
35  memory_node *next;
36};
37
38
39struct small_block
40
41  unsigned long size;                     // size of blocks...
42  unsigned long alloc_list;               // bit field saying weither each block is allocated or not.
43  small_block *next;                      // next small block of same size
44#ifdef MEM_CHECK
45  char *name[32];
46#endif
47} ;
48
49enum { HI_BLOCK, LOW_BLOCK };
50
51class block_manager
52{
53  public :
54
55  long block_size;                             // size of this memory_block
56  small_block *sblocks[JM_SMALL_SIZE];
57  small_block *cblocks[JM_SMALL_SIZE];
58  void *addr;
59
60  memory_node *sfirst,*slast,
61              *cfirst;
62  unsigned char block_type;
63
64  void init(void *block, long Block_size, uchar type);
65  void *static_alloc(long size, char *name);
66  void *cache_alloc(long size, char *name);
67  void static_free(void *ptr);
68  void cache_free(void *ptr);
69  long available();
70  long allocated();
71  long pointer_size(void *ptr);
72  void report(FILE *fp);
73  void inspect();
74
75  int valid_static_ptr(void *ptr);     // only called from within debugger
76  int valid_cache_ptr(void *ptr);
77} bmanage[5];
78
79int bmanage_total=0;
80
81
82void inspect_memory()
83{
84  for (int i=0;i<bmanage_total;i++)
85    bmanage[i].inspect();
86}
87
88
89int block_manager::valid_static_ptr(void *ptr)
90{
91  void *next=(void *)(*(((long *)ptr)-1));
92  if (next && ((small_block *)next)->size<JM_SMALL_SIZE)  // small allocation
93  {
94    small_block *s=(small_block *)next;
95    if (s->size<=0) return 0;
96
97    small_block *c=sblocks[s->size];
98    while (c && c!=s) c=c->next;
99    if (!c) return 0;
100  }
101
102  memory_node *o=(memory_node *)(((char *)ptr)-sizeof(memory_node));
103  memory_node *f=sfirst;
104  while (f && f!=o) f=f->next;
105  if (f) return 1;
106  else return 0;
107}
108
109
110int block_manager::valid_cache_ptr(void *ptr)
111{
112  void *next=(void *)(*(((long *)ptr)-1));
113  if (next && ((small_block *)next)->size<JM_SMALL_SIZE)  // small allocation
114  {
115    small_block *s=(small_block *)next;
116    if (s->size<=0) return 0;
117
118    small_block *c=cblocks[s->size];
119    while (c && c!=s) c=c->next;
120    if (!c) return 0;
121  }
122
123  memory_node *o=(memory_node *)(((char *)ptr)-sizeof(memory_node));
124  memory_node *f=cfirst;
125  while (f && f!=o) f=f->next;
126  if (f) return 1;
127  else return 0;
128}
129
130void small_static_allocation_summary(int &total, int *&static_list, int *&cache_list)
131{
132  int size=1;
133  total=JM_SMALL_SIZE/4;
134  static_list=(int *)jmalloc(total*sizeof(int),"small static report");
135  cache_list=(int *)jmalloc(total*sizeof(int),"small cache report");
136 
137  for (;size<total;size++)
138  {
139    static_list[size]=0;
140    cache_list[size]=0;
141    int i,x;
142    for (i=0;i<bmanage_total;i++)
143    {
144      small_block *s=bmanage[i].sblocks[size];
145      while (s)
146      {
147                                for (x=0;x<32;x++)
148                                  if (s->alloc_list&(1<<x))
149                                    static_list[size]++;
150                       
151                                s=s->next;
152      }
153
154      s=bmanage[i].cblocks[size];
155      while (s)
156      {
157                                for (x=0;x<32;x++)
158                                  if (s->alloc_list&(1<<x))
159                                    cache_list[size]++;
160                       
161                                s=s->next;
162      }
163    }
164  }
165}
166
167void block_manager::inspect()
168{
169  memory_node *f=sfirst;
170  for (;f;f=f->next);               // scan through static big list
171
172  int i,bit;
173  for (i=0;i<JM_SMALL_SIZE;i++)
174  {
175    for (small_block *s=sblocks[i];s;s=s->next)
176    {
177      char *addr=((char *)(s+1));
178      for (int j=0;j<32;j++)
179      {
180                                if (s->alloc_list&bit)
181                                {
182                                  void *next=(void *)(*(((long *)addr)));
183                                  if ((long)next!=(long)s)
184                                  {
185                                    fprintf(stderr,"inspect : bad pointer\n");
186                                    return ;       
187                                  }
188                                }
189                                bit=bit<<1;
190                                addr+=s->size+4;
191      }
192    }
193  }
194
195}
196
197void block_manager::report(FILE *fp)
198{
199  fprintf(fp,"************** Block size = %d ***************\n",block_size);
200  fprintf(fp,"************** STATIC SPACE ******************\n");
201  int i=0;
202  memory_node *f=sfirst;
203  for (;f;f=f->next,i++)
204  {   
205    fprintf(fp,"%4d   %p (%d) %4d      ",i,f,((char *)f-(char *)sfirst),f->size);
206#ifdef MEM_CHECK
207    if (f->size>0)
208      fprintf(fp,"%s",f->name);
209    else fprintf(fp,"FREE");
210#endif
211    fprintf(fp,"\n");
212  }   
213  for (i=0;i<JM_SMALL_SIZE;i++)
214  {
215    for (small_block *s=sblocks[i];s;s=s->next)
216    {     
217      fprintf(fp,"*** Small Block size = %d ***\n",i);     
218      unsigned long x=0,bit=1;
219      char *addr=((char *)(s+1));
220      for (int j=0;j<32;j++)
221      {
222                                fprintf(fp,"%p   ",addr);
223                                if (s->alloc_list&bit)
224                                {
225#ifdef MEM_CHECK
226                                  fprintf(fp,"%s\n",s->name[j]);
227#else
228                                  fprintf(fp,"allocated\n");
229#endif   
230                                } else fprintf(fp,"FREE\n");
231                                bit=bit<<1;
232                                addr+=s->size+4;
233      }
234    }
235  }
236
237
238  fprintf(fp,"************** CACHE SPACE ******************\n",block_size);
239  i=0;
240  for (f=cfirst;f;f=f->next,i++)
241  {   
242    fprintf(fp,"%4d   %p %4d      ",i,f,f->size);
243#ifdef MEM_CHECK
244    if (f->size>0)
245      fprintf(fp,"%s",f->name);
246    else fprintf(fp,"FREE");
247#endif
248    fprintf(fp,"\n");
249  }   
250  for (i=0;i<JM_SMALL_SIZE;i++)
251  {
252    for (small_block *s=cblocks[i];s;s=s->next)
253    {     
254      fprintf(fp,"*** Small Block size = %d ***\n",i);     
255      unsigned long x=0,bit=1;
256      char *addr=((char *)(s+1));
257      for (int j=0;j<32;j++)
258      {
259        fprintf(fp,"%p   ",addr);
260        if (s->alloc_list&bit)
261        {
262#ifdef MEM_CHECK
263          fprintf(fp,"%s\n",s->name[j]);
264#else
265          fprintf(fp,"allocated\n");
266#endif   
267        } else fprintf(fp,"FREE\n");
268        bit=bit<<1;
269        addr+=s->size+4;
270      }
271    }
272  }
273}
274
275long block_manager::pointer_size(void *ptr)
276{
277  void *next=(void *)(*(((long *)ptr)-1));
278  if (next>ptr)
279    return ((memory_node *)(((char *)ptr)-sizeof(memory_node)))->size;
280  else return ((small_block *)next)->size;
281}
282
283long block_manager::available()
284{
285  long size=0;
286  memory_node *f;
287  for (f=sfirst;f;f=f->next)
288    if (f->size<0) size-=f->size;
289
290  for (f=cfirst;f;f=f->next)
291    if (f->size<0) size-=f->size;
292  return size;
293}
294
295long block_manager::allocated()
296{
297  long size=0;
298  memory_node *f;
299  for (f=sfirst;f;f=f->next)
300    if (f->size>0) size+=f->size;
301
302  for (f=cfirst;f;f=f->next)
303    if (f->size>0) size+=f->size;
304  return size;
305}
306
307void block_manager::init(void *block, long Block_size, uchar type)
308{
309  block_size=Block_size;
310  addr=block;
311  /*
312     I'm padding each block, because I'm comparing pointers against size
313     in jfree to determine weither a pointer is too a small object or a large alloc
314     and it must always be true that the address of the pointer is > JM_SMALL_SIZE
315     All systems I know start pointer address pretty high, but this is a porting consern.     
316  */
317 
318  slast=sfirst=(memory_node *)(((char *)block)+JM_SMALL_SIZE);   
319  sfirst->size=-(block_size-sizeof(memory_node)-JM_SMALL_SIZE);
320  sfirst->next=NULL;
321  cfirst=NULL;
322  memset(sblocks,0,sizeof(sblocks));
323  memset(cblocks,0,sizeof(cblocks));
324  block_type=type;
325}
326
327void *block_manager::static_alloc(long size, char *name)
328{
329  if (size<JM_SMALL_SIZE)
330  {
331    small_block *s=sblocks[size];
332    for (;s && s->alloc_list==0xffffffff;s=s->next);
333    if (!s)
334    {
335      s=(small_block *)static_alloc((size+4)*32+sizeof(small_block),"small_block");
336      if (!s) return NULL;   // not enough room for another small block
337      s->alloc_list=1;
338      s->next=sblocks[size];
339      sblocks[size]=s;
340      s->size=size;
341#ifdef MEM_CHECK
342      s->name[0]=strcpy((char *)malloc(strlen(name)+1),name);
343      if ((long)s==break_mem_point)
344        break_mem_fun();
345#endif     
346      long *addr=(long *)(((char *)s)+sizeof(small_block));
347      *addr=(long)s;
348      return (void *)(addr+1);  // return first block
349    } else
350    {
351      int bit=1,i=0,offset=0;
352      char *addr=((char *)s)+sizeof(small_block);
353      while (1)        // we already know there is a bit free
354      {
355        if ((s->alloc_list&bit)==0)
356        {
357          s->alloc_list|=bit;
358#ifdef MEM_CHECK
359          s->name[i]=strcpy((char *)malloc(strlen(name)+1),name);
360#endif           
361          *((long *)addr)=(long)s;
362
363#ifdef MEM_CHECK
364          if ((long)addr==break_mem_point)
365            break_mem_fun();
366#endif
367
368          return (void *)(addr+4);
369        }
370        i++;
371        bit=bit<<1;
372        addr+=size+4;
373      }     
374    }               
375  }
376
377
378  memory_node *s=sfirst;
379  for (;s && -s->size<size;s=s->next);
380  if (!s) return NULL;
381  s->size=-s->size;
382
383  if (s->size-size>sizeof(memory_node)+4)  // is there enough space to split the block?
384  {   
385    memory_node *p=(memory_node *)((char *)s+sizeof(memory_node)+size);
386    if (s==slast)
387      slast=p;
388    p->size=-(s->size-size-sizeof(memory_node));
389#ifdef MEM_CLEAR
390//    memset( ((memory_node *)p)+1,0,-p->size);
391#endif
392    p->next=s->next;
393    s->next=p;
394    s->size=size;
395  }
396#ifdef MEM_CHECK
397  s->name=strcpy((char *)malloc(strlen(name)+1),name);
398
399  if ((long)s==break_mem_point)
400    break_mem_fun();
401
402#endif
403  return (void *)(((char *)s)+sizeof(memory_node));
404}
405
406
407void *block_manager::cache_alloc(long size, char *name)
408{
409  if (size<JM_SMALL_SIZE)
410  {
411    small_block *s=cblocks[size];
412    for (;s && s->alloc_list==0xffffffff;s=s->next);
413    if (!s)
414    {
415      s=(small_block *)cache_alloc((size+4)*32+sizeof(small_block),"small_block");
416      if (!s) return NULL;   // not enough room for another small block
417      s->alloc_list=1;
418      s->next=cblocks[size];
419      cblocks[size]=s;
420      s->size=size;
421#ifdef MEM_CHECK
422      s->name[0]=strcpy((char *)malloc(strlen(name)+1),name);
423
424#endif     
425      long *addr=(long *)(((char *)s)+sizeof(small_block));
426      *addr=(long)s;
427#ifdef MEM_CHECK
428      if ((long)s==break_mem_point)
429        break_mem_fun();
430#endif
431      return (void *)(addr+1);  // return first block
432    } else
433    {
434      int bit=1,i=0,offset=0;
435      char *addr=((char *)s)+sizeof(small_block);
436      while (1)        // we already know there is a bit free
437      {
438        if ((s->alloc_list&bit)==0)
439        {
440          s->alloc_list|=bit;
441#ifdef MEM_CHECK
442          s->name[i]=strcpy((char *)malloc(strlen(name)+1),name);
443          if ((long)s==break_mem_point)
444            break_mem_fun();
445#endif           
446          *((long *)addr)=(long)s;
447          return (void *)(addr+4);
448        }
449        i++;
450        bit=bit<<1;
451        addr+=size+4;
452      }     
453    }               
454  }
455
456
457  memory_node *clast=NULL;
458  memory_node *s=cfirst;
459  for (;s && -s->size<size;s=s->next) clast=s;
460  if (!s) // no current cache space for object, see if we can enlarge the cache space
461  {
462    long size_avail=-slast->size;
463    size_avail-=sizeof(memory_node);
464
465    if (slast->size>0 || size_avail<size) // not enough space
466      return NULL;
467    else
468    {
469      slast->size+=size+sizeof(memory_node);
470      memory_node *nc=(memory_node *)(((char *)(slast)) + (-slast->size+sizeof(memory_node)));
471     
472      nc->next=NULL;
473      nc->size=size;
474#ifdef MEM_CHECK
475      nc->name=strcpy((char *)malloc(strlen(name)+1),name);     
476      if ((long)nc==break_mem_point)
477        break_mem_fun();
478#endif     
479      if (!clast)
480        cfirst=nc;
481      else clast->next=nc;
482      return (void *)(((char *)nc)+sizeof(memory_node));
483    }
484  }
485
486
487  s->size=-s->size;
488
489  if (s->size-size>sizeof(memory_node)+4)  // is there enough space to split the block?
490  {
491    memory_node *p=s;    // store this position
492    long psize=s->size-size-sizeof(memory_node);
493    s=(memory_node *)(((char *)s)+psize+sizeof(memory_node));
494    p->size=-psize;
495    s->next=p;
496    s->size=size;
497    if (cfirst==p) cfirst=s;
498    else clast->next=s;
499  }
500#ifdef MEM_CHECK
501  s->name=strcpy((char *)malloc(strlen(name)+1),name);
502  if ((long)s==break_mem_point)
503    break_mem_fun();
504#endif
505  return (void *)(((char *)s)+sizeof(memory_node));
506}
507
508
509/************************** CACHE FREE ****************************/
510/*    should be called to free a pointer in the cache heap        */
511/*    i.e. end of the heap                                        */
512/******************************************************************/
513void block_manager::cache_free(void *ptr)
514{
515  // see if this was a small_block allocation
516  void *next=(void *)(*(((long *)ptr)-1));
517  if (next && ((small_block *)next)->size<JM_SMALL_SIZE)  // small allocation
518  {
519    small_block *s=(small_block *)next;
520    if (s->size<=0)
521    {
522      fprintf(stderr,"jfree : bad pointer\n");
523      return ;
524    }
525
526    int field=(((char *)ptr)-((char *)s)-sizeof(small_block))/(s->size+4);
527#ifdef MEM_CHECK
528    free(s->name[field]);
529#endif
530    s->alloc_list&=(0xffffffff-(1<<field));
531    if (s->alloc_list==0)
532    {
533      small_block *l=NULL;
534      small_block *n=cblocks[s->size];
535      for (;n!=s;n=n->next) l=n;
536#ifdef MEM_CHECK
537      if (!n)
538      { printf("Free small block error\n"); }
539#endif
540      if (!l)
541      cblocks[s->size]=s->next;
542      else l->next=s->next;
543      cache_free(s);
544    }     
545  } else
546  {
547    memory_node *o=(memory_node *)(((char *)ptr)-sizeof(memory_node)),*last=NULL;
548    memory_node *n=cfirst;
549    for (;n && n!=o;n=n->next) last=n;
550#ifdef MEM_CHECK
551    if (!n)
552    { printf("Free cached big block error\n"); }
553    free(o->name);
554#endif
555   
556    if (last && last->size<0)   // can we add into last block
557    {
558      memory_node *prev=NULL;
559      for (memory_node *n=cfirst;n && n!=last;n=n->next) prev=n;   // find previous to last pointer
560      if (prev)
561        prev->next=o;
562      else cfirst=o;
563
564      o->size=last->size-o->size-sizeof(memory_node);
565      last=prev;
566    } else o->size=-o->size;
567   
568    if (!o->next)           // if no next block, then we should add back into static memory
569    {
570      if (last) last->next=NULL;  // unlink from cache chain
571      else cfirst=NULL;
572
573      if (slast->size>0)    // if last static is allocated then create a new free static at end of list
574      {
575        slast->next=o;
576        slast=o;
577      } else     
578        slast->size+=o->size-sizeof(memory_node);  // else just increase the size of last block
579    } else if (o->next->size<0)   // see if we can add into next block
580    {
581      o->next->size+=o->size-sizeof(memory_node);
582      if (last)     
583        last->next=o->next;
584      else
585        cfirst=o->next;
586    }
587  } 
588}
589
590
591
592/************************** STATIC FREE ***************************/
593/*    should be called to free a pointer in the static heap       */
594/*    i.e. begining of the heap                                   */
595/******************************************************************/
596void block_manager::static_free(void *ptr)
597{
598  // see if this was a small_block allocation
599  void *next=(void *)(*(((long *)ptr)-1));
600  if (next && next<ptr)  // small allocation
601  {
602    small_block *s=(small_block *)next;
603    if (s->size<=0)
604    {
605      fprintf(stderr,"jfree : bad pointer\n");
606      return ;
607    }
608#ifdef MEM_CLEAR
609    memset(ptr,0,s->size);
610#endif
611
612    int field=(((char *)ptr)-((char *)s)-sizeof(small_block))/(s->size+4);
613#ifdef MEM_CHECK
614    free(s->name[field]);
615#endif
616    s->alloc_list&=(0xffffffff-(1<<field));
617    if (s->alloc_list==0)
618    {
619      small_block *l=NULL;
620      small_block *n=sblocks[s->size];
621      for (;n!=s;n=n->next) l=n;
622#ifdef MEM_CHECK
623      if (!n) { printf("Free static small block error\n"); }
624#endif
625      if (!l)
626      sblocks[s->size]=s->next;
627      else l->next=s->next;
628      static_free(s);
629    }     
630  } else
631  {
632    memory_node *o=(memory_node *)(((char *)ptr)-sizeof(memory_node)),*last=NULL;
633#ifdef MEM_CHECK
634    free(o->name);
635#endif
636#ifdef MEM_CLEAR
637    memset(ptr,0,o->size);
638#endif
639
640    if (o->next && o->next->size<0)   // see if we can add into next block
641    {
642      if (o->next==slast)
643        slast=o;
644      o->size+=-o->next->size+sizeof(memory_node);
645      o->next=o->next->next;
646    }
647
648    memory_node *n=sfirst;
649    for (;n && n!=o;n=n->next) last=n;
650#ifdef MEM_CHECK
651    if (!n) { printf("Free static big block error\n"); }
652#endif
653   
654    if (last && last->size<0)
655    {
656      if (o==slast) slast=last;
657      last->next=o->next;
658      last->size-=o->size+sizeof(memory_node); 
659    } else o->size=-o->size;           
660  } 
661}
662
663
664void jmalloc_uninit()
665{
666  for (int i=0;i<bmanage_total;i++)
667  {
668    switch (bmanage[i].block_type)
669    {
670      case HI_BLOCK :
671      { free(bmanage[i].addr); } break;
672#ifdef __WATCOMC__     
673      case LOW_BLOCK :
674      { free_low_memory(bmanage[i].addr); } break;
675#endif     
676    }
677  }
678  bmanage_total=0;
679}
680
681void jmem_cleanup(int ret, void *arg)
682{ jmalloc_uninit(); }
683
684 
685int jmalloc_max_size=3072000;
686int jmalloc_min_low_size=0x1000;
687char *not_enough_total_memory_message="Memory manager : Sorry you do not have enough memory available to\n"
688                                       "                 run this program.\n"
689                                       "    DOS users  : Remove any TSR's and device drivers you can.\n"
690                                       "    UNIX users : Do you have a swapfile/partition setup?\n";
691char *not_enough_low_memory_message="Memory Manager : Not enough low memory available (%d : need %d)\n"
692                                   "  Suggestions...\n"
693                                   "    - make a boot disk\n"
694                                   "    - remove TSR's  & drivers not needed by ABUSE\n"
695                                   "    - add memory to your system\n";
696
697void jmalloc_init(long min_size)
698{
699  if (bmanage_total)
700    fprintf(stderr,"warning : jmalloc_init called twice\n");
701  else
702  {
703//    exit_proc(jmem_cleanup,jmalloc_uninit);          // make sure memory gets freed up on exit
704    void *mem;
705
706#ifdef __POWERPC__
707    long size=jmalloc_max_size-0x10000;
708    for (mem=NULL;!mem && size>0x10000;)
709    {
710      mem=malloc(size+0x10000);
711      if (!mem) size-=0x100;       
712    }
713    free(mem);
714    mem = malloc(size);
715#else
716    long size=jmalloc_max_size;
717    for (mem=NULL;!mem && size>0x4000;)
718    {
719      mem=malloc(size);
720      if (!mem) size-=0x100;       
721    }
722#endif
723    if (mem)
724    {
725                        bmanage[bmanage_total].init(mem,size,HI_BLOCK);
726                        bmanage_total++;     
727                        fprintf(stderr,"Added himem block (%d bytes)\n",size);
728    }
729
730/*    bmanage[bmanage_total].init(malloc(2039552),2039552,HI_BLOCK);
731    bmanage_total++;     
732    bmanage[bmanage_total].init(malloc(150224),150224,HI_BLOCK);
733    bmanage_total++;      */
734
735
736
737#ifdef __WATCOMC__
738    if (size!=jmalloc_max_size)
739    {
740      do
741      {
742                                size=low_memory_available();
743                                if (size>jmalloc_min_low_size+0x1000)              // save 64K for misc low memory needs
744                                {
745                                  bmanage[bmanage_total].init(alloc_low_memory(size-jmalloc_min_low_size-0x1000),size-jmalloc_min_low_size-0x1000,LOW_BLOCK);
746                                  bmanage_total++;
747                                  fprintf(stderr,"Added low memory block (%d bytes)\n",size);
748                                }
749      } while (size>jmalloc_min_low_size+0x1000);
750      if (size<jmalloc_min_low_size)
751      {
752                                fprintf(stderr,not_enough_low_memory_message,size,jmalloc_min_low_size);
753                                exit(0);
754      }
755    }
756#endif
757 
758
759    fprintf(stderr,"Memory available : %d\n",j_available());
760    if (j_available()<min_size)
761    {
762      fprintf(stderr,not_enough_total_memory_message);
763      exit(0);
764    }
765
766  }
767}
768
769
770long j_available()
771{
772  long size=0;
773  for (int i=0;i<bmanage_total;i++)
774    size+=bmanage[i].available();
775  return size;
776}
777
778long j_allocated()
779{
780  long size=0;
781  for (int i=0;i<bmanage_total;i++)
782    size+=bmanage[i].allocated();
783  return size;
784}
785
786
787void *jmalloc(long size, char *name)
788
789  if (!bmanage_total)
790    return malloc(size);
791
792  size=(size+3)&(0xffffffff-3);
793  do
794  {
795    for (int i=0;i<bmanage_total;i++)
796    {
797      void *a;
798      if (alloc_space==ALLOC_SPACE_STATIC)
799        a=bmanage[i].static_alloc(size,name);
800      else
801        a=bmanage[i].cache_alloc(size,name);
802      if (a) return a;
803    }
804    free_up_memory();
805  } while (1); 
806}
807
808void jfree(void *ptr)
809{
810  if (ptr == NULL)
811    return;
812  if (!bmanage_total)
813  {
814    free(ptr);
815    return ;
816  }
817  for (int i=0;i<bmanage_total;i++)
818    if (ptr>=(void *)bmanage[i].sfirst)  // is the pointer in this block?
819    {
820      if (ptr<=(void *)bmanage[i].slast)  // is it in static space?
821      {
822        bmanage[i].static_free(ptr);
823        return ;
824      } else if (ptr<=(void *)(((char *)bmanage[i].sfirst)+bmanage[i].block_size))  // or cache space?
825      {
826        bmanage[i].cache_free(ptr);
827        return ;
828      }
829    }
830
831  free (ptr); 
832//  fprintf(stderr,"jfree : bad pointer\n");
833}
834
835
836void *jrealloc(void *ptr, long size, char *name)
837
838  if (!ptr) return jmalloc(size,name);
839  if (!bmanage_total) { return realloc(ptr,size); }
840
841  if (size==0) { jfree(ptr); return NULL; }
842
843  long old_size=0;
844  for (int i=0;i<bmanage_total;i++)
845    if (ptr>=(void *)bmanage[i].sfirst &&
846        ptr<=(void *)(((char *)bmanage[i].sfirst)+bmanage[i].block_size))
847    {
848      old_size=bmanage[i].pointer_size(ptr); 
849      if (ptr<=(void *)bmanage[i].slast)
850      {
851        int sp=alloc_space; sp=ALLOC_SPACE_STATIC;
852        void *nptr=jmalloc(size,name);
853        if (size>old_size)
854          memcpy(nptr,ptr,old_size);
855        else memcpy(nptr,ptr,size);
856        bmanage[i].static_free(ptr);
857        alloc_space=sp;
858        return nptr;
859      } else
860      {
861        int sp=alloc_space; sp=ALLOC_SPACE_CACHE;
862        void *nptr=jmalloc(size,name);
863        if (size>old_size)
864          memcpy(nptr,ptr,old_size);
865        else memcpy(nptr,ptr,size);
866        bmanage[i].cache_free(ptr);
867        alloc_space=sp;
868        return nptr;
869      }
870    }
871  fprintf(stderr,"jrealloc : bad pointer\n");
872  return NULL;
873}
874
875void dmem_report()
876{
877  mem_report("debug.mem");
878}
879
880
881void mem_report(char *filename)
882{
883  FILE *fp=fopen(filename,"wb");
884  for (int i=0;i<bmanage_total;i++)
885    bmanage[i].report(fp);
886  fclose(fp);
887}
888
889void *operator new( size_t size)
890
891  return jmalloc(size,"::new object");
892}
893
894void operator delete(void *ptr)
895{
896  jfree(ptr);
897}
898
899
900long small_ptr_size(void *ptr)
901{
902  return ((small_block *)(((long *)ptr)[-1]))->size;
903}
904
905
906int valid_ptr(void *ptr)
907{
908  if (!bmanage_total) { return 0; }
909  for (int i=0;i<bmanage_total;i++)
910    if (ptr>=(void *)bmanage[i].sfirst)  // is the pointer in this block?
911    {
912      if (ptr<=(void *)bmanage[i].slast)  // is it in static space?
913      {
914        return bmanage[i].valid_static_ptr(ptr);
915      } else if (ptr<=(void *)(((char *)bmanage[i].sfirst)+bmanage[i].block_size))  // or cache space?
916      {
917        return bmanage[i].valid_cache_ptr(ptr);
918      }
919    }
920
921  return 0;
922}
923
Note: See TracBrowser for help on using the repository browser.