home *** CD-ROM | disk | FTP | other *** search
- /*
- * Sensible malloc and free() for use with microemacs for the Mac.
- *
- * Source: These routines are for the most part adaptations of
- * the storage allocator example program from pages 173-177
- * of "The C Programming Language" by Brian Kernighan and
- * Dennis M. Ritchie, Prentice-Hall Software Series, 1978
- *
- * These routines do somewhat more than memory allocation, too.
- * In this module I attempt to limit the amount of memory malloced,
- * and to reserve a minimum amount of memory for the operating
- * system to use. NOTE: the memory reserved to the operating system
- * contains the actual code of the program, among other things!
- */
-
- #define MICROEMACS
-
- #ifdef MICROEMACS
- extern long envram;
- #endif
-
- #ifndef macintosh /* MPW */
- #ifndef MPU68000 /* Aztec */
- #define LSC /* Yuch! */
- #endif
- #endif
-
- extern long malloc_safety;
-
- #ifdef LSC
- #define FreeMem xxFreeMem
- #define NewPtr xxNewPtr
- long FreeMem()
- {
- asm{
- dc.w 0xA01C
- }
- }
- char *NewPtr(size)
- long size;
- {
- asm{
- move.l size,d0
- dc.w 0xA11E
- move.l a0,d0
- }
- }
- #else
- long FreeMem();
- char *NewPtr();
- #include <Strings.h>
- #endif
-
- #ifndef NULL
- #define NULL 0L
- #endif
-
- typedef long ALIGN;
- union header{
- struct{
- union header *ptr;
- long size;
- } s;
- ALIGN x;
- };
- typedef union header HEADER;
-
- static HEADER base;
- static HEADER *allocp = NULL;
-
- #define NALLOC 128L
- static HEADER *morecore(nu)
- unsigned long nu;
- {
- char *sbrk();
- register char *cp;
- register HEADER *up;
- register long rnu;
- register long s;
-
- rnu = NALLOC * ((nu+NALLOC-1L)/NALLOC);
- if (FreeMem() < malloc_safety) return NULL;
- cp = NewPtr(rnu*(long)sizeof(HEADER));
- #ifdef MICROEMACS
- envram += rnu*(long)sizeof(HEADER);
- #endif
- if(cp == NULL) return NULL;
- up = (HEADER *)cp;
- up->s.size = rnu;
- free((char *)(up + 1));
- return(allocp);
- }
-
- #ifndef macintosh /* MPW C uses long ints, others use short ones. */
- char *malloc(nbytes)
- unsigned int nbytes;
- {
- char *lmalloc();
- return lmalloc((long)nbytes);
- }
- char *lmalloc(nbytes)
- #else
- char *malloc(nbytes)
- #endif
- unsigned long nbytes;
- {
- HEADER *morecore();
- register HEADER *p,*q;
- register long nunits;
-
- nunits = 1L+(nbytes+(long)sizeof(HEADER)-1L)/(long)sizeof(HEADER);
- if ((q = allocp) == NULL){
- base.s.ptr = allocp = q = &base;
- base.s.size = 0;
- }
- for(p = q->s.ptr; ;q=p, p=p->s.ptr){
- if(p->s.size >= nunits){
- if(p->s.size == nunits)
- q->s.ptr = p->s.ptr;
- else{
- p->s.size -= nunits;
- p += p->s.size;
- p->s.size = nunits;
- }
- allocp = q;
- return((char *)(p + 1));
- }
- if (p == allocp)
- if ((p = morecore(nunits))==NULL){
- return(NULL);
- }
- }
- }
- free(ap)
- char *ap;
- {
- register HEADER *p,*q;
- if(ap == NULL){ /* Manifest programmer error. */
- return;
- }
- p = (HEADER *)ap - 1;
- for (q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr)
- if (q >= q->s.ptr && (p > q || p < q->s.ptr))
- break;
- if (p + p->s.size == q->s.ptr){
- p->s.size += q->s.ptr->s.size;
- p->s.ptr = q->s.ptr->s.ptr;
- }
- else
- p->s.ptr = q->s.ptr;
- if (q + q->s.size == p){
- q->s.size += p->s.size;
- q->s.ptr = p->s.ptr;
- }
- else
- q->s.ptr = p;
- allocp = q;
- }
-