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