diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/spin/tl_mem.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/spin/tl_mem.c')
-rwxr-xr-x | sys/src/cmd/spin/tl_mem.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/sys/src/cmd/spin/tl_mem.c b/sys/src/cmd/spin/tl_mem.c new file mode 100755 index 000000000..52021e466 --- /dev/null +++ b/sys/src/cmd/spin/tl_mem.c @@ -0,0 +1,120 @@ +/***** tl_spin: tl_mem.c *****/ + +/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ +/* All Rights Reserved. This software is for educational purposes only. */ +/* No guarantee whatsoever is expressed or implied by the distribution of */ +/* this code. Permission is given to distribute this code provided that */ +/* this introductory message is not removed and no monies are exchanged. */ +/* Software written by Gerard J. Holzmann. For tool documentation see: */ +/* http://spinroot.com/ */ +/* Send all bug-reports and/or questions to: bugs@spinroot.com */ + +/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ +/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ + +#include "tl.h" + +#if 1 +#define log(e, u, d) event[e][(int) u] += (long) d; +#else +#define log(e, u, d) +#endif + +#define A_LARGE 80 +#define A_USER 0x55000000 +#define NOTOOBIG 32768 + +#define POOL 0 +#define ALLOC 1 +#define FREE 2 +#define NREVENT 3 + +extern unsigned long All_Mem; +extern int tl_verbose; + +union M { + long size; + union M *link; +}; + +static union M *freelist[A_LARGE]; +static long req[A_LARGE]; +static long event[NREVENT][A_LARGE]; + +void * +tl_emalloc(int U) +{ union M *m; + long r, u; + void *rp; + + u = (long) ((U-1)/sizeof(union M) + 2); + + if (u >= A_LARGE) + { log(ALLOC, 0, 1); + if (tl_verbose) + printf("tl_spin: memalloc %ld bytes\n", u); + m = (union M *) emalloc((int) u*sizeof(union M)); + All_Mem += (unsigned long) u*sizeof(union M); + } else + { if (!freelist[u]) + { r = req[u] += req[u] ? req[u] : 1; + if (r >= NOTOOBIG) + r = req[u] = NOTOOBIG; + log(POOL, u, r); + freelist[u] = (union M *) + emalloc((int) r*u*sizeof(union M)); + All_Mem += (unsigned long) r*u*sizeof(union M); + m = freelist[u] + (r-2)*u; + for ( ; m >= freelist[u]; m -= u) + m->link = m+u; + } + log(ALLOC, u, 1); + m = freelist[u]; + freelist[u] = m->link; + } + m->size = (u|A_USER); + + for (r = 1; r < u; ) + (&m->size)[r++] = 0; + + rp = (void *) (m+1); + memset(rp, 0, U); + return rp; +} + +void +tfree(void *v) +{ union M *m = (union M *) v; + long u; + + --m; + if ((m->size&0xFF000000) != A_USER) + Fatal("releasing a free block", (char *)0); + + u = (m->size &= 0xFFFFFF); + if (u >= A_LARGE) + { log(FREE, 0, 1); + /* free(m); */ + } else + { log(FREE, u, 1); + m->link = freelist[u]; + freelist[u] = m; + } +} + +void +a_stats(void) +{ long p, a, f; + int i; + + printf(" size\t pool\tallocs\t frees\n"); + for (i = 0; i < A_LARGE; i++) + { p = event[POOL][i]; + a = event[ALLOC][i]; + f = event[FREE][i]; + + if(p|a|f) + printf("%5d\t%6ld\t%6ld\t%6ld\n", + i, p, a, f); + } +} |