]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/spin/tl_mem.c
audiohda: fix syntax error
[plan9front.git] / sys / src / cmd / spin / tl_mem.c
1 /***** tl_spin: tl_mem.c *****/
2
3 /*
4  * This file is part of the public release of Spin. It is subject to the
5  * terms in the LICENSE file that is included in this source directory.
6  * Tool documentation is available at http://spinroot.com
7  *
8  * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper,
9  * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995.
10  */
11
12 #include "tl.h"
13
14 #if 1
15 #define log(e, u, d)    event[e][(int) u] += (long) d;
16 #else
17 #define log(e, u, d)
18 #endif
19
20 #define A_LARGE         80
21 #define A_USER          0x55000000
22 #define NOTOOBIG        32768
23
24 #define POOL            0
25 #define ALLOC           1
26 #define FREE            2
27 #define NREVENT         3
28
29 extern  unsigned long All_Mem;
30 extern  int tl_verbose;
31
32 union M {
33         long size;
34         union M *link;
35 };
36
37 static union M *freelist[A_LARGE];
38 static long     req[A_LARGE];
39 static long     event[NREVENT][A_LARGE];
40
41 void *
42 tl_emalloc(int U)
43 {       union M *m;
44         long r, u;
45         void *rp;
46
47         u = (long) ((U-1)/sizeof(union M) + 2);
48
49         if (u >= A_LARGE)
50         {       log(ALLOC, 0, 1);
51                 if (tl_verbose)
52                 printf("tl_spin: memalloc %ld bytes\n", u);
53                 m = (union M *) emalloc((int) u*sizeof(union M));
54                 All_Mem += (unsigned long) u*sizeof(union M);
55         } else
56         {       if (!freelist[u])
57                 {       r = req[u] += req[u] ? req[u] : 1;
58                         if (r >= NOTOOBIG)
59                                 r = req[u] = NOTOOBIG;
60                         log(POOL, u, r);
61                         freelist[u] = (union M *)
62                                 emalloc((int) r*u*sizeof(union M));
63                         All_Mem += (unsigned long) r*u*sizeof(union M);
64                         m = freelist[u] + (r-2)*u;
65                         for ( ; m >= freelist[u]; m -= u)
66                                 m->link = m+u;
67                 }
68                 log(ALLOC, u, 1);
69                 m = freelist[u];
70                 freelist[u] = m->link;
71         }
72         m->size = (u|A_USER);
73
74         for (r = 1; r < u; )
75                 (&m->size)[r++] = 0;
76
77         rp = (void *) (m+1);
78         memset(rp, 0, U);
79         return rp;
80 }
81
82 void
83 tfree(void *v)
84 {       union M *m = (union M *) v;
85         long u;
86
87         --m;
88         if ((m->size&0xFF000000) != A_USER)
89                 Fatal("releasing a free block", (char *)0);
90
91         u = (m->size &= 0xFFFFFF);
92         if (u >= A_LARGE)
93         {       log(FREE, 0, 1);
94                 /* free(m); */
95         } else
96         {       log(FREE, u, 1);
97                 m->link = freelist[u];
98                 freelist[u] = m;
99         }
100 }
101
102 void
103 a_stats(void)
104 {       long    p, a, f;
105         int     i;
106
107         printf(" size\t  pool\tallocs\t frees\n");
108         for (i = 0; i < A_LARGE; i++)
109         {       p = event[POOL][i];
110                 a = event[ALLOC][i];
111                 f = event[FREE][i];
112
113                 if(p|a|f)
114                 printf("%5d\t%6ld\t%6ld\t%6ld\n",
115                         i, p, a, f);
116         }
117 }