17dd7cddfSDavid du Colombier /***** tl_spin: tl_mem.c *****/
27dd7cddfSDavid du Colombier
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier *
8*de2caf28SDavid du Colombier * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper,
9*de2caf28SDavid du Colombier * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995.
10*de2caf28SDavid du Colombier */
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier #include "tl.h"
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier #if 1
157dd7cddfSDavid du Colombier #define log(e, u, d) event[e][(int) u] += (long) d;
167dd7cddfSDavid du Colombier #else
177dd7cddfSDavid du Colombier #define log(e, u, d)
187dd7cddfSDavid du Colombier #endif
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier #define A_LARGE 80
217dd7cddfSDavid du Colombier #define A_USER 0x55000000
227dd7cddfSDavid du Colombier #define NOTOOBIG 32768
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier #define POOL 0
257dd7cddfSDavid du Colombier #define ALLOC 1
267dd7cddfSDavid du Colombier #define FREE 2
277dd7cddfSDavid du Colombier #define NREVENT 3
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier extern unsigned long All_Mem;
307dd7cddfSDavid du Colombier extern int tl_verbose;
317dd7cddfSDavid du Colombier
327dd7cddfSDavid du Colombier union M {
337dd7cddfSDavid du Colombier long size;
347dd7cddfSDavid du Colombier union M *link;
357dd7cddfSDavid du Colombier };
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier static union M *freelist[A_LARGE];
387dd7cddfSDavid du Colombier static long req[A_LARGE];
397dd7cddfSDavid du Colombier static long event[NREVENT][A_LARGE];
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier void *
tl_emalloc(int U)427dd7cddfSDavid du Colombier tl_emalloc(int U)
437dd7cddfSDavid du Colombier { union M *m;
447dd7cddfSDavid du Colombier long r, u;
457dd7cddfSDavid du Colombier void *rp;
467dd7cddfSDavid du Colombier
477dd7cddfSDavid du Colombier u = (long) ((U-1)/sizeof(union M) + 2);
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier if (u >= A_LARGE)
507dd7cddfSDavid du Colombier { log(ALLOC, 0, 1);
517dd7cddfSDavid du Colombier if (tl_verbose)
52*de2caf28SDavid du Colombier { printf("tl_spin: memalloc %ld bytes\n", u);
53*de2caf28SDavid du Colombier }
547dd7cddfSDavid du Colombier m = (union M *) emalloc((int) u*sizeof(union M));
557dd7cddfSDavid du Colombier All_Mem += (unsigned long) u*sizeof(union M);
567dd7cddfSDavid du Colombier } else
577dd7cddfSDavid du Colombier { if (!freelist[u])
587dd7cddfSDavid du Colombier { r = req[u] += req[u] ? req[u] : 1;
597dd7cddfSDavid du Colombier if (r >= NOTOOBIG)
60*de2caf28SDavid du Colombier { r = req[u] = NOTOOBIG;
61*de2caf28SDavid du Colombier }
627dd7cddfSDavid du Colombier log(POOL, u, r);
637dd7cddfSDavid du Colombier freelist[u] = (union M *)
647dd7cddfSDavid du Colombier emalloc((int) r*u*sizeof(union M));
657dd7cddfSDavid du Colombier All_Mem += (unsigned long) r*u*sizeof(union M);
667dd7cddfSDavid du Colombier m = freelist[u] + (r-2)*u;
677dd7cddfSDavid du Colombier for ( ; m >= freelist[u]; m -= u)
68*de2caf28SDavid du Colombier { m->link = m+u;
69*de2caf28SDavid du Colombier } }
707dd7cddfSDavid du Colombier log(ALLOC, u, 1);
717dd7cddfSDavid du Colombier m = freelist[u];
727dd7cddfSDavid du Colombier freelist[u] = m->link;
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier m->size = (u|A_USER);
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier for (r = 1; r < u; )
77*de2caf28SDavid du Colombier { (&m->size)[r++] = 0;
78*de2caf28SDavid du Colombier }
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
85*de2caf28SDavid du Colombier /* could be more efficient, but not a bottleneck */
86*de2caf28SDavid du Colombier void*
tl_erealloc(void * v,int U,int old_size)87*de2caf28SDavid du Colombier tl_erealloc(void *v, int U, int old_size)
88*de2caf28SDavid du Colombier { void* tmp = tl_emalloc(U);
89*de2caf28SDavid du Colombier
90*de2caf28SDavid du Colombier if (v)
91*de2caf28SDavid du Colombier { strncpy(tmp, v, old_size);
92*de2caf28SDavid du Colombier tfree(v);
93*de2caf28SDavid du Colombier }
94*de2caf28SDavid du Colombier
95*de2caf28SDavid du Colombier return tmp;
96*de2caf28SDavid du Colombier }
97*de2caf28SDavid du Colombier
987dd7cddfSDavid du Colombier void
tfree(void * v)997dd7cddfSDavid du Colombier tfree(void *v)
1007dd7cddfSDavid du Colombier { union M *m = (union M *) v;
1017dd7cddfSDavid du Colombier long u;
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier --m;
1047dd7cddfSDavid du Colombier if ((m->size&0xFF000000) != A_USER)
105*de2caf28SDavid du Colombier { Fatal("releasing a free block", (char *)0);
106*de2caf28SDavid du Colombier }
1077dd7cddfSDavid du Colombier
1087dd7cddfSDavid du Colombier u = (m->size &= 0xFFFFFF);
1097dd7cddfSDavid du Colombier if (u >= A_LARGE)
1107dd7cddfSDavid du Colombier { log(FREE, 0, 1);
1117dd7cddfSDavid du Colombier /* free(m); */
1127dd7cddfSDavid du Colombier } else
1137dd7cddfSDavid du Colombier { log(FREE, u, 1);
1147dd7cddfSDavid du Colombier m->link = freelist[u];
1157dd7cddfSDavid du Colombier freelist[u] = m;
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier }
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombier void
a_stats(void)1207dd7cddfSDavid du Colombier a_stats(void)
1217dd7cddfSDavid du Colombier { long p, a, f;
1227dd7cddfSDavid du Colombier int i;
1237dd7cddfSDavid du Colombier
1247dd7cddfSDavid du Colombier printf(" size\t pool\tallocs\t frees\n");
1257dd7cddfSDavid du Colombier for (i = 0; i < A_LARGE; i++)
1267dd7cddfSDavid du Colombier { p = event[POOL][i];
1277dd7cddfSDavid du Colombier a = event[ALLOC][i];
1287dd7cddfSDavid du Colombier f = event[FREE][i];
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier if (p|a|f)
131*de2caf28SDavid du Colombier { printf("%5d\t%6ld\t%6ld\t%6ld\n",
1327dd7cddfSDavid du Colombier i, p, a, f);
133*de2caf28SDavid du Colombier } }
1347dd7cddfSDavid du Colombier }
135