/* * t a l l o c . c */ /*)LIBRARY */ #ifdef DOCUMENTATION title talloc Threaded Storage Allocator Functions index Allocate space that can be easily deleted index Free space allocated by talloc() index Mark on current allocation thread synopsis char * talloc(n) unsigned n; tfree(p) char *p; extern char *tmark; description talloc() is like malloc(); it allocates space. However, all this space is linked (threaded) together, and can be freed easily. Thus: here = tmark; a = talloc(5); b = talloc(5); ... tfree(here); The call to tfree() deletes a, b, and anything else allocated by talloc() between the point at which tmark was sampled and the call to tfree(). Like malloc(), talloc() returns NULL if it can't get you space. It is safe to save tmark more than once; for example, if a function knows its caller has saved tmark, it needn't ensure that it always frees its space after an error; the caller's tfree() will get rid of everything. talloc() calls malloc(), and malloc() can be used without interfering with talloc(); tfree() has no effect on space allocated directly with malloc(). Space allocated with talloc() must NEVER be passed to realloc() or free(); the pointers differ. Needless to say, passing a value to tfree() that was not obtained from tmark or which is obsolete because a value obtained earlier was already passed will cause trouble. The overhead involved in using talloc() instead of malloc() is one (char *) per call. bugs author Jerry Leichter #endif /* *)EDITLEVEL=09 * Edit history * 0.0 18-May-81 JSL Invention * 0.1 19-May-81 JSL Fix bug in tfree() * 0.2 20-May-81 JSL Cleanup; improved documentation */ #define NULL 0 extern char *malloc(); typedef union /* Machine-dependent alignment constant */ { char u1; char *u2; } ALIGN; /* malloc() returns a pointer that is guaranteed to satisfy any alignment * constraint of its host machine. talloc() should do the same. talloc() * needs space for one character pointer for threading; type ALIGN must * guarantee (1) sufficient space for such a pointer and (2) that a pointer * returned by malloc(), + sizeof(ALIGN), also satisfies all alignment con- * straints. For the PDP-11 and the VAX, word alignment is sufficient, and * a pointer is one word, so this is easy and requires no wasted space. Other * machines may require more. */ struct p { char *pointer; }; static char *head = NULL; char *tmark = &head; char * talloc(n) unsigned n; { register char *space; if ((space = malloc(n + sizeof(ALIGN))) == NULL) return(NULL); ((struct p *)tmark)->pointer = space; /* link last to new */ tmark = space; /* point mark to new */ ((struct p *)space)->pointer = NULL; /* clear link */ return(space + sizeof(ALIGN)); } tfree(p) register char *p; { register char *q; #ifdef DEBUG printf("tfree: head %o tmark %o p %o\n",&head,tmark,p); #endif tmark = p; p = ((struct p *)p)->pointer; while (q = p) { p = ((struct p *)q)->pointer; #ifdef DEBUG printf("Freeing %o\n",q); #endif free(q); } ((struct p *)tmark)->pointer = NULL; }