Browse Source

add recaloc(3)

OPENBSD_4_3
millert 17 years ago
parent
commit
63cad49094
4 changed files with 64 additions and 21 deletions
  1. +2
    -1
      src/include/stdlib.h
  2. +2
    -2
      src/lib/libc/stdlib/Makefile.inc
  3. +25
    -3
      src/lib/libc/stdlib/malloc.3
  4. +35
    -15
      src/lib/libc/stdlib/malloc.c

+ 2
- 1
src/include/stdlib.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: stdlib.h,v 1.39 2006/09/17 16:48:04 djm Exp $ */
/* $OpenBSD: stdlib.h,v 1.40 2007/09/03 14:37:02 millert Exp $ */
/* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ /* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */
/*- /*-
@ -128,6 +128,7 @@ void *malloc(size_t);
void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
int rand(void); int rand(void);
void *realloc(void *, size_t); void *realloc(void *, size_t);
void *recalloc(void *, size_t, size_t);
void srand(unsigned); void srand(unsigned);
double strtod(const char *, char **); double strtod(const char *, char **);
long strtol(const char *, char **, int); long strtol(const char *, char **, int);


+ 2
- 2
src/lib/libc/stdlib/Makefile.inc View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile.inc,v 1.35 2006/01/13 17:58:09 millert Exp $
# $OpenBSD: Makefile.inc,v 1.36 2007/09/03 14:37:02 millert Exp $
# stdlib sources # stdlib sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib .PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
@ -55,7 +55,7 @@ MLINKS+=insque.3 remque.3
MLINKS+=labs.3 llabs.3 MLINKS+=labs.3 llabs.3
MLINKS+=lsearch.3 lfind.3 MLINKS+=lsearch.3 lfind.3
MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3 MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
MLINKS+=malloc.3 recalloc.3 malloc.3 cfree.3 malloc.3 malloc.conf.5
MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
MLINKS+=radixsort.3 sradixsort.3 MLINKS+=radixsort.3 sradixsort.3
MLINKS+=rand.3 srand.3 rand.3 rand_r.3 MLINKS+=rand.3 srand.3 rand.3 rand_r.3


+ 25
- 3
src/lib/libc/stdlib/malloc.3 View File

@ -30,15 +30,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: malloc.3,v 1.47 2007/08/08 21:24:29 millert Exp $
.\" $OpenBSD: malloc.3,v 1.48 2007/09/03 14:37:02 millert Exp $
.\" .\"
.Dd $Mdocdate: August 8 2007 $
.Dd $Mdocdate: September 3 2007 $
.Dt MALLOC 3 .Dt MALLOC 3
.Os .Os
.Sh NAME .Sh NAME
.Nm malloc , .Nm malloc ,
.Nm calloc , .Nm calloc ,
.Nm realloc , .Nm realloc ,
.Nm recalloc ,
.Nm free , .Nm free ,
.Nm cfree .Nm cfree
.Nd memory allocation and deallocation .Nd memory allocation and deallocation
@ -50,6 +51,8 @@
.Fn calloc "size_t nmemb" "size_t size" .Fn calloc "size_t nmemb" "size_t size"
.Ft void * .Ft void *
.Fn realloc "void *ptr" "size_t size" .Fn realloc "void *ptr" "size_t size"
.Ft void *
.Fn recalloc "void *ptr" "size_t nmemb" "size_t size"
.Ft void .Ft void
.Fn free "void *ptr" .Fn free "void *ptr"
.Ft void .Ft void
@ -203,7 +206,18 @@ if ((newp = realloc(p, num * size)) == NULL) {
... ...
.Ed .Ed
.Pp .Pp
Malloc will first look for a symbolic link called
The
.Fn recalloc
function is similar to
.Fn realloc
except that it shares semantics with
.Fn calloc
rather than
.Fn malloc .
Newly allocated space is initialized to zero and the resulting size is
checked for integer overflow.
.Pp
These functions will first look for a symbolic link called
.Pa /etc/malloc.conf .Pa /etc/malloc.conf
and next check the environment for a variable called and next check the environment for a variable called
.Ev MALLOC_OPTIONS .Ev MALLOC_OPTIONS
@ -258,6 +272,8 @@ sizeof(ptr) errors where sizeof(*ptr) is meant.
.Dq realloc . .Dq realloc .
Always reallocate when Always reallocate when
.Fn realloc .Fn realloc
or
.Fn recalloc
is called, even if the initial allocation was big enough. is called, even if the initial allocation was big enough.
This can substantially aid in compacting memory. This can substantially aid in compacting memory.
.\".Pp .\".Pp
@ -440,6 +456,12 @@ The
.Fn malloc .Fn malloc
function conforms to function conforms to
.St -ansiC . .St -ansiC .
.Pp
The
.Fn recalloc
function is an
.Ox
extension.
.Sh HISTORY .Sh HISTORY
The present implementation of The present implementation of
.Fn malloc .Fn malloc


+ 35
- 15
src/lib/libc/stdlib/malloc.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.86 2007/02/12 20:00:14 otto Exp $ */
/* $OpenBSD: malloc.c,v 1.87 2007/09/03 14:37:02 millert Exp $ */
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -250,9 +250,9 @@ static char *malloc_func;
/* /*
* Necessary function declarations. * Necessary function declarations.
*/ */
static void *imalloc(size_t size);
static void *imalloc(size_t size, int zero_fill);
static void ifree(void *ptr); static void ifree(void *ptr);
static void *irealloc(void *ptr, size_t size);
static void *irealloc(void *ptr, size_t size, int zero_fill);
static void *malloc_bytes(size_t size); static void *malloc_bytes(size_t size);
static struct pginfo *pginfo_list; static struct pginfo *pginfo_list;
@ -1188,7 +1188,7 @@ malloc_bytes(size_t size)
* Allocate a piece of memory * Allocate a piece of memory
*/ */
static void * static void *
imalloc(size_t size)
imalloc(size_t size, int zero_fill)
{ {
void *result; void *result;
int ptralloc = 0; int ptralloc = 0;
@ -1218,7 +1218,7 @@ imalloc(size_t size)
if (malloc_abort == 1 && result == NULL) if (malloc_abort == 1 && result == NULL)
wrterror("allocation failed"); wrterror("allocation failed");
if (malloc_zero && result != NULL)
if ((malloc_zero || zero_fill) && result != NULL)
memset(result, 0, size); memset(result, 0, size);
if (result && ptralloc) if (result && ptralloc)
@ -1230,7 +1230,7 @@ imalloc(size_t size)
* Change the size of an allocation. * Change the size of an allocation.
*/ */
static void * static void *
irealloc(void *ptr, size_t size)
irealloc(void *ptr, size_t size, int zero_fill)
{ {
void *p; void *p;
size_t osize; size_t osize;
@ -1253,7 +1253,7 @@ irealloc(void *ptr, size_t size)
if (size <= PTR_SIZE) if (size <= PTR_SIZE)
return (ptr); return (ptr);
p = imalloc(size);
p = imalloc(size, zero_fill);
if (p) if (p)
memcpy(p, ptr, PTR_SIZE); memcpy(p, ptr, PTR_SIZE);
ifree(ptr); ifree(ptr);
@ -1315,7 +1315,9 @@ irealloc(void *ptr, size_t size)
if (!malloc_realloc && size <= osize && if (!malloc_realloc && size <= osize &&
size > osize - malloc_pagesize) { size > osize - malloc_pagesize) {
if (malloc_junk)
if (zero_fill)
memset((char *)ptr + size, 0, osize - size);
else if (malloc_junk)
memset((char *)ptr + size, SOME_JUNK, osize - size); memset((char *)ptr + size, SOME_JUNK, osize - size);
return (ptr); /* ..don't do anything else. */ return (ptr); /* ..don't do anything else. */
} }
@ -1338,7 +1340,9 @@ irealloc(void *ptr, size_t size)
if (!malloc_realloc && size <= osize && if (!malloc_realloc && size <= osize &&
(size > osize / 2 || osize == malloc_minsize)) { (size > osize / 2 || osize == malloc_minsize)) {
if (malloc_junk)
if (zero_fill)
memset((char *) ptr + size, 0, osize - size);
else if (malloc_junk)
memset((char *) ptr + size, SOME_JUNK, osize - size); memset((char *) ptr + size, SOME_JUNK, osize - size);
return (ptr); /* ..don't do anything else. */ return (ptr); /* ..don't do anything else. */
} }
@ -1347,7 +1351,7 @@ irealloc(void *ptr, size_t size)
return (NULL); return (NULL);
} }
p = imalloc(size);
p = imalloc(size, zero_fill);
if (p != NULL) { if (p != NULL) {
/* copy the lesser of the two sizes, and free the old one */ /* copy the lesser of the two sizes, and free the old one */
@ -1876,7 +1880,7 @@ malloc(size_t size)
malloc_recurse(); malloc_recurse();
return (NULL); return (NULL);
} }
r = imalloc(size);
r = imalloc(size, 0);
UTRACE(0, size, r); UTRACE(0, size, r);
malloc_active--; malloc_active--;
_MALLOC_UNLOCK(); _MALLOC_UNLOCK();
@ -1907,8 +1911,8 @@ free(void *ptr)
return; return;
} }
void *
realloc(void *ptr, size_t size)
static void *
_realloc(void *ptr, size_t size, int zero_fill)
{ {
void *r; void *r;
@ -1920,9 +1924,9 @@ realloc(void *ptr, size_t size)
} }
if (ptr == NULL) if (ptr == NULL)
r = imalloc(size);
r = imalloc(size, zero_fill);
else else
r = irealloc(ptr, size);
r = irealloc(ptr, size, zero_fill);
UTRACE(ptr, size, r); UTRACE(ptr, size, r);
malloc_active--; malloc_active--;
@ -1933,3 +1937,19 @@ realloc(void *ptr, size_t size)
} }
return (r); return (r);
} }
void *
realloc(void *ptr, size_t size)
{
return (_realloc(ptr, size, 0));
}
void *
recalloc(void *ptr, size_t nmemb, size_t size)
{
if (nmemb && SIZE_MAX / nmemb < size) {
errno = ENOMEM;
return (NULL);
}
return (_realloc(ptr, nmemb * size, 1));
}

Loading…
Cancel
Save