xref: /plan9-contrib/sys/src/cmd/spin/tl_mem.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
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