/* This file contains the functions perform garbage collection and allocate
/* this whole file would have be skipped if NO_RECYCLE is defined */
#define BTST(bitno, byte) ((byte) & (1 << (bitno)))
#define BSET(bitno, byte) ((byte) |= (1 << (bitno)))
#define BCLR(bitno, byte) ((byte) &= ~(1 << (bitno)))
#define TST(blkno) ((blkno) < MAXBIT ? BTST((blkno) & 7, bitmap[(blkno) >> 3]) : 1)
#define SET(blkno) if ((blkno) < MAXBIT) BSET((blkno) & 7, bitmap[(blkno) >> 3])
#define CLR(blkno) if ((blkno) < MAXBIT) BCLR((blkno) & 7, bitmap[(blkno) >> 3])
/* bitmap of free blocks in first 4096k of tmp file */
static unsigned char bitmap
[512];
#define MAXBIT (sizeof bitmap << 3)
/* this function locates all free blocks in the current tmp file */
/* start by assuming every block is free */
for (i
= 0; i
< sizeof bitmap
; i
++)
/* header blocks aren't free */
/* blocks needed for current hdr aren't free */
for (i
= 1; i
< MAXBLKS
; i
++)
/* blocks needed for undo version aren't free */
if (read(tmpfd
, &oldhdr
, (unsigned)sizeof oldhdr
) != sizeof oldhdr
)
msg("garbage() failed to read oldhdr??");
for (i
= 0; i
< sizeof bitmap
; i
++)
for (i
= 1; i
< MAXBLKS
; i
++)
/* blocks needed for cut buffers aren't free */
for (i
= cutneeds(&oldhdr
) - 1; i
>= 0; i
--)
/* This function allocates the first available block in the tmp file */
/* search for the first byte with a free bit set */
for (i
= 0; i
< sizeof bitmap
&& bitmap
[i
] == 0; i
++)
/* if we hit the end of the bitmap, return the end of the file */
offset
= lseek(tmpfd
, 0L, 2);
else /* compute the offset for the free block */
for (i
<<= 3; TST(i
) == 0; i
++)
offset
= (long)i
* (long)BLKSIZE
;
/* mark the block as "allocated" */
# define MEMMAGIC 0x19f72cc0L
static char *allocated
[MAXALLOC
];
static char *fromfile
[MAXALLOC
];
static int fromline
[MAXALLOC
];
static int sizes
[MAXALLOC
];
char *dbmalloc(size
, file
, line
)
size
= size
+ sizeof(long) - (size
% sizeof(long));
ret
= (char *)malloc(size
+ 2 * sizeof(long)) + sizeof(long);
for (i
= 0; i
< MAXALLOC
&& allocated
[i
]; i
++)
fprintf(stderr
, "\r\n%s(%d): Too many malloc calls!\n", file
, line
);
sizes
[i
] = size
/sizeof(long);
((long *)ret
)[-1] = MEMMAGIC
;
((long *)ret
)[sizes
[i
]] = MEMMAGIC
;
for (i
= 0; i
< MAXALLOC
&& allocated
[i
] != ptr
; i
++)
fprintf(stderr
, "\r\n%s(%d): attempt to free mem that wasn't allocated\n", file
, line
);
allocated
[i
] = (char *)0;
if (((long *)ptr
)[-1] != MEMMAGIC
)
fprintf(stderr
, "\r\n%s(%d): underflowed malloc space, allocated at %s(%d)\n", file
, line
, fromfile
[i
], fromline
[i
]);
if (((long *)ptr
)[sizes
[i
]] != MEMMAGIC
)
fprintf(stderr
, "\r\n%s(%d): overflowed malloc space, allocated at %s(%d)\n", file
, line
, fromfile
[i
], fromline
[i
]);
free(ptr
- sizeof(long));
for (i
= j
= 0; i
< MAXALLOC
&& allocated
[i
]; i
++)
if (((long *)allocated
[i
])[-1] != MEMMAGIC
)
fprintf(stderr
, "\r\n%s(%d): underflowed malloc space, allocated at %s(%d)\n", file
, line
, fromfile
[i
], fromline
[i
]);
if (((long *)allocated
[i
])[sizes
[i
]] != MEMMAGIC
)
fprintf(stderr
, "\r\n%s(%d): overflowed malloc space, allocated at %s(%d)\n", file
, line
, fromfile
[i
], fromline
[i
]);