Fix allocator routines. Instead of abusing CIRCLEQ pointers, add an explicit
type field to tag memory nodes that are or are not on the free list.
This commit is contained in:
parent
795bcb0d40
commit
aafa26eec9
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cc.c,v 1.24 2013/11/27 17:24:43 christos Exp $ */
|
||||
/* $NetBSD: cc.c,v 1.25 2014/01/03 07:14:20 mlelstv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Christian E. Hopps
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cc.c,v 1.24 2013/11/27 17:24:43 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cc.c,v 1.25 2014/01/03 07:14:20 mlelstv Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -513,7 +513,7 @@ alloc_chipmem(u_long size)
|
|||
* for a new node in between.
|
||||
*/
|
||||
TAILQ_REMOVE(&free_list, mn, free_link);
|
||||
TAILQ_NEXT(mn, free_link) = NULL;
|
||||
mn->type = MNODE_USED;
|
||||
size = mn->size; /* increase size. (or same) */
|
||||
chip_total -= mn->size;
|
||||
splx(s);
|
||||
|
@ -533,7 +533,7 @@ alloc_chipmem(u_long size)
|
|||
* and mark as not on free list
|
||||
*/
|
||||
TAILQ_INSERT_AFTER(&chip_list, new, mn, link);
|
||||
TAILQ_NEXT(mn, free_link) = NULL;
|
||||
mn->type = MNODE_USED;
|
||||
|
||||
chip_total -= size + sizeof(struct mem_node);
|
||||
splx(s);
|
||||
|
@ -557,52 +557,53 @@ free_chipmem(void *mem)
|
|||
/*
|
||||
* check ahead of us.
|
||||
*/
|
||||
if (TAILQ_NEXT(next, link) != NULL &&
|
||||
TAILQ_NEXT(next, free_link) != NULL) {
|
||||
if (next->type == MNODE_FREE) {
|
||||
/*
|
||||
* if next is: a valid node and a free node. ==> merge
|
||||
*/
|
||||
TAILQ_INSERT_BEFORE(next, mn, free_link);
|
||||
mn->type = MNODE_FREE;
|
||||
TAILQ_REMOVE(&chip_list, next, link);
|
||||
TAILQ_REMOVE(&chip_list, next, free_link);
|
||||
TAILQ_REMOVE(&free_list, next, free_link);
|
||||
chip_total += mn->size + sizeof(struct mem_node);
|
||||
mn->size += next->size + sizeof(struct mem_node);
|
||||
}
|
||||
if (TAILQ_PREV(prev, chiplist, link) != NULL &&
|
||||
TAILQ_PREV(prev, freelist, free_link) != NULL) {
|
||||
if (prev->type == MNODE_FREE) {
|
||||
/*
|
||||
* if prev is: a valid node and a free node. ==> merge
|
||||
*/
|
||||
if (TAILQ_NEXT(mn, free_link) == NULL)
|
||||
if (mn->type != MNODE_FREE)
|
||||
chip_total += mn->size + sizeof(struct mem_node);
|
||||
else {
|
||||
/* already on free list */
|
||||
TAILQ_REMOVE(&free_list, mn, free_link);
|
||||
mn->type = MNODE_USED;
|
||||
chip_total += sizeof(struct mem_node);
|
||||
}
|
||||
TAILQ_REMOVE(&chip_list, mn, link);
|
||||
prev->size += mn->size + sizeof(struct mem_node);
|
||||
} else if (TAILQ_NEXT(mn, free_link) == NULL) {
|
||||
} else if (mn->type != MNODE_FREE) {
|
||||
/*
|
||||
* we still are not on free list and we need to be.
|
||||
* <-- | -->
|
||||
*/
|
||||
while (TAILQ_NEXT(next, link) != NULL &&
|
||||
TAILQ_PREV(prev, chiplist, link) != NULL) {
|
||||
if (TAILQ_NEXT(next, free_link) != NULL) {
|
||||
while (next != NULL && prev != NULL) {
|
||||
if (next->type == MNODE_FREE) {
|
||||
TAILQ_INSERT_BEFORE(next, mn, free_link);
|
||||
mn->type = MNODE_FREE;
|
||||
break;
|
||||
}
|
||||
if (TAILQ_NEXT(prev, free_link) != NULL) {
|
||||
if (prev->type == MNODE_FREE) {
|
||||
TAILQ_INSERT_AFTER(&free_list, prev, mn,
|
||||
free_link);
|
||||
mn->type = MNODE_FREE;
|
||||
break;
|
||||
}
|
||||
prev = TAILQ_PREV(prev, chiplist, link);
|
||||
next = TAILQ_NEXT(next, link);
|
||||
}
|
||||
if (TAILQ_NEXT(mn, free_link) == NULL) {
|
||||
if (TAILQ_NEXT(next, link) == NULL) {
|
||||
if (mn->type != MNODE_FREE) {
|
||||
if (next == NULL) {
|
||||
/*
|
||||
* we are not on list so we can add
|
||||
* ourselves to the tail. (we walked to it.)
|
||||
|
@ -611,6 +612,7 @@ free_chipmem(void *mem)
|
|||
} else {
|
||||
TAILQ_INSERT_HEAD(&free_list,mn,free_link);
|
||||
}
|
||||
mn->type = MNODE_FREE;
|
||||
}
|
||||
chip_total += mn->size; /* add our helpings to the pool. */
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cc.h,v 1.17 2013/11/23 22:48:00 christos Exp $ */
|
||||
/* $NetBSD: cc.h,v 1.18 2014/01/03 07:14:20 mlelstv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Christian E. Hopps
|
||||
|
@ -160,7 +160,10 @@ struct mem_node {
|
|||
TAILQ_ENTRY(mem_node) link;
|
||||
TAILQ_ENTRY(mem_node) free_link;
|
||||
u_long size; /* size of memory following node. */
|
||||
u_char type; /* free, used */
|
||||
};
|
||||
#define MNODE_FREE 0
|
||||
#define MNODE_USED 1
|
||||
|
||||
#define CM_BLOCKSIZE 0x4
|
||||
#define CM_BLOCKMASK (~(CM_BLOCKSIZE - 1))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: stalloc.c,v 1.15 2013/11/27 17:24:43 christos Exp $ */
|
||||
/* $NetBSD: stalloc.c,v 1.16 2014/01/03 07:14:20 mlelstv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Leo Weppelman (Atari modifications)
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: stalloc.c,v 1.15 2013/11/27 17:24:43 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: stalloc.c,v 1.16 2014/01/03 07:14:20 mlelstv Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -117,7 +117,7 @@ alloc_stmem(u_long size, void **phys_addr)
|
|||
* for a new node in between.
|
||||
*/
|
||||
TAILQ_REMOVE(&free_list, mn, free_link);
|
||||
TAILQ_NEXT(mn, free_link) = NULL;
|
||||
mn->type = MNODE_USED;
|
||||
size = mn->size; /* increase size. (or same) */
|
||||
stmem_total -= mn->size;
|
||||
splx(s);
|
||||
|
@ -138,7 +138,7 @@ alloc_stmem(u_long size, void **phys_addr)
|
|||
* and mark as not on free list
|
||||
*/
|
||||
TAILQ_INSERT_AFTER(&st_list, new, mn, link);
|
||||
TAILQ_NEXT(mn, free_link) = NULL;
|
||||
mn->type = MNODE_USED;
|
||||
|
||||
stmem_total -= size + sizeof(struct mem_node);
|
||||
splx(s);
|
||||
|
@ -150,7 +150,7 @@ void
|
|||
free_stmem(void *mem)
|
||||
{
|
||||
struct mem_node *mn, *next, *prev;
|
||||
int s;
|
||||
int s;
|
||||
|
||||
if (mem == NULL)
|
||||
return;
|
||||
|
@ -163,48 +163,52 @@ free_stmem(void *mem)
|
|||
/*
|
||||
* check ahead of us.
|
||||
*/
|
||||
if (next != NULL && TAILQ_NEXT(next, free_link) != NULL) {
|
||||
if (next->type == MNODE_FREE) {
|
||||
/*
|
||||
* if next is: a valid node and a free node. ==> merge
|
||||
*/
|
||||
TAILQ_INSERT_BEFORE(next, mn, free_link);
|
||||
mn->type = MNODE_FREE;
|
||||
TAILQ_REMOVE(&st_list, next, link);
|
||||
TAILQ_REMOVE(&st_list, next, free_link);
|
||||
TAILQ_REMOVE(&free_list, next, free_link);
|
||||
stmem_total += mn->size + sizeof(struct mem_node);
|
||||
mn->size += next->size + sizeof(struct mem_node);
|
||||
}
|
||||
if (prev != NULL && TAILQ_PREV(prev, freelist, free_link) != NULL) {
|
||||
if (prev->type == MNODE_FREE) {
|
||||
/*
|
||||
* if prev is: a valid node and a free node. ==> merge
|
||||
*/
|
||||
if (TAILQ_NEXT(mn, free_link) == NULL)
|
||||
if (mn->type != MNODE_FREE)
|
||||
stmem_total += mn->size + sizeof(struct mem_node);
|
||||
else {
|
||||
/* already on free list */
|
||||
TAILQ_REMOVE(&free_list, mn, free_link);
|
||||
mn->type = MNODE_USED;
|
||||
stmem_total += sizeof(struct mem_node);
|
||||
}
|
||||
TAILQ_REMOVE(&st_list, mn, link);
|
||||
prev->size += mn->size + sizeof(struct mem_node);
|
||||
} else if (TAILQ_NEXT(mn, free_link) == NULL) {
|
||||
} else if (mn->type != MNODE_FREE) {
|
||||
/*
|
||||
* we still are not on free list and we need to be.
|
||||
* <-- | -->
|
||||
*/
|
||||
while (next != NULL && prev != NULL) {
|
||||
if (TAILQ_NEXT(next, free_link) != NULL) {
|
||||
if (next->type == MNODE_FREE) {
|
||||
TAILQ_INSERT_BEFORE(next, mn, free_link);
|
||||
mn->type = MNODE_FREE;
|
||||
break;
|
||||
}
|
||||
if (TAILQ_NEXT(prev, free_link) != NULL) {
|
||||
if (prev->type == MNODE_FREE) {
|
||||
TAILQ_INSERT_AFTER(&free_list, prev, mn,
|
||||
free_link);
|
||||
mn->type = MNODE_FREE;
|
||||
break;
|
||||
}
|
||||
prev = TAILQ_PREV(prev, stlist, link);
|
||||
next = TAILQ_NEXT(next, link);
|
||||
}
|
||||
if (TAILQ_NEXT(mn, free_link) == NULL) {
|
||||
if (mn->type != MNODE_FREE) {
|
||||
if (next == NULL) {
|
||||
/*
|
||||
* we are not on list so we can add
|
||||
|
@ -214,6 +218,7 @@ free_stmem(void *mem)
|
|||
} else {
|
||||
TAILQ_INSERT_HEAD(&free_list,mn,free_link);
|
||||
}
|
||||
mn->type = MNODE_FREE;
|
||||
}
|
||||
stmem_total += mn->size;/* add our helpings to the pool. */
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: stalloc.h,v 1.5 2013/11/23 22:52:40 christos Exp $ */
|
||||
/* $NetBSD: stalloc.h,v 1.6 2014/01/03 07:14:20 mlelstv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Christian E. Hopps (allocator stuff)
|
||||
|
@ -42,7 +42,10 @@ struct mem_node {
|
|||
TAILQ_ENTRY(mem_node) link;
|
||||
TAILQ_ENTRY(mem_node) free_link;
|
||||
u_long size; /* size of memory following node. */
|
||||
u_char type; /* free, used */
|
||||
};
|
||||
#define MNODE_FREE 0
|
||||
#define MNODE_USED 1
|
||||
|
||||
#define ST_BLOCKSIZE (sizeof(long))
|
||||
#define ST_BLOCKMASK (~(ST_BLOCKSIZE - 1))
|
||||
|
|
Loading…
Reference in New Issue