|
|
1.1 root 1: /* recycle.c */
2:
3: /* Author:
4: * Steve Kirkendall
5: * 14407 SW Teal Blvd. #C
6: * Beaverton, OR 97005
7: * [email protected]
8: */
9:
10:
11: /* This file contains the functions perform garbage collection and allocate
12: * reusable blocks.
13: */
14:
15: #include "config.h"
16: #include "vi.h"
17:
18: #ifndef NO_RECYCLE
19: /* this whole file would have be skipped if NO_RECYCLE is defined */
20:
21:
22: #define BTST(bitno, byte) ((byte) & (1 << (bitno)))
23: #define BSET(bitno, byte) ((byte) |= (1 << (bitno)))
24: #define BCLR(bitno, byte) ((byte) &= ~(1 << (bitno)))
25:
26: #define TST(blkno) ((blkno) < MAXBIT ? BTST((blkno) & 7, bitmap[(blkno) >> 3]) : 1)
27: #define SET(blkno) if ((blkno) < MAXBIT) BSET((blkno) & 7, bitmap[(blkno) >> 3])
28: #define CLR(blkno) if ((blkno) < MAXBIT) BCLR((blkno) & 7, bitmap[(blkno) >> 3])
29:
30: /* bitmap of free blocks in first 4096k of tmp file */
31: static unsigned char bitmap[512];
32: #define MAXBIT (sizeof bitmap << 3)
33:
34: /* this function locates all free blocks in the current tmp file */
35: void garbage()
36: {
37: int i;
38: BLK oldhdr;
39:
40: /* start by assuming every block is free */
41: for (i = 0; i < sizeof bitmap; i++)
42: {
43: bitmap[i] = 255;
44: }
45:
46: /* header blocks aren't free */
47: #ifndef lint
48: CLR(0);
49: CLR(1);
50: #endif
51:
52: /* blocks needed for current hdr aren't free */
53: for (i = 1; i < MAXBLKS; i++)
54: {
55: CLR(hdr.n[i]);
56: }
57:
58: /* blocks needed for undo version aren't free */
59: lseek(tmpfd, 0L, 0);
60: if (read(tmpfd, &oldhdr, (unsigned)sizeof oldhdr) != sizeof oldhdr)
61: {
62: msg("garbage() failed to read oldhdr??");
63: for (i = 0; i < sizeof bitmap; i++)
64: {
65: bitmap[i] = 0;
66: }
67: return;
68: }
69: for (i = 1; i < MAXBLKS; i++)
70: {
71: CLR(oldhdr.n[i]);
72: }
73:
74: /* blocks needed for cut buffers aren't free */
75: for (i = cutneeds(&oldhdr) - 1; i >= 0; i--)
76: {
77: CLR(oldhdr.n[i]);
78: }
79: }
80:
81: /* This function allocates the first available block in the tmp file */
82: long allocate()
83: {
84: int i;
85: long offset;
86:
87: /* search for the first byte with a free bit set */
88: for (i = 0; i < sizeof bitmap && bitmap[i] == 0; i++)
89: {
90: }
91:
92: /* if we hit the end of the bitmap, return the end of the file */
93: if (i == sizeof bitmap)
94: {
95: offset = lseek(tmpfd, 0L, 2);
96: }
97: else /* compute the offset for the free block */
98: {
99: for (i <<= 3; TST(i) == 0; i++)
100: {
101: }
102: offset = (long)i * (long)BLKSIZE;
103:
104: /* mark the block as "allocated" */
105: CLR(i);
106: }
107:
108: return offset;
109: }
110:
111: #endif
112:
113: #ifdef DEBUG
114: # include <stdio.h>
115: # undef malloc
116: # undef free
117: # define MEMMAGIC 0x19f72cc0L
118: # define MAXALLOC 800
119: static char *allocated[MAXALLOC];
120: static char *fromfile[MAXALLOC];
121: static int fromline[MAXALLOC];
122: static int sizes[MAXALLOC];
123:
124: char *dbmalloc(size, file, line)
125: int size;
126: char *file;
127: int line;
128: {
129: char *ret;
130: int i;
131:
132: size = size + sizeof(long) - (size % sizeof(long));
133: ret = (char *)malloc(size + 2 * sizeof(long)) + sizeof(long);
134: for (i = 0; i < MAXALLOC && allocated[i]; i++)
135: {
136: }
137: if (i == MAXALLOC)
138: {
139: endwin();
140: fprintf(stderr, "\r\n%s(%d): Too many malloc calls!\n", file, line);
141: abort();
142: }
143: sizes[i] = size/sizeof(long);
144: allocated[i] = ret;
145: fromfile[i] = file;
146: fromline[i] = line;
147: ((long *)ret)[-1] = MEMMAGIC;
148: ((long *)ret)[sizes[i]] = MEMMAGIC;
149: return ret;
150: }
151:
152: dbfree(ptr, file, line)
153: char *ptr;
154: char *file;
155: int line;
156: {
157: int i;
158:
159: for (i = 0; i < MAXALLOC && allocated[i] != ptr; i++)
160: {
161: }
162: if (i == MAXALLOC)
163: {
164: endwin();
165: fprintf(stderr, "\r\n%s(%d): attempt to free mem that wasn't allocated\n", file, line);
166: abort();
167: }
168: allocated[i] = (char *)0;
169: if (((long *)ptr)[-1] != MEMMAGIC)
170: {
171: endwin();
172: fprintf(stderr, "\r\n%s(%d): underflowed malloc space, allocated at %s(%d)\n", file, line, fromfile[i], fromline[i]);
173: abort();
174: }
175: if (((long *)ptr)[sizes[i]] != MEMMAGIC)
176: {
177: endwin();
178: fprintf(stderr, "\r\n%s(%d): overflowed malloc space, allocated at %s(%d)\n", file, line, fromfile[i], fromline[i]);
179: abort();
180: }
181: free(ptr - sizeof(long));
182: }
183:
184: dbcheckmem(file, line)
185: char *file;
186: int line;
187: {
188: int i, j;
189:
190: for (i = j = 0; i < MAXALLOC && allocated[i]; i++)
191: {
192: if (((long *)allocated[i])[-1] != MEMMAGIC)
193: {
194: if (!j) endwin();
195: fprintf(stderr, "\r\n%s(%d): underflowed malloc space, allocated at %s(%d)\n", file, line, fromfile[i], fromline[i]);
196: j++;
197: }
198: if (((long *)allocated[i])[sizes[i]] != MEMMAGIC)
199: {
200: if (!j) endwin();
201: fprintf(stderr, "\r\n%s(%d): overflowed malloc space, allocated at %s(%d)\n", file, line, fromfile[i], fromline[i]);
202: j++;
203: }
204: }
205: if (j)
206: {
207: abort();
208: }
209: }
210: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.