In preparation for a new malloc implementation:
* Add posix_memalign(). * Move calloc() from calloc.c to malloc.c. Add a calloc() implementation in rtld-elf in order to make the loader happy (even though calloc() isn't used in rtld-elf). * Add _malloc_prefork() and _malloc_postfork(), and use them instead of directly manipulating __malloc_lock. Approved by: phk, markm (mentor)
This commit is contained in:
parent
0b61bced98
commit
52828c0e9c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154248
@ -130,10 +130,11 @@ void _set_tp(void *tp);
|
||||
extern const char *__progname;
|
||||
|
||||
/*
|
||||
* This is the lock to make malloc() thread-safe. It is externalized
|
||||
* so that thread libraries can protect malloc across fork().
|
||||
* These functions are used by the threading libraries in order to protect
|
||||
* malloc across fork().
|
||||
*/
|
||||
extern struct _spinlock *__malloc_lock;
|
||||
void _malloc_prefork(void);
|
||||
void _malloc_postfork(void);
|
||||
|
||||
/*
|
||||
* Function to clean up streams, called from abort() and exit().
|
||||
|
@ -5,7 +5,7 @@
|
||||
.PATH: ${.CURDIR}/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
|
||||
|
||||
MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
|
||||
bsearch.c calloc.c div.c exit.c getenv.c getopt.c getopt_long.c \
|
||||
bsearch.c div.c exit.c getenv.c getopt.c getopt_long.c \
|
||||
getsubopt.c grantpt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \
|
||||
insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c malloc.c \
|
||||
merge.c putenv.c qsort.c qsort_r.c radixsort.c rand.c random.c \
|
||||
@ -21,7 +21,8 @@ MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
|
||||
MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
|
||||
div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 grantpt.3 \
|
||||
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
|
||||
lsearch.3 malloc.3 memory.3 qsort.3 radixsort.3 rand.3 random.3 \
|
||||
lsearch.3 malloc.3 memory.3 posix_memalign.3 qsort.3 radixsort.3 \
|
||||
rand.3 random.3 \
|
||||
realpath.3 strfmon.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
|
||||
|
||||
MLINKS+=a64l.3 l64a.3 a64l.3 l64a_r.3
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)calloc.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *
|
||||
calloc(num, size)
|
||||
size_t num;
|
||||
size_t size;
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (size != 0 && SIZE_T_MAX / size < num) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
size *= num;
|
||||
if ( (p = malloc(size)) )
|
||||
bzero(p, size);
|
||||
return(p);
|
||||
}
|
@ -1150,6 +1150,50 @@ malloc(size_t size)
|
||||
return (pubrealloc(NULL, size, " in malloc():"));
|
||||
}
|
||||
|
||||
int
|
||||
posix_memalign(void **memptr, size_t alignment, size_t size)
|
||||
{
|
||||
int err;
|
||||
void *result;
|
||||
|
||||
/* Make sure that alignment is a large enough power of 2. */
|
||||
if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *))
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* (size & alignment) is enough to assure the requested alignment, since
|
||||
* the allocator always allocates power-of-two blocks.
|
||||
*/
|
||||
err = errno; /* Protect errno against changes in pubrealloc(). */
|
||||
result = pubrealloc(NULL, (size & alignment), " in posix_memalign()");
|
||||
errno = err;
|
||||
|
||||
if (result == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
*memptr = result;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *
|
||||
calloc(size_t num, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (size != 0 && (num * size) / size != num) {
|
||||
/* size_t overflow. */
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret = pubrealloc(NULL, num * size, " in calloc():");
|
||||
|
||||
if (ret != NULL)
|
||||
memset(ret, 0, num * size);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
free(void *ptr)
|
||||
{
|
||||
@ -1164,3 +1208,23 @@ realloc(void *ptr, size_t size)
|
||||
return (pubrealloc(ptr, size, " in realloc():"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin library-private functions, used by threading libraries for protection
|
||||
* of malloc during fork(). These functions are only called if the program is
|
||||
* running in threaded mode, so there is no need to check whether the program
|
||||
* is threaded here.
|
||||
*/
|
||||
|
||||
void
|
||||
_malloc_prefork(void)
|
||||
{
|
||||
|
||||
_spinlock(__malloc_lock);
|
||||
}
|
||||
|
||||
void
|
||||
_malloc_postfork(void)
|
||||
{
|
||||
|
||||
_spinunlock(__malloc_lock);
|
||||
}
|
||||
|
89
lib/libc/stdlib/posix_memalign.3
Normal file
89
lib/libc/stdlib/posix_memalign.3
Normal file
@ -0,0 +1,89 @@
|
||||
.\" Copyright (C) 2006 Jason Evans <jasone@FreeBSD.org>.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), this list of conditions and the following disclaimer in
|
||||
.\" the documentation and/or other materials provided with the
|
||||
.\" distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
|
||||
.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
|
||||
.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 11, 2006
|
||||
.Dt POSIX_MEMALIGN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm posix_memalign
|
||||
.Nd aligned memory allocation
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In stdlib.h
|
||||
.Ft int
|
||||
.Fn posix_memalign "void **ptr" "size_t alignment" "size_t size"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn posix_memalign
|
||||
function allocates
|
||||
.Fa size
|
||||
bytes of memory such that the allocation's base address is an even multiple of
|
||||
.Fa alignment ,
|
||||
and returns the allocation in the value pointed to by
|
||||
.Fa ptr .
|
||||
.Pp
|
||||
The requested
|
||||
.Fa alignment
|
||||
must be a power of 2 at least as large as sizeof(void *).
|
||||
.Pp
|
||||
Memory that is allocated via
|
||||
.Fn posix_memalign
|
||||
can be used as an argument in subsequent calls to
|
||||
.Xr realloc 3 ,
|
||||
.Xr reallocf 3 ,
|
||||
and
|
||||
.Xr free 3 .
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn posix_memalign
|
||||
function returns the value 0 if successful; otherwise it returns an error value.
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn posix_memalign
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa alignment
|
||||
parameter is not a power of 2 at least as large as sizeof(void *).
|
||||
.It Bq Er ENOMEM
|
||||
Memory allocation error.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr malloc 3 ,
|
||||
.Xr valloc 3 ,
|
||||
.Xr realloc 3 ,
|
||||
.Xr reallocf 3 ,
|
||||
.Xr free 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn posix_memalign
|
||||
function conforms to
|
||||
.St -p1003.1-2001 .
|
@ -91,7 +91,7 @@ _fork(void)
|
||||
|
||||
/* Fork a new process: */
|
||||
if (_kse_isthreaded() != 0) {
|
||||
_spinlock(__malloc_lock);
|
||||
_malloc_prefork();
|
||||
}
|
||||
if ((ret = __sys_fork()) == 0) {
|
||||
/* Child process */
|
||||
@ -107,8 +107,8 @@ _fork(void)
|
||||
}
|
||||
_thr_mutex_reinit(&_thr_atfork_mutex);
|
||||
} else {
|
||||
if ((_kse_isthreaded() != 0) && (__malloc_lock != NULL)) {
|
||||
_spinunlock(__malloc_lock);
|
||||
if (_kse_isthreaded() != 0) {
|
||||
_malloc_postfork();
|
||||
}
|
||||
errsave = errno;
|
||||
if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) {
|
||||
|
@ -91,7 +91,7 @@ _fork(void)
|
||||
|
||||
/* Fork a new process: */
|
||||
if (_kse_isthreaded() != 0) {
|
||||
_spinlock(__malloc_lock);
|
||||
_malloc_prefork();
|
||||
}
|
||||
if ((ret = __sys_fork()) == 0) {
|
||||
/* Child process */
|
||||
@ -107,8 +107,8 @@ _fork(void)
|
||||
}
|
||||
_thr_mutex_reinit(&_thr_atfork_mutex);
|
||||
} else {
|
||||
if ((_kse_isthreaded() != 0) && (__malloc_lock != NULL)) {
|
||||
_spinunlock(__malloc_lock);
|
||||
if (_kse_isthreaded() != 0) {
|
||||
_malloc_postfork();
|
||||
}
|
||||
errsave = errno;
|
||||
if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) {
|
||||
|
@ -94,12 +94,6 @@ _pthread_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* For a while, allow libpthread to work with a libc that doesn't
|
||||
* export the malloc lock.
|
||||
*/
|
||||
#pragma weak __malloc_lock
|
||||
|
||||
__weak_reference(_fork, fork);
|
||||
|
||||
pid_t
|
||||
@ -129,9 +123,9 @@ _fork(void)
|
||||
* child process because another thread in malloc code will
|
||||
* simply be kill by fork().
|
||||
*/
|
||||
if ((_thr_isthreaded() != 0) && (__malloc_lock != NULL)) {
|
||||
if (_thr_isthreaded() != 0) {
|
||||
unlock_malloc = 1;
|
||||
_spinlock(__malloc_lock);
|
||||
_malloc_prefork();
|
||||
} else {
|
||||
unlock_malloc = 0;
|
||||
}
|
||||
@ -160,7 +154,7 @@ _fork(void)
|
||||
_thr_umtx_init(&_thr_atfork_lock);
|
||||
_thr_setthreaded(0);
|
||||
|
||||
/* reinitialize libc spinlocks, this includes __malloc_lock. */
|
||||
/* reinitialize libc spinlocks. */
|
||||
_thr_spinlock_init();
|
||||
_mutex_fork(curthread);
|
||||
|
||||
@ -183,7 +177,7 @@ _fork(void)
|
||||
_thr_signal_unblock(curthread);
|
||||
|
||||
if (unlock_malloc)
|
||||
_spinunlock(__malloc_lock);
|
||||
_malloc_postfork();
|
||||
|
||||
/* Run down atfork parent handlers. */
|
||||
TAILQ_FOREACH(af, &_thr_atfork_list, qe) {
|
||||
|
@ -236,6 +236,22 @@ malloc(nbytes)
|
||||
return ((char *)(op + 1));
|
||||
}
|
||||
|
||||
void *
|
||||
calloc(size_t num, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (size != 0 && (num * size) / size != num) {
|
||||
/* size_t overflow. */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((ret = malloc(num * size)) != NULL)
|
||||
memset(ret, 0, num * size);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate more memory to the indicated bucket.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user