17dd7cddfSDavid du Colombier /***** tl_spin: tl_mem.c *****/
27dd7cddfSDavid du Colombier
3*312a1df1SDavid du Colombier /* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */
47dd7cddfSDavid du Colombier /* All Rights Reserved. This software is for educational purposes only. */
5*312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6*312a1df1SDavid du Colombier /* this code. Permission is given to distribute this code provided that */
7*312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged. */
8*312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann. For tool documentation see: */
9*312a1df1SDavid du Colombier /* http://spinroot.com/ */
10*312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com */
11*312a1df1SDavid du Colombier
127dd7cddfSDavid du Colombier /* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */
137dd7cddfSDavid du Colombier /* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier #include "tl.h"
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier #if 1
187dd7cddfSDavid du Colombier #define log(e, u, d) event[e][(int) u] += (long) d;
197dd7cddfSDavid du Colombier #else
207dd7cddfSDavid du Colombier #define log(e, u, d)
217dd7cddfSDavid du Colombier #endif
227dd7cddfSDavid du Colombier
237dd7cddfSDavid du Colombier #define A_LARGE 80
247dd7cddfSDavid du Colombier #define A_USER 0x55000000
257dd7cddfSDavid du Colombier #define NOTOOBIG 32768
267dd7cddfSDavid du Colombier
277dd7cddfSDavid du Colombier #define POOL 0
287dd7cddfSDavid du Colombier #define ALLOC 1
297dd7cddfSDavid du Colombier #define FREE 2
307dd7cddfSDavid du Colombier #define NREVENT 3
317dd7cddfSDavid du Colombier
327dd7cddfSDavid du Colombier extern unsigned long All_Mem;
337dd7cddfSDavid du Colombier extern int tl_verbose;
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier union M {
367dd7cddfSDavid du Colombier long size;
377dd7cddfSDavid du Colombier union M *link;
387dd7cddfSDavid du Colombier };
397dd7cddfSDavid du Colombier
407dd7cddfSDavid du Colombier static union M *freelist[A_LARGE];
417dd7cddfSDavid du Colombier static long req[A_LARGE];
427dd7cddfSDavid du Colombier static long event[NREVENT][A_LARGE];
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier void *
tl_emalloc(int U)457dd7cddfSDavid du Colombier tl_emalloc(int U)
467dd7cddfSDavid du Colombier { union M *m;
477dd7cddfSDavid du Colombier long r, u;
487dd7cddfSDavid du Colombier void *rp;
497dd7cddfSDavid du Colombier
507dd7cddfSDavid du Colombier u = (long) ((U-1)/sizeof(union M) + 2);
517dd7cddfSDavid du Colombier
527dd7cddfSDavid du Colombier if (u >= A_LARGE)
537dd7cddfSDavid du Colombier { log(ALLOC, 0, 1);
547dd7cddfSDavid du Colombier if (tl_verbose)
557dd7cddfSDavid du Colombier printf("tl_spin: memalloc %ld bytes\n", u);
567dd7cddfSDavid du Colombier m = (union M *) emalloc((int) u*sizeof(union M));
577dd7cddfSDavid du Colombier All_Mem += (unsigned long) u*sizeof(union M);
587dd7cddfSDavid du Colombier } else
597dd7cddfSDavid du Colombier { if (!freelist[u])
607dd7cddfSDavid du Colombier { r = req[u] += req[u] ? req[u] : 1;
617dd7cddfSDavid du Colombier if (r >= NOTOOBIG)
627dd7cddfSDavid du Colombier r = req[u] = NOTOOBIG;
637dd7cddfSDavid du Colombier log(POOL, u, r);
647dd7cddfSDavid du Colombier freelist[u] = (union M *)
657dd7cddfSDavid du Colombier emalloc((int) r*u*sizeof(union M));
667dd7cddfSDavid du Colombier All_Mem += (unsigned long) r*u*sizeof(union M);
677dd7cddfSDavid du Colombier m = freelist[u] + (r-2)*u;
687dd7cddfSDavid du Colombier for ( ; m >= freelist[u]; m -= u)
697dd7cddfSDavid du Colombier m->link = m+u;
707dd7cddfSDavid du Colombier }
717dd7cddfSDavid du Colombier log(ALLOC, u, 1);
727dd7cddfSDavid du Colombier m = freelist[u];
737dd7cddfSDavid du Colombier freelist[u] = m->link;
747dd7cddfSDavid du Colombier }
757dd7cddfSDavid du Colombier m->size = (u|A_USER);
767dd7cddfSDavid du Colombier
777dd7cddfSDavid du Colombier for (r = 1; r < u; )
787dd7cddfSDavid du Colombier (&m->size)[r++] = 0;
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier rp = (void *) (m+1);
817dd7cddfSDavid du Colombier memset(rp, 0, U);
827dd7cddfSDavid du Colombier return rp;
837dd7cddfSDavid du Colombier }
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier void
tfree(void * v)867dd7cddfSDavid du Colombier tfree(void *v)
877dd7cddfSDavid du Colombier { union M *m = (union M *) v;
887dd7cddfSDavid du Colombier long u;
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier --m;
917dd7cddfSDavid du Colombier if ((m->size&0xFF000000) != A_USER)
927dd7cddfSDavid du Colombier Fatal("releasing a free block", (char *)0);
937dd7cddfSDavid du Colombier
947dd7cddfSDavid du Colombier u = (m->size &= 0xFFFFFF);
957dd7cddfSDavid du Colombier if (u >= A_LARGE)
967dd7cddfSDavid du Colombier { log(FREE, 0, 1);
977dd7cddfSDavid du Colombier /* free(m); */
987dd7cddfSDavid du Colombier } else
997dd7cddfSDavid du Colombier { log(FREE, u, 1);
1007dd7cddfSDavid du Colombier m->link = freelist[u];
1017dd7cddfSDavid du Colombier freelist[u] = m;
1027dd7cddfSDavid du Colombier }
1037dd7cddfSDavid du Colombier }
1047dd7cddfSDavid du Colombier
1057dd7cddfSDavid du Colombier void
a_stats(void)1067dd7cddfSDavid du Colombier a_stats(void)
1077dd7cddfSDavid du Colombier { long p, a, f;
1087dd7cddfSDavid du Colombier int i;
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier printf(" size\t pool\tallocs\t frees\n");
1117dd7cddfSDavid du Colombier for (i = 0; i < A_LARGE; i++)
1127dd7cddfSDavid du Colombier { p = event[POOL][i];
1137dd7cddfSDavid du Colombier a = event[ALLOC][i];
1147dd7cddfSDavid du Colombier f = event[FREE][i];
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier if(p|a|f)
1177dd7cddfSDavid du Colombier printf("%5d\t%6ld\t%6ld\t%6ld\n",
1187dd7cddfSDavid du Colombier i, p, a, f);
1197dd7cddfSDavid du Colombier }
1207dd7cddfSDavid du Colombier }
121