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 $ */
/*-
@ -128,6 +128,7 @@ void *malloc(size_t);
void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
int rand(void);
void *realloc(void *, size_t);
void *recalloc(void *, size_t, size_t);
void srand(unsigned);
double strtod(const char *, char **);
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
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
@ -55,7 +55,7 @@ MLINKS+=insque.3 remque.3
MLINKS+=labs.3 llabs.3
MLINKS+=lsearch.3 lfind.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+=radixsort.3 sradixsort.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
.\" 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
.Os
.Sh NAME
.Nm malloc ,
.Nm calloc ,
.Nm realloc ,
.Nm recalloc ,
.Nm free ,
.Nm cfree
.Nd memory allocation and deallocation
@ -50,6 +51,8 @@
.Fn calloc "size_t nmemb" "size_t size"
.Ft void *
.Fn realloc "void *ptr" "size_t size"
.Ft void *
.Fn recalloc "void *ptr" "size_t nmemb" "size_t size"
.Ft void
.Fn free "void *ptr"
.Ft void
@ -203,7 +206,18 @@ if ((newp = realloc(p, num * size)) == NULL) {
...
.Ed
.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
and next check the environment for a variable called
.Ev MALLOC_OPTIONS
@ -258,6 +272,8 @@ sizeof(ptr) errors where sizeof(*ptr) is meant.
.Dq realloc .
Always reallocate when
.Fn realloc
or
.Fn recalloc
is called, even if the initial allocation was big enough.
This can substantially aid in compacting memory.
.\".Pp
@ -440,6 +456,12 @@ The
.Fn malloc
function conforms to
.St -ansiC .
.Pp
The
.Fn recalloc
function is an
.Ox
extension.
.Sh HISTORY
The present implementation of
.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.
*/
static void *imalloc(size_t size);
static void *imalloc(size_t size, int zero_fill);
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 struct pginfo *pginfo_list;
@ -1188,7 +1188,7 @@ malloc_bytes(size_t size)
* Allocate a piece of memory
*/
static void *
imalloc(size_t size)
imalloc(size_t size, int zero_fill)
{
void *result;
int ptralloc = 0;
@ -1218,7 +1218,7 @@ imalloc(size_t size)
if (malloc_abort == 1 && result == NULL)
wrterror("allocation failed");
if (malloc_zero && result != NULL)
if ((malloc_zero || zero_fill) && result != NULL)
memset(result, 0, size);
if (result && ptralloc)
@ -1230,7 +1230,7 @@ imalloc(size_t size)
* Change the size of an allocation.
*/
static void *
irealloc(void *ptr, size_t size)
irealloc(void *ptr, size_t size, int zero_fill)
{
void *p;
size_t osize;
@ -1253,7 +1253,7 @@ irealloc(void *ptr, size_t size)
if (size <= PTR_SIZE)
return (ptr);
p = imalloc(size);
p = imalloc(size, zero_fill);
if (p)
memcpy(p, ptr, PTR_SIZE);
ifree(ptr);
@ -1315,7 +1315,9 @@ irealloc(void *ptr, size_t size)
if (!malloc_realloc && size <= osize &&
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);
return (ptr); /* ..don't do anything else. */
}
@ -1338,7 +1340,9 @@ irealloc(void *ptr, size_t size)
if (!malloc_realloc && size <= osize &&
(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);
return (ptr); /* ..don't do anything else. */
}
@ -1347,7 +1351,7 @@ irealloc(void *ptr, size_t size)
return (NULL);
}
p = imalloc(size);
p = imalloc(size, zero_fill);
if (p != NULL) {
/* copy the lesser of the two sizes, and free the old one */
@ -1876,7 +1880,7 @@ malloc(size_t size)
malloc_recurse();
return (NULL);
}
r = imalloc(size);
r = imalloc(size, 0);
UTRACE(0, size, r);
malloc_active--;
_MALLOC_UNLOCK();
@ -1907,8 +1911,8 @@ free(void *ptr)
return;
}
void *
realloc(void *ptr, size_t size)
static void *
_realloc(void *ptr, size_t size, int zero_fill)
{
void *r;
@ -1920,9 +1924,9 @@ realloc(void *ptr, size_t size)
}
if (ptr == NULL)
r = imalloc(size);
r = imalloc(size, zero_fill);
else
r = irealloc(ptr, size);
r = irealloc(ptr, size, zero_fill);
UTRACE(ptr, size, r);
malloc_active--;
@ -1933,3 +1937,19 @@ realloc(void *ptr, size_t size)
}
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