123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- /***** 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);
- }
- }
|