void AllocateHMASpace (size_t lowbuffer, size_t highbuffer) { REG struct buffer FAR *bp = firstbuf; int n; if (FP_SEG(bp) != 0xffff) return; n = LoL_nbuffers; do { /* check if buffer intersects with requested area */ if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer) { flush1(bp); /* unlink bp from buffer chain */ b_prev(bp)->b_next = bp->b_next; b_next(bp)->b_prev = bp->b_prev; if (FP_OFF(bp) == FP_OFF(firstbuf)) firstbuf = b_next(bp); LoL_nbuffers--; } bp = b_next(bp); } while (--n); }
STATIC void move_buffer(struct buffer FAR *bp, size_t firstbp) { /* connect bp->b_prev and bp->b_next */ b_next(bp)->b_prev = bp->b_prev; b_prev(bp)->b_next = bp->b_next; /* insert bp between firstbp and firstbp->b_prev */ bp->b_prev = bufptr(firstbp)->b_prev; bp->b_next = firstbp; b_next(bp)->b_prev = FP_OFF(bp); b_prev(bp)->b_next = FP_OFF(bp); }
VOID setinvld(REG COUNT dsk) { struct buffer FAR *bp = firstbuf; do { if (bp->b_unit == dsk) bp->b_flag = 0; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); }
BOOL dirty_buffers(REG COUNT dsk) { struct buffer FAR *bp = firstbuf; do { if (bp->b_unit == dsk && (bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY)) return TRUE; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); return FALSE; }
BOOL flush_buffers(REG COUNT dsk) { struct buffer FAR *bp = firstbuf; REG BOOL ok = TRUE; bp = firstbuf; do { if (bp->b_unit == dsk) if (!flush1(bp)) ok = FALSE; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); return ok; }
void dumpBufferCache(void) { struct buffer FAR *bp = firstbuf; int printed = 0; /* Search through buffers to see if the required block */ /* is already in a buffer */ do { printf("%8lx %02x ", bp->b_blkno, bp->b_flag); if (++printed % 6 == 0) printf("\n"); bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); printf("\n"); }
BOOL flush(void) { REG struct buffer FAR *bp = firstbuf; REG BOOL ok; ok = TRUE; do { if (!flush1(bp)) ok = FALSE; bp->b_flag &= ~BFR_VALID; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); network_redirector(REM_FLUSHALL); return (ok); }
/* Gets one text line out of a channel's buffer from a stream interface. * Return values : * >0 : number of bytes read. Includes the \n if present before len or end. * =0 : no '\n' before end found. <str> is left undefined. * <0 : no more bytes readable because output is shut. * The channel status is not changed. The caller must call co_skip() to * update it. The '\n' is waited for as long as neither the buffer nor the * output are full. If either of them is full, the string may be returned * as is, without the '\n'. */ int co_getline(const struct channel *chn, char *str, int len) { int ret, max; char *p; ret = 0; max = len; /* closed or empty + imminent close = -1; empty = 0 */ if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) { if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) ret = -1; goto out; } p = co_head(chn); if (max > co_data(chn)) { max = co_data(chn); str[max-1] = 0; } while (max) { *str++ = *p; ret++; max--; if (*p == '\n') break; p = b_next(&chn->buf, p); } if (ret > 0 && ret < len && (ret < co_data(chn) || channel_may_recv(chn)) && *(str-1) != '\n' && !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) ret = 0; out: if (max) *str = 0; return ret; }
BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk, int mode) { struct buffer FAR *bp = firstbuf; /* Search through buffers to see if the required block */ /* is already in a buffer */ do { if (blknolow <= bp->b_blkno && bp->b_blkno <= blknohigh && (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)) { if (mode == XFR_READ) flush1(bp); else bp->b_flag = 0; } bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); return FALSE; }
STATIC struct buffer FAR *searchblock(ULONG blkno, COUNT dsk) { int fat_count = 0; struct buffer FAR *bp; size_t lastNonFat = 0; size_t uncacheBuf = 0; seg bufseg = FP_SEG(firstbuf); size_t firstbp = FP_OFF(firstbuf); #ifdef DISPLAY_GETBLOCK printf("[searchblock %d, blk %ld, buf ", dsk, blkno); #endif /* Search through buffers to see if the required block */ /* is already in a buffer */ bp = MK_FP(bufseg, firstbp); do { if ((bp->b_blkno == blkno) && (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)) { /* found it -- rearrange LRU links */ #ifdef DISPLAY_GETBLOCK printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp)); #endif bp->b_flag &= ~BFR_UNCACHE; /* reset uncache attribute */ if (FP_OFF(bp) != firstbp) { *(UWORD *)&firstbuf = FP_OFF(bp); move_buffer(bp, firstbp); } return bp; } if (bp->b_flag & BFR_UNCACHE) uncacheBuf = FP_OFF(bp); if (bp->b_flag & BFR_FAT) fat_count++; else lastNonFat = FP_OFF(bp); bp = b_next(bp); } while (FP_OFF(bp) != firstbp); /* now take either the last buffer in chain (not used recently) or, if we are low on FAT buffers, the last non FAT buffer */ if (uncacheBuf) { bp = bufptr(uncacheBuf); } else if (bp->b_flag & BFR_FAT && fat_count < 3 && lastNonFat) { bp = bufptr(lastNonFat); } else { bp = b_prev(bufptr(firstbp)); } bp->b_flag |= BFR_UNCACHE; /* set uncache attribute */ #ifdef DISPLAY_GETBLOCK printf("MISS, replace %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp)); #endif if (FP_OFF(bp) != firstbp) /* move to front */ { move_buffer(bp, firstbp); *(UWORD *)&firstbuf = FP_OFF(bp); } return bp; }