diff --git a/modules/src/alloc/Malloc.c b/modules/src/alloc/Malloc.c new file mode 100644 index 000000000..97b7cddfd --- /dev/null +++ b/modules/src/alloc/Malloc.c @@ -0,0 +1,59 @@ +/* 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 memory allocation routines offered in this file are: + + char *Malloc(n) : allocate n bytes + char *Srealloc(ptr, n) : reallocate buffer to n bytes + char *Salloc(str, n) : allocate n bytes, initialized with the string + str + + This file imports routines from "system". +*/ + +#include +#include "in_all.h" +#include "alloc.h" + +PRIVATE +m_fatal() { + + (void) sys_write(2, "Out of memory\n", 14); + sys_stop(S_EXIT); +} + +EXPORT char * +Malloc(sz) + unsigned int sz; +{ + char *res = malloc(sz); + + if (res == 0) m_fatal(); + return res; +} + +EXPORT char * +Salloc(str, sz) + register char str[]; + register unsigned int sz; +{ + /* Salloc() is not a primitive function: it just allocates a + piece of storage and copies a given string into it. + */ + char *res = malloc(sz); + register char *m = res; + + if (m == 0) m_fatal(); + while (sz--) + *m++ = *str++; + return res; +} + +EXPORT char * +Srealloc(str, sz) + char str[]; + unsigned int sz; +{ + str = realloc(str, sz); + if (str == 0) m_fatal(); + return str; +} diff --git a/modules/src/alloc/alloc.3 b/modules/src/alloc/alloc.3 new file mode 100644 index 000000000..3a71beb20 --- /dev/null +++ b/modules/src/alloc/alloc.3 @@ -0,0 +1,73 @@ +.TH ALLOC 3ACK "March 25, 1986" +.SH NAME +Malloc, Salloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines +.SH SYNOPSIS +.B #include +.PP +.B char *Malloc(size) +.br +.B unsigned int size; +.PP +.B char *Salloc(str, size) +.br +.B char *str; +.B unsigned int size; +.PP +.B char *Srealloc(str, size) +.br +.B char *str; +.br +.B unsigned int size; +.PP +.B char *st_alloc(phead, size, count) +.br +.B char **phead; +.br +.B unsigned int size; +.PP +.B st_free(ptr, phead, size) +.br +.B char *ptr; +.br +.B char **phead; +.br +.B unsigned int size; +.PP +.SH DESCRIPTION +This set of routines provides a checking memory allocation mechanism. +.PP +\fIMalloc\fR returns a pointer to a block of at least \fIsize\fR +bytes, beginning on a boundary suitable for any data type. +.PP +\fISalloc\fR returns a pointer to a block of at least \fIsize\fR +bytes, initialized with the null-terminated string \fIstr\fR. +.PP +\fISrealloc\fR reallocates +the string at \fIstr\fR to \fIsize\fR bytes. +.PP +All these routines use \fImalloc\fR and \fIrealloc\fR. +\fIFree\fR can be used on pointers returned by these routines. +.PP +\fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists +of structures, whose first field is a pointer called \fBnext\fR. +This field is used to chain free structures together. +\fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field +containing the head of the free list, \fIsize\fR contains the size of the +structures, and \fIcount\fR indicates how many new structures must be allocated +in case the free list is exhausted. +It returns a pointer to a zero-initialized structure. +\fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to +the structure to be freed, \fIphead\fR is again a pointer to a field +containing the head of the free list, and \fIsize\fR again contains the size +of the structures. +These last two routines are best used in a macro. +.SH FILES +.nf +~em/modules/h/alloc.h +~em/modules/lib/liballoc.a +.fi +.SH "SEE ALSO" +malloc(3) +.SH DIAGNOSTICS +\fIMalloc\fR, \fISalloc\fR, \fISrealloc\fR, and \fIst_alloc\fR +give an error message and stop execution if there is no memory available. diff --git a/modules/src/alloc/alloc.h b/modules/src/alloc/alloc.h new file mode 100644 index 000000000..f872971a0 --- /dev/null +++ b/modules/src/alloc/alloc.h @@ -0,0 +1,23 @@ +/* PROGRAM'S INTERFACE TO MEMORY ALLOCATION ROUTINES */ + +/* This file serves as the interface between the program and the + memory allocating routines. + There are 3 memory allocation routines: + char *Malloc(n) allocate n bytes + char *Salloc(str, n) allocate n bytes and fill them with + string str + char *Realloc(str, n) reallocate the string at str to n bytes, + only works if str was last allocated +*/ + +extern char *Salloc(), *Malloc(), *Srealloc(); +extern char *malloc(), *realloc(); + +/* S T R U C T U R E - S T O R A G E D E F I N I T I O N S */ + +#ifndef BOTCH_FREE +#define st_free(ptr, phead, size) (ptr->next = *phead, *phead = ptr) +#else def BOTCH_FREE +#define st_free(ptr, phead, size) (botch((char *)(ptr), size), \ + ptr->next = *phead, *phead = ptr) +#endif BOTCH_FREE diff --git a/modules/src/alloc/botch.c b/modules/src/alloc/botch.c new file mode 100644 index 000000000..e163c2867 --- /dev/null +++ b/modules/src/alloc/botch.c @@ -0,0 +1,20 @@ +/* botch - write garbage over a chunk of memory, useful if you want + to check if freed memory is used inappopriately. +*/ + +#include +#include "in_all.h" + +EXPORT +botch(ptr, n) + char *ptr; + int n; +{ + assert((long)ptr % sizeof (long) == 0); + while (n >= sizeof (long)) { + /* high-speed botch loop */ + *(long *)ptr = 025252525252L; + ptr += sizeof (long), n -= sizeof (long); + } + while (n--) *ptr++ = '\252'; +} diff --git a/modules/src/alloc/clear.c b/modules/src/alloc/clear.c new file mode 100644 index 000000000..ad8d60387 --- /dev/null +++ b/modules/src/alloc/clear.c @@ -0,0 +1,23 @@ +/* clear - clear a block of memory, and try to do it fast. +*/ + +#include +#include "in_all.h" + +/* instead of Calloc: */ +EXPORT +clear(ptr, n) + register char *ptr; + register int n; +{ + register long *q = (long *) ptr; + + assert((long)q % sizeof (long) == 0); + while (n >= sizeof (long)) { + /* high-speed clear loop */ + *q++ = 0; + n -= sizeof (long); + } + ptr = (char *) q; + while (n--) *ptr++ = '\0'; +} diff --git a/modules/src/alloc/in_all.h b/modules/src/alloc/in_all.h new file mode 100644 index 000000000..8850f61a2 --- /dev/null +++ b/modules/src/alloc/in_all.h @@ -0,0 +1,7 @@ +#ifdef DEBUG +#define PRIVATE +#else +#define PRIVATE static +#endif + +#define EXPORT diff --git a/modules/src/alloc/st_alloc.c b/modules/src/alloc/st_alloc.c new file mode 100644 index 000000000..434fa7c05 --- /dev/null +++ b/modules/src/alloc/st_alloc.c @@ -0,0 +1,47 @@ +/* st_alloc - get a structure from a free list. If no structures left, + create new ones. The structures for which this works are + supposed to have as their first tag the string "next", which + should be a pointer type. + The counterpart, st_free, is a macro, defined in alloc.h +*/ + +#include "alloc.h" + +struct xxx { + char *next; +}; + +char * +st_alloc(phead, size, count) + char **phead; + register unsigned int size; +{ + register char *p; + char *retval; + + if (*phead == 0) { + + p = Malloc(size * count); + ((struct xxx *) p)->next = 0; + while (--count) { + p += size; + ((struct xxx *) p)->next = p - size; + } + *phead = p; + } + else p = *phead; + *phead = ((struct xxx *)p)->next; + retval = p; + if (size >= sizeof(long)) { + register long *q = (long *) p; + do { + *q++ = 0; + size -= sizeof(long); + } while (size >= sizeof(long)); + + p = (char *) q; + } + + while (size--) *p++ = 0; + return retval; +} diff --git a/modules/src/alloc/std_alloc.c b/modules/src/alloc/std_alloc.c new file mode 100644 index 000000000..2f8697d00 --- /dev/null +++ b/modules/src/alloc/std_alloc.c @@ -0,0 +1,38 @@ +/* st_alloc - get a structure from a free list. If no structures left, + create new ones. The structures for which this works are + supposed to have as their first tag the string "next", which + should be a pointer type. + The counterpart, st_free, is a macro, defined in alloc.h +*/ + +#include "alloc.h" + +struct xxx { + char *next; +}; + +char * +std_alloc(phead, size, count, pcnt) + char **phead; + register unsigned int size; + int *pcnt; +{ + register char *p; + + if (*phead == 0) { + + p = Malloc(size * count); + *pcnt += count; + ((struct xxx *) p)->next = 0; + while (--count) { + p += size; + ((struct xxx *) p)->next = p - size; + } + *phead = p; + } + else p = *phead; + *phead = ((struct xxx *) p)->next; + p += size; + while (size--) *--p = 0; + return p; +}