|
@ -8,7 +8,7 @@ |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
#if defined(LIBC_SCCS) && !defined(lint) |
|
|
#if defined(LIBC_SCCS) && !defined(lint) |
|
|
static char rcsid[] = "$OpenBSD: malloc.c,v 1.5 1996/08/19 08:33:37 tholo Exp $"; |
|
|
|
|
|
|
|
|
static char rcsid[] = "$OpenBSD: malloc.c,v 1.6 1996/08/20 17:30:49 downsj Exp $"; |
|
|
#endif /* LIBC_SCCS and not lint */ |
|
|
#endif /* LIBC_SCCS and not lint */ |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@ -24,6 +24,11 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.5 1996/08/19 08:33:37 tholo Exp $" |
|
|
*/ |
|
|
*/ |
|
|
#define MALLOC_STATS |
|
|
#define MALLOC_STATS |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Defining CFREE_STUB will include a cfree() stub that just calls free(). |
|
|
|
|
|
*/ |
|
|
|
|
|
#define CFREE_STUB |
|
|
|
|
|
|
|
|
#if defined(EXTRA_SANITY) && !defined(MALLOC_STATS) |
|
|
#if defined(EXTRA_SANITY) && !defined(MALLOC_STATS) |
|
|
# define MALLOC_STATS /* required for EXTRA_SANITY */ |
|
|
# define MALLOC_STATS /* required for EXTRA_SANITY */ |
|
|
#endif |
|
|
#endif |
|
@ -111,7 +116,8 @@ struct pgfree { |
|
|
#ifdef __i386__ |
|
|
#ifdef __i386__ |
|
|
#define ffs _ffs |
|
|
#define ffs _ffs |
|
|
static __inline int |
|
|
static __inline int |
|
|
_ffs(unsigned input) |
|
|
|
|
|
|
|
|
_ffs(input) |
|
|
|
|
|
unsigned input; |
|
|
{ |
|
|
{ |
|
|
int result; |
|
|
int result; |
|
|
asm("bsfl %1,%0" : "=r" (result) : "r" (input)); |
|
|
asm("bsfl %1,%0" : "=r" (result) : "r" (input)); |
|
@ -120,7 +126,8 @@ _ffs(unsigned input) |
|
|
|
|
|
|
|
|
#define fls _fls |
|
|
#define fls _fls |
|
|
static __inline int |
|
|
static __inline int |
|
|
_fls(unsigned input) |
|
|
|
|
|
|
|
|
_fls(input) |
|
|
|
|
|
unsigned input; |
|
|
{ |
|
|
{ |
|
|
int result; |
|
|
int result; |
|
|
asm("bsrl %1,%0" : "=r" (result) : "r" (input)); |
|
|
asm("bsrl %1,%0" : "=r" (result) : "r" (input)); |
|
@ -129,7 +136,9 @@ _fls(unsigned input) |
|
|
|
|
|
|
|
|
#define set_bit _set_bit |
|
|
#define set_bit _set_bit |
|
|
static __inline void |
|
|
static __inline void |
|
|
_set_bit(struct pginfo *pi, int bit) |
|
|
|
|
|
|
|
|
_set_bit(pi, bit) |
|
|
|
|
|
struct pginfo *pi; |
|
|
|
|
|
int bit; |
|
|
{ |
|
|
{ |
|
|
asm("btsl %0,(%1)" : |
|
|
asm("btsl %0,(%1)" : |
|
|
: "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS))); |
|
|
: "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS))); |
|
@ -137,7 +146,9 @@ _set_bit(struct pginfo *pi, int bit) |
|
|
|
|
|
|
|
|
#define clr_bit _clr_bit |
|
|
#define clr_bit _clr_bit |
|
|
static __inline void |
|
|
static __inline void |
|
|
_clr_bit(struct pginfo *pi, int bit) |
|
|
|
|
|
|
|
|
_clr_bit(pi, bit) |
|
|
|
|
|
struct pginfo *pi; |
|
|
|
|
|
int bit; |
|
|
{ |
|
|
{ |
|
|
asm("btcl %0,(%1)" : |
|
|
asm("btcl %0,(%1)" : |
|
|
: "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS))); |
|
|
: "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS))); |
|
@ -273,7 +284,8 @@ static int extend_pgdir(u_long index); |
|
|
|
|
|
|
|
|
#ifdef MALLOC_STATS |
|
|
#ifdef MALLOC_STATS |
|
|
void |
|
|
void |
|
|
malloc_dump(FILE *fd) |
|
|
|
|
|
|
|
|
malloc_dump(fd) |
|
|
|
|
|
FILE *fd; |
|
|
{ |
|
|
{ |
|
|
struct pginfo **pd; |
|
|
struct pginfo **pd; |
|
|
struct pgfree *pf; |
|
|
struct pgfree *pf; |
|
@ -330,7 +342,8 @@ malloc_dump(FILE *fd) |
|
|
#endif /* MALLOC_STATS */ |
|
|
#endif /* MALLOC_STATS */ |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
wrterror(char *p) |
|
|
|
|
|
|
|
|
wrterror(p) |
|
|
|
|
|
char *p; |
|
|
{ |
|
|
{ |
|
|
char *q = "Malloc error: "; |
|
|
char *q = "Malloc error: "; |
|
|
suicide = 1; |
|
|
suicide = 1; |
|
@ -344,7 +357,8 @@ wrterror(char *p) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
wrtwarning(char *p) |
|
|
|
|
|
|
|
|
wrtwarning(p) |
|
|
|
|
|
char *p; |
|
|
{ |
|
|
{ |
|
|
char *q = "Malloc warning: "; |
|
|
char *q = "Malloc warning: "; |
|
|
if (malloc_abort) |
|
|
if (malloc_abort) |
|
@ -372,7 +386,8 @@ malloc_exit() |
|
|
* Allocate a number of pages from the OS |
|
|
* Allocate a number of pages from the OS |
|
|
*/ |
|
|
*/ |
|
|
static caddr_t |
|
|
static caddr_t |
|
|
map_pages(int pages) |
|
|
|
|
|
|
|
|
map_pages(pages) |
|
|
|
|
|
int pages; |
|
|
{ |
|
|
{ |
|
|
caddr_t result,tail; |
|
|
caddr_t result,tail; |
|
|
|
|
|
|
|
@ -400,7 +415,9 @@ map_pages(int pages) |
|
|
*/ |
|
|
*/ |
|
|
#ifndef set_bit |
|
|
#ifndef set_bit |
|
|
static __inline void |
|
|
static __inline void |
|
|
set_bit(struct pginfo *pi, int bit) |
|
|
|
|
|
|
|
|
set_bit(pi, bit) |
|
|
|
|
|
struct pginfo *pi; |
|
|
|
|
|
int bit; |
|
|
{ |
|
|
{ |
|
|
pi->bits[bit/MALLOC_BITS] |= 1<<(bit%MALLOC_BITS); |
|
|
pi->bits[bit/MALLOC_BITS] |= 1<<(bit%MALLOC_BITS); |
|
|
} |
|
|
} |
|
@ -411,7 +428,9 @@ set_bit(struct pginfo *pi, int bit) |
|
|
*/ |
|
|
*/ |
|
|
#ifndef clr_bit |
|
|
#ifndef clr_bit |
|
|
static __inline void |
|
|
static __inline void |
|
|
clr_bit(struct pginfo *pi, int bit) |
|
|
|
|
|
|
|
|
clr_bit(pi, bit) |
|
|
|
|
|
struct pginfo *pi; |
|
|
|
|
|
int bit; |
|
|
{ |
|
|
{ |
|
|
pi->bits[bit/MALLOC_BITS] &= ~(1<<(bit%MALLOC_BITS)); |
|
|
pi->bits[bit/MALLOC_BITS] &= ~(1<<(bit%MALLOC_BITS)); |
|
|
} |
|
|
} |
|
@ -422,7 +441,9 @@ clr_bit(struct pginfo *pi, int bit) |
|
|
* Test a bit in the bitmap |
|
|
* Test a bit in the bitmap |
|
|
*/ |
|
|
*/ |
|
|
static __inline int |
|
|
static __inline int |
|
|
tst_bit(struct pginfo *pi, int bit) |
|
|
|
|
|
|
|
|
tst_bit(pi, bit) |
|
|
|
|
|
struct pginfo *pi; |
|
|
|
|
|
int bit; |
|
|
{ |
|
|
{ |
|
|
return pi->bits[bit/MALLOC_BITS] & (1<<(bit%MALLOC_BITS)); |
|
|
return pi->bits[bit/MALLOC_BITS] & (1<<(bit%MALLOC_BITS)); |
|
|
} |
|
|
} |
|
@ -433,7 +454,8 @@ tst_bit(struct pginfo *pi, int bit) |
|
|
*/ |
|
|
*/ |
|
|
#ifndef fls |
|
|
#ifndef fls |
|
|
static __inline int |
|
|
static __inline int |
|
|
fls(int size) |
|
|
|
|
|
|
|
|
fls(size) |
|
|
|
|
|
int size; |
|
|
{ |
|
|
{ |
|
|
int i = 1; |
|
|
int i = 1; |
|
|
while (size >>= 1) |
|
|
while (size >>= 1) |
|
@ -446,7 +468,8 @@ fls(int size) |
|
|
* Extend page directory |
|
|
* Extend page directory |
|
|
*/ |
|
|
*/ |
|
|
static int |
|
|
static int |
|
|
extend_pgdir(u_long index) |
|
|
|
|
|
|
|
|
extend_pgdir(index) |
|
|
|
|
|
u_long index; |
|
|
{ |
|
|
{ |
|
|
struct pginfo **new,**old; |
|
|
struct pginfo **new,**old; |
|
|
int i, oldlen; |
|
|
int i, oldlen; |
|
@ -617,7 +640,8 @@ malloc_init () |
|
|
* Allocate a number of complete pages |
|
|
* Allocate a number of complete pages |
|
|
*/ |
|
|
*/ |
|
|
void * |
|
|
void * |
|
|
malloc_pages(size_t size) |
|
|
|
|
|
|
|
|
malloc_pages(size) |
|
|
|
|
|
size_t size; |
|
|
{ |
|
|
{ |
|
|
void *p,*delay_free = 0; |
|
|
void *p,*delay_free = 0; |
|
|
int i; |
|
|
int i; |
|
@ -702,7 +726,8 @@ malloc_pages(size_t size) |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
static __inline int |
|
|
static __inline int |
|
|
malloc_make_chunks(int bits) |
|
|
|
|
|
|
|
|
malloc_make_chunks(bits) |
|
|
|
|
|
int bits; |
|
|
{ |
|
|
{ |
|
|
struct pginfo *bp; |
|
|
struct pginfo *bp; |
|
|
void *pp; |
|
|
void *pp; |
|
@ -765,7 +790,8 @@ malloc_make_chunks(int bits) |
|
|
* Allocate a fragment |
|
|
* Allocate a fragment |
|
|
*/ |
|
|
*/ |
|
|
static void * |
|
|
static void * |
|
|
malloc_bytes(size_t size) |
|
|
|
|
|
|
|
|
malloc_bytes(size) |
|
|
|
|
|
size_t size; |
|
|
{ |
|
|
{ |
|
|
int j; |
|
|
int j; |
|
|
struct pginfo *bp; |
|
|
struct pginfo *bp; |
|
@ -813,7 +839,8 @@ malloc_bytes(size_t size) |
|
|
* Allocate a piece of memory |
|
|
* Allocate a piece of memory |
|
|
*/ |
|
|
*/ |
|
|
void * |
|
|
void * |
|
|
malloc(size_t size) |
|
|
|
|
|
|
|
|
malloc(size) |
|
|
|
|
|
size_t size; |
|
|
{ |
|
|
{ |
|
|
void *result; |
|
|
void *result; |
|
|
#ifdef _THREAD_SAFE |
|
|
#ifdef _THREAD_SAFE |
|
@ -850,7 +877,9 @@ malloc(size_t size) |
|
|
* Change the size of an allocation. |
|
|
* Change the size of an allocation. |
|
|
*/ |
|
|
*/ |
|
|
void * |
|
|
void * |
|
|
realloc(void *ptr, size_t size) |
|
|
|
|
|
|
|
|
realloc(ptr, size) |
|
|
|
|
|
void *ptr; |
|
|
|
|
|
size_t size; |
|
|
{ |
|
|
{ |
|
|
void *p; |
|
|
void *p; |
|
|
u_long osize,index; |
|
|
u_long osize,index; |
|
@ -987,7 +1016,10 @@ realloc(void *ptr, size_t size) |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
static __inline void |
|
|
static __inline void |
|
|
free_pages(void *ptr, int index, struct pginfo *info) |
|
|
|
|
|
|
|
|
free_pages(ptr, index, info) |
|
|
|
|
|
void *ptr; |
|
|
|
|
|
int index; |
|
|
|
|
|
struct pginfo *info; |
|
|
{ |
|
|
{ |
|
|
int i; |
|
|
int i; |
|
|
struct pgfree *pf,*pt; |
|
|
struct pgfree *pf,*pt; |
|
@ -1110,7 +1142,10 @@ free_pages(void *ptr, int index, struct pginfo *info) |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
static __inline void |
|
|
static __inline void |
|
|
free_bytes(void *ptr, int index, struct pginfo *info) |
|
|
|
|
|
|
|
|
free_bytes(ptr, index, info) |
|
|
|
|
|
void *ptr; |
|
|
|
|
|
int index; |
|
|
|
|
|
struct pginfo *info; |
|
|
{ |
|
|
{ |
|
|
int i; |
|
|
int i; |
|
|
struct pginfo **mp; |
|
|
struct pginfo **mp; |
|
@ -1169,7 +1204,8 @@ free_bytes(void *ptr, int index, struct pginfo *info) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
free(void *ptr) |
|
|
|
|
|
|
|
|
free(ptr) |
|
|
|
|
|
void *ptr; |
|
|
{ |
|
|
{ |
|
|
struct pginfo *info; |
|
|
struct pginfo *info; |
|
|
int index; |
|
|
int index; |
|
@ -1222,3 +1258,12 @@ free(void *ptr) |
|
|
#endif |
|
|
#endif |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef CFREE_STUB |
|
|
|
|
|
void |
|
|
|
|
|
cfree(ptr) |
|
|
|
|
|
void *ptr; |
|
|
|
|
|
{ |
|
|
|
|
|
free(ptr); |
|
|
|
|
|
} |
|
|
|
|
|
#endif |