/* * Try to free up some pages by shrinking the buffer-cache * * Priority tells the routine how hard to try to shrink the * buffers: 3 means "don't bother too much", while a value * of 0 means "we'd better get some free pages now". */ int shrink_buffers(unsigned int priority) { struct buffer_head *bh; int i; if (priority < 2) sync_buffers(0); bh = free_list; i = nr_buffers >> priority; for ( ; i-- > 0 ; bh = bh->b_next_free) { if (bh->b_count || !bh->b_this_page) continue; if (bh->b_lock) if (priority) continue; else wait_on_buffer(bh); if (bh->b_dirt) { ll_rw_block(WRITEA,bh); continue; } if (try_to_free(bh)) return 1; } return 0; }
/* * Try to free up some pages by shrinking the buffer-cache * * Priority tells the routine how hard to try to shrink the * buffers: 3 means "don't bother too much", while a value * of 0 means "we'd better get some free pages now". */ int shrink_buffers(unsigned int priority) { struct buffer_head *bh; int i; if (priority < 2) sync_buffers(0,0); bh = free_list; i = nr_buffers >> priority; for ( ; i-- > 0 ; bh = bh->b_next_free) { if (bh->b_count || (priority >= 5 && mem_map[MAP_NR((unsigned long) bh->b_data)] > 1)) { put_last_free(bh); continue; } if (!bh->b_this_page) continue; if (bh->b_lock) if (priority) continue; else wait_on_buffer(bh); if (bh->b_dirt) { bh->b_count++; ll_rw_block(WRITEA, 1, &bh); bh->b_count--; continue; } if (try_to_free(bh, &bh)) return 1; } return 0; }
void wtbfree(void *p, unsigned n) { struct wtbheader *hp, *prevp; if (headptr == NULL) { /* first use */ if (! (headptr = malloc(sizeof *headptr))) /*can't save fragment, dump it */ return; headptr->p = p; headptr->n = n; headptr->next = NULL; } else if (p < headptr->p) { /* Special case: less than head */ if ((char *)p + n == headptr->p) { /* merge */ headptr->p = p; headptr->n = n; try_to_free(headptr); if(!headptr->n) { /* delete empty node */ void *tp = headptr; headptr = headptr->next; free(tp); } } else { struct wtbheader *tp; if (! (tp = malloc(sizeof *tp))) /* can't save fragment, dump it */ return; tp->p = p; tp->n = n; tp->next = headptr; headptr = tp; } } else { for (prevp = hp = headptr; hp->next && p > hp->next->p; prevp = hp, hp = hp->next) { ; /* just advance */ } if ((char *)hp->p + hp->n == p) { /* merge to current */ hp->n += n; try_to_free(hp); if (!hp->n) { if (hp == headptr) headptr = NULL; prevp->next = hp->next; free(hp); } } else if (hp->next && (char *)p + n == hp->next->p) { /* merge to next */ hp->next->p = p; hp->next->n += n; try_to_free(hp->next); if (! hp->next->n) { /* delete empty node */ void *tp = hp->next; hp->next = hp->next->next; free(tp); } } else { /* insert */ struct wtbheader *tp; if(! (tp = malloc(sizeof *tp))) /* can't save fragment, dump */ return; tp->p = p; tp->n = n; tp->next = hp->next; hp->next = tp; } } }