示例#1
0
文件: buffer.c 项目: binsys/doc-linux
/*
 * 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;
}
示例#2
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;
}
示例#3
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;
        }


    }

}