OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [libgloss/] [microblaze/] [xil_malloc.c] - Blame information for rev 207

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/* Copyright (c) 1995, 2002, 2009 Xilinx, Inc.  All rights reserved.
2
 
3
   Redistribution and use in source and binary forms, with or without
4
   modification, are permitted provided that the following conditions are
5
   met:
6
 
7
   1.  Redistributions source code must retain the above copyright notice,
8
   this list of conditions and the following disclaimer.
9
 
10
   2.  Redistributions in binary form must reproduce the above copyright
11
   notice, this list of conditions and the following disclaimer in the
12
   documentation and/or other materials provided with the distribution.
13
 
14
   3.  Neither the name of Xilinx nor the names of its contributors may be
15
   used to endorse or promote products derived from this software without
16
   specific prior written permission.
17
 
18
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
19
   IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
   TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21
   PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24
   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 
30
*/
31
 
32
#ifdef DEBUG
33
#include <stdlib.h>
34
#include <stddef.h>
35
#include <stdio.h>
36
#else
37
typedef unsigned int size_t;
38
#define NULL 0
39
#endif
40
 
41
#define sbrk xil_sbrk
42
 
43
/* The only extern functions I need if not printing. */
44
extern  void* sbrk(size_t incr);
45
extern  void *memcpy(void *s1, const void *s2, size_t n);
46
extern  void *memset(void *s, int c, size_t n);
47
 
48
 
49
typedef unsigned char BOOLEAN;
50
const BOOLEAN FALSE=0;
51
const BOOLEAN TRUE =1;
52
 
53
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
54
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
55
 
56
#define M_DBG_NORMAL 0
57
#define M_DBG_PARTIAL 1
58
#define M_DBG_FULL 2
59
 
60
/* debugging breakpoint aids */
61
static char xil_mem_null_free[] = "xil_mem_null_free";
62
static char xil_mem_chkcnt   [] = "xil_mem_chkcnt";
63
 
64
/* Flag values describing the state of a memory block.
65
/* Indicator for allocated blk */
66
#define M_ALLOCEDFLAG 0x5a
67
/* End-of-block if debug level */
68
#define M_ALLOCED 0xc99cc99c
69
/* Free block indicator. */
70
#define M_FREEFLAG 0xa5
71
/* End-of-block if debug level */
72
#define M_FREE 0x9cc99cc9
73
/* Zero length block. */
74
#define M_ZEROFLAG 0xaa
75
 
76
/* Header of a memory block. */
77
typedef unsigned char DATA_T;
78
typedef DATA_T *      DATA_P;
79
struct M_HEADER
80
{
81
  unsigned       dbglev:2;       /* Debug level this was created with. */
82
  unsigned       size:22;        /* Size of block / 8. 32 Meg max. */
83
  unsigned       flag:8;         /* Indicates whether allocated or freed. */
84
};
85
typedef struct M_HEADER* M_HEADERP;
86
 
87
BOOLEAN isalloced(M_HEADERP this)
88
{
89
  return this->flag == M_ALLOCEDFLAG;
90
}
91
BOOLEAN isfree(M_HEADERP this)
92
{
93
  return this->flag == M_FREEFLAG;
94
}
95
BOOLEAN iszero(M_HEADERP this)
96
{
97
  return this->flag == M_ZEROFLAG;
98
}
99
 
100
void           setalloced(M_HEADERP this)     { this->flag = M_ALLOCEDFLAG; }
101
void           setfree(M_HEADERP this)        { this->flag = M_FREEFLAG; }
102
void           setzero(M_HEADERP this)        { this->flag = M_ZEROFLAG; }
103
 
104
int            getdbglev(M_HEADERP this)      { return this->dbglev; }
105
void           setdbglev(M_HEADERP this, int d) { this->dbglev = d; }
106
 
107
size_t         getsize(M_HEADERP this)        { return this->size << 3; }  /* Alignment is 8. */
108
void           setsize(M_HEADERP this, size_t s){ this->size = s >> 3; }
109
 
110
DATA_T *       getend(M_HEADERP this)         { return (((DATA_T *)this)+getsize(this)); }
111
 
112
/* Next pointer is after data in block. */
113
M_HEADERP     getnext(M_HEADERP this)        { return *(((M_HEADERP*)getend(this)) - 1); }
114
void           setnext(M_HEADERP this, M_HEADERP n) { *(((M_HEADERP*)getend(this)) - 1) = n; }
115
 
116
/* Routines used to set a flag at end of block if debuglevel != normal. */
117
/* Sentinel is right BEFORE the next pointer. */
118
unsigned long* getsentinel(M_HEADERP this);
119
void           setsentinel(M_HEADERP this, unsigned long lflag);
120
BOOLEAN        testsentinel(M_HEADERP this, unsigned long lflag);
121
 
122
/* Routines to handle data.  Depend on debug level. */
123
DATA_T *       getdata(M_HEADERP this)        { return (((DATA_T*)this)+sizeof(*this)); }
124
size_t         getdatasize(M_HEADERP this);
125
 
126
/* Fill data with a pattern. */
127
void           setdata(M_HEADERP this, int f);
128
 
129
/* Debug routines */
130
BOOLEAN        checkalloc(M_HEADERP this);    /* Is this a valid allocated memory pointer? */
131
BOOLEAN        checkfree(M_HEADERP this);     /* Is this a valid freelist entry? */
132
 
133
 
134
 
135
/* Get length of data. */
136
size_t
137
getdatasize(M_HEADERP this)
138
{
139
  /* By default, size is size of block - size of header. */
140
  int tmp_size = getsize(this) - sizeof(struct M_HEADER);
141
 
142
  if (this->dbglev != M_DBG_NORMAL)
143
    {
144
      /* Subtract size of sentinel, and next pointer. */
145
      tmp_size -= sizeof(long) + sizeof(M_HEADERP);
146
      /* If only eight bytes, no room for sentinel. */
147
      if (tmp_size < 0)
148
        tmp_size = 0;
149
    }
150
  else
151
    {
152
      /* Free block always has a next pointer.  Otherwise not. */
153
      if (isfree(this))
154
        tmp_size -= sizeof(M_HEADERP);
155
    }
156
  return tmp_size;
157
}
158
 
159
/* Set the data buffer to value f. */
160
void
161
setdata(M_HEADERP this, int f)
162
{
163
  memset(getdata(this), f, getdatasize(this));
164
}
165
 
166
/* At the end of the block, there may be a longword with
167
   special meaning.  This is the sentinel.  If there is a sentinel,
168
   there is by definition a next pointer. */
169
unsigned long*
170
getsentinel(M_HEADERP this)
171
{
172
  DATA_T* addr = (getend(this) - sizeof(M_HEADERP)); /* location of next pointer. */
173
  if (getdata(this) < addr)
174
    return ((unsigned long*)addr) - 1;        /* Right before next pointer. */
175
  else
176
    return NULL;                      /* Block too small.  No room for sent. */
177
}
178
 
179
void
180
setsentinel(M_HEADERP this, unsigned long lflag)
181
{
182
  unsigned long* addr = getsentinel(this);
183
  if (addr)
184
    *addr = lflag;
185
}
186
 
187
BOOLEAN
188
testsentinel(M_HEADERP this, unsigned long lflag)
189
{
190
  unsigned long* addr = getsentinel(this);
191
  if (addr)
192
    return *addr == lflag;
193
  else
194
    return TRUE;
195
}
196
 
197
/*  sizeof(struct M_HEADER)+sizeof(M_HEADERP);  Alignment */
198
#define M_BLOCKSIZE 8
199
/*  4096 / 8; // M_BLOCKSIZE ;      Number of freelist entries. */
200
#define M_FREESIZE 512
201
/*  64 * 1024;                 Size of incremental memory hunks allocated, */
202
#define M_BRKINC 2048
203
 
204
static M_HEADERP freelist[M_FREESIZE];       /* Free list. */
205
 
206
static M_HEADERP alloclist = NULL;           /* Pointer to linked list
207
                                                of Allocated blocks. */
208
static int mdebuglevel = M_DBG_NORMAL;
209
 
210
static DATA_T zerobuf[M_BLOCKSIZE] = { M_ZEROFLAG, M_ZEROFLAG, M_ZEROFLAG,
211
                                       M_ZEROFLAG, M_ZEROFLAG, M_ZEROFLAG,
212
                                       M_ZEROFLAG, M_ZEROFLAG };
213
static M_HEADERP zeroblock = (M_HEADERP)zerobuf;
214
 
215
static unsigned long totalallocated = 0;        /* NOT actually malloced, but
216
                                                   rather the size of the pool. */
217
 
218
static unsigned long totalmalloc = 0;           /* Total amount malloced. */
219
 
220
static unsigned long highwater = 0;             /* Largest amount of memory
221
                                                   allocated at any time. */
222
static long nummallocs = 0;
223
static long numfrees = 0;
224
static long numreallocs = 0;
225
 
226
int m_prtflag  = 0;
227
int m_stopaddr = 0;
228
int m_stopcnt  = 0;
229
int m_reenter  = 0;
230
static int m_curcount = 0;
231
 
232
M_HEADERP
233
getmemblock(size_t n)
234
{
235
  M_HEADERP block = (M_HEADERP) sbrk(n);
236
  if (block != NULL)
237
    totalallocated += n;
238
 
239
  return block;
240
}
241
 
242
 
243
static BOOLEAN
244
die (char* msg)
245
{
246
  mdebuglevel = M_DBG_NORMAL;
247
#ifdef DEBUG
248
  printf ("%s\n", msg);
249
  exit (1);
250
#else
251
  /* Go into infinite loop. */
252
  for (;;)
253
    ;
254
#endif
255
  return FALSE;
256
}
257
 
258
int
259
getfreeindex(size_t size)
260
{
261
  return MIN(size / M_BLOCKSIZE, M_FREESIZE - 1);
262
}
263
 
264
static
265
void coalesce(M_HEADERP h)
266
{
267
  /* Coalesce block h with free block any free blocks after it.
268
     Assumes that H is currently allocated.  Sentinel at end is
269
     set to allocated so if H is free, caller has to fix it. */
270
  for (;;)
271
    {
272
      long i;
273
      M_HEADERP f;
274
      M_HEADERP next = (M_HEADERP)getend(h);
275
 
276
      if (next || isalloced(next))
277
        break; /* no more coalscing can be done. */
278
 
279
      /* Take it off the free list. */
280
      i = getfreeindex(getsize(next));
281
      f = freelist[i];
282
      if (f == next)
283
        freelist[i] = getnext(next);
284
      else
285
        {
286
          while (f != NULL && getnext(f) != next)
287
            f = getnext(f);
288
 
289
          /* Didn't find it in the free list. */
290
          if (f == NULL)
291
            die ("Coalesce failed.");
292
 
293
          setnext(f, getnext(next));
294
        }
295
 
296
      /* Add two blocks together and start over. */
297
      setsize(h, getsize(h) + getsize(next));
298
 
299
      if (getdbglev(h) > M_DBG_NORMAL)
300
        {
301
          setsentinel(h, M_ALLOCED);
302
        }
303
    } /* forever */
304
}
305
 
306
BOOLEAN
307
checkalloc(M_HEADERP this)
308
{
309
  if (!isalloced(this))
310
    return die ("checkalloc: pointer header clobbered.");
311
 
312
  if (getdbglev(this) > M_DBG_NORMAL)
313
    {
314
      if (!testsentinel(this, M_ALLOCED))
315
        return die ("checkalloc: pointer length overrun.");
316
    }
317
  return TRUE;
318
}
319
 
320
BOOLEAN
321
checkfree(M_HEADERP this)
322
{
323
  DATA_T *d;
324
  int i;
325
  if (!isfree(this))
326
    die ("checkfree: pointer header clobbered.");
327
 
328
  if (getdbglev(this) > M_DBG_NORMAL)
329
    {
330
      if (!testsentinel(this, M_FREE))
331
        die ("checkfree: pointer length overrun.");
332
 
333
      d = getdata(this);
334
      i = getdatasize(this);
335
      while (i-- > 0) {
336
        if (*d++ != M_FREEFLAG)
337
          die("checkfree: freed data clobbered.");
338
      }
339
    }
340
  return TRUE;
341
}
342
 
343
static void
344
checkfreelist()
345
{
346
  long i;
347
  for (i = 0; i < M_FREESIZE; i += 1)
348
    {
349
      M_HEADERP h = (M_HEADERP) freelist[i];
350
      while (h != NULL)
351
        {
352
        checkfree(h);
353
        if (i != (M_FREESIZE - 1) && getsize(h) != (i * M_BLOCKSIZE))
354
          die ("checkfreelist: free list size mismatch.");
355
        h = getnext(h);
356
        }
357
    }
358
}
359
 
360
static void
361
checkalloclist()
362
{
363
  M_HEADERP a = (M_HEADERP) alloclist;
364
  while (a != NULL)
365
    {
366
      checkalloc(a);
367
      a = getnext(a);
368
    }
369
}
370
 
371
/* Free a block of memory.  This is done by adding to the free list. */
372
static void
373
addtofreelist (M_HEADERP h)
374
{
375
  long i;
376
  /* Merge freed blocks together. */
377
  coalesce(h);
378
 
379
  /* link this block to the front of the appropriate free list. */
380
  i = getfreeindex(getsize(h));
381
  setnext(h, freelist[i]);
382
  freelist[i] = h;
383
 
384
  /* Set the flag info. */
385
  setfree(h);
386
  setdbglev(h, mdebuglevel);
387
  if (mdebuglevel > M_DBG_NORMAL)
388
    {
389
      /* Fill with some meaningful (and testable) data. */
390
      setdata(h, M_FREEFLAG);
391
      setsentinel(h, M_FREE);
392
    }
393
}
394
 
395
void
396
xil_malloc_verify()
397
{
398
  int i;
399
  for ( i = 0; i < M_BLOCKSIZE; i += 1)
400
    {
401
      if (zerobuf[i] != M_ZEROFLAG)
402
        die ("malloc_verify: Zero block clobbered.");
403
    }
404
  checkfreelist();
405
  checkalloclist();
406
}
407
 
408
void
409
xil_malloc_debug (int level)
410
{
411
  mdebuglevel = MAX (M_DBG_NORMAL, MIN (M_DBG_FULL, level));
412
}
413
 
414
void*
415
xil_malloc (size_t nbytes)
416
{
417
  int i;
418
  int minf;
419
  int maxf;
420
  size_t msize;
421
  M_HEADERP p;
422
  M_HEADERP h;
423
 
424
  nummallocs += 1;
425
 
426
  if (nbytes == 0)
427
    return getdata(zeroblock);
428
 
429
  if (mdebuglevel == M_DBG_FULL)
430
    {
431
#ifdef DEBUG
432
      static unsigned do_cnt = ~0;
433
      static unsigned done_cnt = 0;
434
      if (do_cnt == ~0)
435
        {
436
          char *x = (char *)getenv(xil_mem_chkcnt);
437
          do_cnt = 1;
438
          if (x)
439
            do_cnt = atoi(x);
440
        }
441
      if (do_cnt == 1 || done_cnt % do_cnt == 0)
442
        xil_malloc_verify();
443
      done_cnt++;
444
#else
445
      xil_malloc_verify();
446
#endif
447
    }
448
 
449
  nbytes += sizeof (struct M_HEADER);
450
 
451
  /* If debug, leave room for flag and next pointer. */
452
  if (mdebuglevel > M_DBG_NORMAL)
453
    nbytes += sizeof (long) + sizeof (M_HEADERP*);
454
 
455
  /* Round up to allocation unit */
456
  msize = ((nbytes + M_BLOCKSIZE - 1) / M_BLOCKSIZE) * M_BLOCKSIZE;
457
 
458
  /* Look around for a block of approximately the right size. */
459
  h = NULL;
460
  minf = getfreeindex(msize);
461
  maxf = MIN(minf * 2, M_FREESIZE);
462
 
463
  for (i = minf; i < M_FREESIZE; i += 1)
464
    {
465
      if (i >= maxf)
466
        i = M_FREESIZE - 1;    /* Skip over blocks too large. */
467
 
468
      h = freelist[i];
469
      p = NULL;       /* Previous. */
470
      while (h != NULL)
471
        {
472
          if (getsize(h) >= nbytes)
473
            {
474
              /* Take h out of linked list */
475
              if (p)
476
                setnext(p, getnext(h));
477
              else
478
                freelist[i] = getnext(h);
479
 
480
              if (!isfree(h))
481
                die ("malloc: freelist clobbered.\n");
482
 
483
              goto gotit;
484
            }
485
          else
486
            {
487
              p = h;
488
              h = getnext(h);
489
            }
490
        }
491
    }
492
 
493
  /* Didn't find any free pointers.  Allocate more heap.
494
     Round up to next heap increment. */
495
  i = ((msize + sizeof(long) + M_BRKINC - 1) / M_BRKINC) * M_BRKINC;
496
  if ((h = getmemblock (i)) == NULL)
497
    {
498
#ifdef DEBUG
499
      printf ("xil_malloc: Out of dynamic memory.\n");
500
#endif
501
      return NULL;
502
    }
503
 
504
  /* Mark end of block with zero for four bytes so we don't merge next block
505
     into free list accidentally. */
506
  setsize(h, i - sizeof(long));
507
  *((long*)getend(h)) = 0;
508
 
509
 gotit:
510
  /* Merge allocated blocks so we can free a bigger part of what is left! */
511
  coalesce(h);
512
  if (getsize(h) >= msize + M_BLOCKSIZE)
513
    {
514
      M_HEADERP r;
515
      int rsize;
516
      /* add the remainder of this block to the free list. */
517
      rsize = getsize(h) - msize;
518
      r = (M_HEADERP) (((DATA_T *)h) + msize);
519
      setsize (r, rsize);
520
      setsize (h, msize);
521
      addtofreelist (r);
522
    }
523
 
524
  setalloced(h);
525
  setdbglev(h, mdebuglevel);
526
  if (mdebuglevel > M_DBG_NORMAL)
527
    {
528
      // Chain into alloc'd list and set sentinel. */
529
      setsentinel(h, M_ALLOCED);
530
      setnext(h, alloclist);
531
      alloclist = h;
532
    }
533
 
534
#ifdef DEBUG
535
  if (!m_reenter && m_prtflag)
536
    {
537
      m_reenter = 1;
538
      printf("%d      malloc\n",h+1);
539
      fflush(stdout);
540
      if (m_stopaddr)
541
        {
542
          if ((DATA_T *)m_stopaddr == getdata(h))
543
            {
544
              if (m_stopcnt == ++m_curcount)
545
                exit(10);
546
            }
547
        }
548
      m_reenter = 0;
549
    }
550
#endif
551
 
552
  totalmalloc += getsize(h);
553
  if (totalmalloc > highwater)
554
    highwater = totalmalloc;
555
 
556
  return getdata(h);
557
}
558
 
559
void
560
xil_free(void* ap)
561
{
562
  M_HEADERP h;
563
  numfrees += 1;
564
 
565
  if (ap == NULL)
566
   {
567
#ifdef DEBUG
568
     if (mdebuglevel != M_DBG_NORMAL && getenv(xil_mem_null_free))
569
       die ("free: tried to free NULL pointer.");
570
     else
571
       return;        /* Let `em do it. */
572
#else
573
     return;
574
#endif
575
   }
576
 
577
  /* Drop through to here if not a smartheap allocation.  This
578
     handles free of both xil_malloc and libc malloc. */
579
 
580
  h = (M_HEADERP) (((DATA_T *)ap) - sizeof (struct M_HEADER));
581
 
582
  if (h == zeroblock)
583
    return;
584
 
585
#ifdef DEBUG
586
  if (!m_reenter && m_prtflag) {
587
    m_reenter = 1;
588
    printf("%d      mfree\n",h+1);
589
    fflush(stdout);
590
    m_reenter = 0;
591
  }
592
#endif
593
 
594
  if (!isalloced(h)) {
595
    if (isfree(h))
596
      die ("free: tried to free pointer twice.");
597
    else
598
      die ("free: tried to free a block not allocated by malloc.");
599
    return;
600
  }
601
 
602
  if (getdbglev(h) > M_DBG_NORMAL)
603
    {
604
      /* Make sure things look reasonable. */
605
      checkalloc(h);
606
 
607
      /* Try to find the pointer in the alloc list. */
608
      if (alloclist == h)
609
        alloclist = getnext(h);
610
      else
611
        {
612
          M_HEADERP a = alloclist;
613
          while (a != NULL && getnext(a) != h)
614
            a = getnext(a);
615
 
616
          /* If a is NULL, debuglevel must have been reset at some point. */
617
          if (a != NULL)
618
            setnext(a, getnext(h));
619
        }
620
    }
621
 
622
  totalmalloc -= getsize(h);
623
 
624
  addtofreelist (h);
625
 
626
  if (mdebuglevel == M_DBG_FULL)
627
    {
628
#ifdef DEBUG
629
      static unsigned do_cnt = ~0;
630
      static unsigned done_cnt = 0;
631
      if (do_cnt == ~0)
632
        {
633
          char *x = (char *)getenv(xil_mem_chkcnt);
634
          do_cnt = 1;
635
          if (x)
636
            do_cnt = atoi(x);
637
        }
638
      if (do_cnt == 1 || done_cnt % do_cnt == 0)
639
        xil_malloc_verify();
640
      done_cnt++;
641
#else
642
      xil_malloc_verify();
643
#endif
644
    }
645
}
646
 
647
unsigned
648
xil_msize (void* ap)
649
{
650
  M_HEADERP h = (M_HEADERP) (((DATA_T *)ap) - sizeof (struct M_HEADER));
651
  return getdatasize(h);
652
}
653
 
654
void*
655
xil_realloc (void* oldblk, size_t newsize )
656
{
657
  M_HEADERP h;
658
  size_t oldsize;
659
  void* newblk;
660
 
661
  numreallocs += 1;
662
 
663
  if (oldblk == NULL)
664
    {
665
      if (mdebuglevel != M_DBG_NORMAL)
666
        die ("realloc: tried to realloc NULL pointer.");
667
      else
668
        return xil_malloc(newsize);        /* Don't need to copy anything. */
669
    }
670
 
671
  /* Make sure this is a valid block. */
672
  h = (M_HEADERP) (((char*)oldblk) - sizeof (struct M_HEADER));
673
 
674
  /* if old block was zero bytes, just alloc a new one. */
675
  if (h == zeroblock)
676
    return xil_malloc(newsize);           /* Source is empty anyway. */
677
 
678
  /* If old block was already freed, error. */
679
  if (isfree(h))
680
    die ("realloc: tried to realloc freed pointer.");
681
 
682
  if (!isalloced(h))
683
    {
684
      long* pdesc = *(long**)h;         /* Get pointer to the block descriptor. */
685
      long* pnextdesc = (long*)*pdesc;
686
      if ((pdesc[1] & ~3) != (long)h)   /* Should point back to block. */
687
        die ("realloc: header clobbered.");
688
 
689
      /* This must be a libc block.  We need to figure out how big it is.
690
         Length of block is delta between two descriptors - sizeof (void*). */
691
 
692
      oldsize = (size_t) ((pnextdesc[1] & ~3) - (pdesc[1] & ~3)-sizeof(void*));
693
 
694
      /* Don't bother to change anything unless there's not enough room. */
695
      if (oldsize < newsize)
696
        {
697
          /* Alloc a new block with our malloc. */
698
          if ((newblk = xil_malloc(newsize)) == NULL )
699
            return NULL ;
700
 
701
          /* Copy the old data to it. */
702
          memcpy (newblk, oldblk, (newsize < oldsize) ? newsize : oldsize);
703
          xil_free(oldblk);
704
          return newblk;
705
        }
706
    }
707
 
708
  /* If the new size is bigger than my allocated
709
     size, or if more than 1/4 of the block would be left free, allocate
710
     a new block and copy the data.  Otherwise, leave well enough alone. */
711
 
712
  coalesce(h);
713
 
714
  oldsize = getdatasize(h);
715
 
716
  if (oldsize < newsize
717
      || (newsize > (2*M_BLOCKSIZE) && (newsize*4) < (oldsize*3)))
718
    {
719
      if (( newblk = xil_malloc( newsize )) == NULL )
720
        return NULL ;
721
 
722
      memcpy (newblk, oldblk, (newsize < oldsize) ? newsize : oldsize);
723
 
724
      xil_free (oldblk);
725
      return newblk;
726
    }
727
  else
728
    return oldblk;
729
}
730
 
731
void*
732
xil_calloc (size_t number, size_t size)
733
{
734
  long*  longptr ;
735
  void*  blockptr ;
736
  size_t temp   = number * size + sizeof (long) - 1;
737
  temp -= temp % sizeof (long);
738
 
739
  blockptr = xil_malloc( temp );
740
  if ( blockptr != 0 )
741
    {
742
      longptr = (long*) blockptr ;
743
      temp /= sizeof (long);
744
      while ( temp-- > 0 )
745
        {
746
          *longptr++ = 0 ;
747
        }
748
    }
749
  return blockptr ;
750
}
751
 
752
#define M_STAT_NORMAL 0
753
#define M_STAT_VERBOSE 1
754
#define M_STAT_REALLYVERBOSE 2
755
 
756
#ifdef DEBUG
757
void
758
xil_mstats(int verbosity)
759
{
760
  unsigned long totalfree = 0;
761
  int i;
762
  printf("Memory Statics:\n"
763
         "---------------\n");
764
  printf("   Number of calls to malloc:   %ld.\n", nummallocs);
765
  printf("   Number of calls to free:     %ld.\n", numfrees);
766
  printf("   Number of calls to realloc:  %ld.\n", numreallocs);
767
  printf("   Total allocated memory:      %lu (0x%lx)\n",
768
         totalallocated, totalallocated);
769
  printf("   Currently malloced memory:   %lu (0x%lx)\n",
770
         totalmalloc, totalmalloc);
771
  fflush(stdout);
772
 
773
 
774
  for (i = 0; i < M_FREESIZE; i += 1)
775
    {
776
      M_HEADERP h = freelist[i];
777
      unsigned long numblocks = 0;
778
      while (h != NULL)
779
        {
780
          totalfree += getsize(h);
781
          numblocks += 1;
782
          h = getnext(h);
783
        }
784
      if (verbosity > M_STAT_NORMAL && numblocks > 0)
785
        {
786
          printf("   There are %d blocks on freelist for size %d\n",
787
                 numblocks, i * M_BLOCKSIZE);
788
          fflush(stdout);
789
        }
790
    }
791
  printf("   Currently free memory:       %lu (0x%lx)\n",
792
         totalfree, totalfree);
793
  printf("   High water mark:             %lu (0x%lx)\n",
794
         highwater, highwater);
795
 
796
  printf("\n");
797
  fflush(stdout);
798
}
799
#else
800
void
801
xil_mstats(int verbosity)
802
{
803
}
804
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.