123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /* M E M O R Y A L L O C A T I O N R O U T I N E S */
- /* The reason for having own memory allocation routines (malloc(),
- realloc() and free()) is plain: the garbage collection performed by
- the library functions malloc(), realloc() and free() costs a lot of
- time, while in most cases (on a VAX) the freeing and reallocation of
- memory is not necessary.
- The (basic) memory allocating routines offered by this memory
- handling package are:
- char *malloc(n) : allocate n bytes
- char *realloc(ptr, n) : reallocate buffer to n bytes
- (works only if ptr was last allocated)
- free(ptr) : if ptr points to last allocated
- memory, this memory is re-allocatable
- This module imports routines from "system", an assertion macro,
- and the compile-time
- constants ALIGNBITS, ALLOCSIZ, DEBUG.
- ALIGNBITS is an integer constant defining suitable alignment,
- ALLOCSIZ is the size of the chunks of memory asked from the system,
- DEBUG enables the assertions.
- */
- #include <assert.h>
- #include <system.h>
- #ifndef ALIGNBITS
- #define ALIGNBITS 07
- #endif
- #ifndef ALLOCSIZ
- #define ALLOCSIZ 4096
- #endif
- /* the following variables are used for book-keeping */
- static int nfreebytes = 0; /* # free bytes in sys_break-ed space */
- static char *freeb = 0; /* pointer to first free byte */
- static char *lastalloc; /* pointer to last malloced sp */
- static int lastnbytes; /* nr of bytes in last allocated space */
- static char *firstfreeb; /* pointer to first ever free byte */
- #define ALIGN(m) (((m)&ALIGNBITS)? (m)+((1+ALIGNBITS)-((m)&ALIGNBITS)):(m))
- char *sys_break();
- char *
- malloc(n)
- unsigned int n;
- {
- /* malloc() is a very simple malloc().
- */
- n = ALIGN(n);
- if (nfreebytes < n) {
- register int nbts = (n <= ALLOCSIZ) ? ALLOCSIZ : n;
- if (!nfreebytes) {
- if (!firstfreeb) {
- /* We arrive here the first time malloc is
- called
- */
- int diff;
- if (!(freeb = sys_break(0))) return 0;
- if ((diff = (int)((long)freeb&ALIGNBITS))!=0) {
- /* align memory to ALIGNBITS ... */
- diff = (1 + ALIGNBITS) - diff;
- if (!(freeb = sys_break(diff))) {
- return 0;
- }
- freeb += diff;
- assert(((long)freeb & ALIGNBITS) == 0);
- }
- firstfreeb = freeb;
- }
- if (!(freeb = sys_break(nbts))) return 0;
- }
- else {
- if (!sys_break(nbts)) return 0;
- }
- nfreebytes += nbts;
- }
- lastalloc = freeb;
- freeb = lastalloc + n;
- lastnbytes = n;
- nfreebytes -= n;
- return lastalloc;
- }
- char *
- realloc(ptr, n)
- char *ptr;
- unsigned int n;
- {
- /* realloc() is designed to append more bytes to the latest
- allocated piece of memory.
- */
- register int nbytes = n;
- if (!ptr || ptr != lastalloc) { /* security */
- return 0;
- }
- nbytes -= lastnbytes; /* # bytes required */
- if (nbytes == 0) { /* no extra bytes */
- return lastalloc;
- }
- /* if nbytes < 0: free last allocated bytes;
- if nbytes > 0: allocate more bytes
- */
- if (nbytes > 0) nbytes = ALIGN(nbytes);
- if (nfreebytes < nbytes) {
- register int nbts = (nbytes < ALLOCSIZ) ? ALLOCSIZ : nbytes;
- if (!sys_break(nbts)) return 0;
- nfreebytes += nbts;
- }
- freeb += nbytes; /* less bytes */
- lastnbytes += nbytes; /* change nr of last all. bytes */
- nfreebytes -= nbytes; /* less or more free bytes */
- return lastalloc;
- }
- free(p)
- char *p;
- {
- if (lastalloc && lastalloc == p) {
- nfreebytes += lastnbytes;
- freeb = lastalloc;
- lastnbytes = 0;
- lastalloc = 0;
- }
- }
- #ifdef DEBUG
- mem_stat()
- {
- printf("Total nr of bytes allocated: %d\n",
- sys_break(0) - firstfreeb);
- }
- #endif DEBUG
|