|
|
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.