Add nallocm().
Add nallocm(), which computes the real allocation size that would result from the corresponding allocm() call. nallocm() is a functional superset of OS X's malloc_good_size(), in that it takes alignment constraints into account.
This commit is contained in:
parent
4bb0983013
commit
7e15dab94d
@ -41,6 +41,7 @@
|
|||||||
<refname>rallocm</refname>
|
<refname>rallocm</refname>
|
||||||
<refname>sallocm</refname>
|
<refname>sallocm</refname>
|
||||||
<refname>dallocm</refname>
|
<refname>dallocm</refname>
|
||||||
|
<refname>nallocm</refname>
|
||||||
-->
|
-->
|
||||||
<refpurpose>general purpose memory allocation functions</refpurpose>
|
<refpurpose>general purpose memory allocation functions</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
@ -154,6 +155,12 @@
|
|||||||
<paramdef>void *<parameter>ptr</parameter></paramdef>
|
<paramdef>void *<parameter>ptr</parameter></paramdef>
|
||||||
<paramdef>int <parameter>flags</parameter></paramdef>
|
<paramdef>int <parameter>flags</parameter></paramdef>
|
||||||
</funcprototype>
|
</funcprototype>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>nallocm</function></funcdef>
|
||||||
|
<paramdef>size_t *<parameter>rsize</parameter></paramdef>
|
||||||
|
<paramdef>size_t <parameter>size</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>flags</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
</funcsynopsis>
|
</funcsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
@ -301,8 +308,9 @@ for (i = 0; i < nbins; i++) {
|
|||||||
|
|
||||||
<para>The <function>allocm<parameter/></function>,
|
<para>The <function>allocm<parameter/></function>,
|
||||||
<function>rallocm<parameter/></function>,
|
<function>rallocm<parameter/></function>,
|
||||||
<function>sallocm<parameter/></function>, and
|
<function>sallocm<parameter/></function>,
|
||||||
<function>dallocm<parameter/></function> functions all have a
|
<function>dallocm<parameter/></function>, and
|
||||||
|
<function>nallocm<parameter/></function> functions all have a
|
||||||
<parameter>flags</parameter> argument that can be used to specify
|
<parameter>flags</parameter> argument that can be used to specify
|
||||||
options. The functions only check the options that are contextually
|
options. The functions only check the options that are contextually
|
||||||
relevant. Use bitwise or (<code language="C">|</code>) operations to
|
relevant. Use bitwise or (<code language="C">|</code>) operations to
|
||||||
@ -351,7 +359,9 @@ for (i = 0; i < nbins; i++) {
|
|||||||
least <parameter>size</parameter> bytes of memory, sets
|
least <parameter>size</parameter> bytes of memory, sets
|
||||||
<parameter>*ptr</parameter> to the base address of the allocation, and
|
<parameter>*ptr</parameter> to the base address of the allocation, and
|
||||||
sets <parameter>*rsize</parameter> to the real size of the allocation if
|
sets <parameter>*rsize</parameter> to the real size of the allocation if
|
||||||
<parameter>rsize</parameter> is not <constant>NULL</constant>.</para>
|
<parameter>rsize</parameter> is not <constant>NULL</constant>. Behavior
|
||||||
|
is undefined if <parameter>size</parameter> is
|
||||||
|
<constant>0<constant>.</para>
|
||||||
|
|
||||||
<para>The <function>rallocm<parameter/></function> function resizes the
|
<para>The <function>rallocm<parameter/></function> function resizes the
|
||||||
allocation at <parameter>*ptr</parameter> to be at least
|
allocation at <parameter>*ptr</parameter> to be at least
|
||||||
@ -364,7 +374,8 @@ for (i = 0; i < nbins; i++) {
|
|||||||
language="C"><parameter>size</parameter> +
|
language="C"><parameter>size</parameter> +
|
||||||
<parameter>extra</parameter>)</code> bytes, though inability to allocate
|
<parameter>extra</parameter>)</code> bytes, though inability to allocate
|
||||||
the extra byte(s) will not by itself result in failure. Behavior is
|
the extra byte(s) will not by itself result in failure. Behavior is
|
||||||
undefined if <code language="C">(<parameter>size</parameter> +
|
undefined if <parameter>size</parameter> is <constant>0<constant>, or if
|
||||||
|
<code language="C">(<parameter>size</parameter> +
|
||||||
<parameter>extra</parameter> >
|
<parameter>extra</parameter> >
|
||||||
<constant>SIZE_T_MAX</constant>)</code>.</para>
|
<constant>SIZE_T_MAX</constant>)</code>.</para>
|
||||||
|
|
||||||
@ -374,6 +385,15 @@ for (i = 0; i < nbins; i++) {
|
|||||||
<para>The <function>dallocm<parameter/></function> function causes the
|
<para>The <function>dallocm<parameter/></function> function causes the
|
||||||
memory referenced by <parameter>ptr</parameter> to be made available for
|
memory referenced by <parameter>ptr</parameter> to be made available for
|
||||||
future allocations.</para>
|
future allocations.</para>
|
||||||
|
|
||||||
|
<para>The <function>nallocm<parameter/></function> function allocates no
|
||||||
|
memory, but it performs the same size computation as the
|
||||||
|
<function>allocm<parameter/></function> function, and if
|
||||||
|
<parameter>rsize</parameter> is not <constant>NULL</constant> it sets
|
||||||
|
<parameter>*rsize</parameter> to the real size of the allocation that
|
||||||
|
would result from the equivalent <function>allocm<parameter/></function>
|
||||||
|
function call. Behavior is undefined if
|
||||||
|
<parameter>size</parameter> is <constant>0<constant>.</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
<refsect1 id="tuning">
|
<refsect1 id="tuning">
|
||||||
@ -1857,11 +1877,13 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
|||||||
<title>Experimental API</title>
|
<title>Experimental API</title>
|
||||||
<para>The <function>allocm<parameter/></function>,
|
<para>The <function>allocm<parameter/></function>,
|
||||||
<function>rallocm<parameter/></function>,
|
<function>rallocm<parameter/></function>,
|
||||||
<function>sallocm<parameter/></function>, and
|
<function>sallocm<parameter/></function>,
|
||||||
<function>dallocm<parameter/></function> functions return
|
<function>dallocm<parameter/></function>, and
|
||||||
|
<function>nallocm<parameter/></function> functions return
|
||||||
<constant>ALLOCM_SUCCESS</constant> on success; otherwise they return an
|
<constant>ALLOCM_SUCCESS</constant> on success; otherwise they return an
|
||||||
error value. The <function>allocm<parameter/></function> and
|
error value. The <function>allocm<parameter/></function>,
|
||||||
<function>rallocm<parameter/></function> functions will fail if:
|
<function>rallocm<parameter/></function>, and
|
||||||
|
<function>nallocm<parameter/></function> functions will fail if:
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><errorname>ALLOCM_ERR_OOM</errorname></term>
|
<term><errorname>ALLOCM_ERR_OOM</errorname></term>
|
||||||
|
@ -548,10 +548,6 @@ sa2u(size_t size, size_t alignment, size_t *run_size_p)
|
|||||||
* 96 | 1100000 | 32
|
* 96 | 1100000 | 32
|
||||||
* 144 | 10100000 | 32
|
* 144 | 10100000 | 32
|
||||||
* 192 | 11000000 | 64
|
* 192 | 11000000 | 64
|
||||||
*
|
|
||||||
* Depending on runtime settings, it is possible that arena_malloc()
|
|
||||||
* will further round up to a power of two, but that never causes
|
|
||||||
* correctness issues.
|
|
||||||
*/
|
*/
|
||||||
usize = (size + (alignment - 1)) & (-alignment);
|
usize = (size + (alignment - 1)) & (-alignment);
|
||||||
/*
|
/*
|
||||||
|
@ -59,6 +59,7 @@ int JEMALLOC_P(rallocm)(void **ptr, size_t *rsize, size_t size,
|
|||||||
int JEMALLOC_P(sallocm)(const void *ptr, size_t *rsize, int flags)
|
int JEMALLOC_P(sallocm)(const void *ptr, size_t *rsize, int flags)
|
||||||
JEMALLOC_ATTR(nonnull(1));
|
JEMALLOC_ATTR(nonnull(1));
|
||||||
int JEMALLOC_P(dallocm)(void *ptr, int flags) JEMALLOC_ATTR(nonnull(1));
|
int JEMALLOC_P(dallocm)(void *ptr, int flags) JEMALLOC_ATTR(nonnull(1));
|
||||||
|
int JEMALLOC_P(nallocm)(size_t *rsize, size_t size, int flags);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
|
@ -1586,6 +1586,28 @@ JEMALLOC_P(dallocm)(void *ptr, int flags)
|
|||||||
return (ALLOCM_SUCCESS);
|
return (ALLOCM_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ATTR(visibility("default"))
|
||||||
|
int
|
||||||
|
JEMALLOC_P(nallocm)(size_t *rsize, size_t size, int flags)
|
||||||
|
{
|
||||||
|
size_t usize;
|
||||||
|
size_t alignment = (ZU(1) << (flags & ALLOCM_LG_ALIGN_MASK)
|
||||||
|
& (SIZE_T_MAX-1));
|
||||||
|
|
||||||
|
assert(size != 0);
|
||||||
|
|
||||||
|
if (malloc_init())
|
||||||
|
return (ALLOCM_ERR_OOM);
|
||||||
|
|
||||||
|
usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment, NULL);
|
||||||
|
if (usize == 0)
|
||||||
|
return (ALLOCM_ERR_OOM);
|
||||||
|
|
||||||
|
if (rsize != NULL)
|
||||||
|
*rsize = usize;
|
||||||
|
return (ALLOCM_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End non-standard functions.
|
* End non-standard functions.
|
||||||
*/
|
*/
|
||||||
|
@ -15,24 +15,33 @@ main(void)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
void *p;
|
void *p;
|
||||||
size_t sz, alignment, total, tsz;
|
size_t nsz, rsz, sz, alignment, total;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
void *ps[NITER];
|
void *ps[NITER];
|
||||||
|
|
||||||
fprintf(stderr, "Test begin\n");
|
fprintf(stderr, "Test begin\n");
|
||||||
|
|
||||||
sz = 0;
|
sz = 42;
|
||||||
r = JEMALLOC_P(allocm)(&p, &sz, 42, 0);
|
nsz = 0;
|
||||||
|
r = JEMALLOC_P(nallocm)(&nsz, sz, 0);
|
||||||
|
if (r != ALLOCM_SUCCESS) {
|
||||||
|
fprintf(stderr, "Unexpected nallocm() error\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
rsz = 0;
|
||||||
|
r = JEMALLOC_P(allocm)(&p, &rsz, sz, 0);
|
||||||
if (r != ALLOCM_SUCCESS) {
|
if (r != ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr, "Unexpected allocm() error\n");
|
fprintf(stderr, "Unexpected allocm() error\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if (sz < 42)
|
if (rsz < sz)
|
||||||
fprintf(stderr, "Real size smaller than expected\n");
|
fprintf(stderr, "Real size smaller than expected\n");
|
||||||
|
if (nsz != rsz)
|
||||||
|
fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
|
||||||
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
|
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected dallocm() error\n");
|
fprintf(stderr, "Unexpected dallocm() error\n");
|
||||||
|
|
||||||
r = JEMALLOC_P(allocm)(&p, NULL, 42, 0);
|
r = JEMALLOC_P(allocm)(&p, NULL, sz, 0);
|
||||||
if (r != ALLOCM_SUCCESS) {
|
if (r != ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr, "Unexpected allocm() error\n");
|
fprintf(stderr, "Unexpected allocm() error\n");
|
||||||
abort();
|
abort();
|
||||||
@ -40,11 +49,20 @@ main(void)
|
|||||||
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
|
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected dallocm() error\n");
|
fprintf(stderr, "Unexpected dallocm() error\n");
|
||||||
|
|
||||||
r = JEMALLOC_P(allocm)(&p, NULL, 42, ALLOCM_ZERO);
|
nsz = 0;
|
||||||
|
r = JEMALLOC_P(nallocm)(&nsz, sz, ALLOCM_ZERO);
|
||||||
|
if (r != ALLOCM_SUCCESS) {
|
||||||
|
fprintf(stderr, "Unexpected nallocm() error\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
rsz = 0;
|
||||||
|
r = JEMALLOC_P(allocm)(&p, &rsz, sz, ALLOCM_ZERO);
|
||||||
if (r != ALLOCM_SUCCESS) {
|
if (r != ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr, "Unexpected allocm() error\n");
|
fprintf(stderr, "Unexpected allocm() error\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
if (nsz != rsz)
|
||||||
|
fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
|
||||||
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
|
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected dallocm() error\n");
|
fprintf(stderr, "Unexpected dallocm() error\n");
|
||||||
|
|
||||||
@ -55,12 +73,22 @@ main(void)
|
|||||||
alignment = 0x80000000LU;
|
alignment = 0x80000000LU;
|
||||||
sz = 0x80000000LU;
|
sz = 0x80000000LU;
|
||||||
#endif
|
#endif
|
||||||
r = JEMALLOC_P(allocm)(&p, NULL, sz, ALLOCM_ALIGN(alignment));
|
nsz = 0;
|
||||||
|
r = JEMALLOC_P(nallocm)(&nsz, sz, ALLOCM_ALIGN(alignment));
|
||||||
|
if (r == ALLOCM_SUCCESS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Expected error for nallocm(&nsz, %zu, 0x%x)\n",
|
||||||
|
sz, ALLOCM_ALIGN(alignment));
|
||||||
|
}
|
||||||
|
rsz = 0;
|
||||||
|
r = JEMALLOC_P(allocm)(&p, &rsz, sz, ALLOCM_ALIGN(alignment));
|
||||||
if (r == ALLOCM_SUCCESS) {
|
if (r == ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Expected error for allocm(&p, %zu, 0x%x)\n",
|
"Expected error for allocm(&p, %zu, 0x%x)\n",
|
||||||
sz, ALLOCM_ALIGN(alignment));
|
sz, ALLOCM_ALIGN(alignment));
|
||||||
}
|
}
|
||||||
|
if (nsz != rsz)
|
||||||
|
fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
|
||||||
|
|
||||||
#if LG_SIZEOF_PTR == 3
|
#if LG_SIZEOF_PTR == 3
|
||||||
alignment = 0x4000000000000000LLU;
|
alignment = 0x4000000000000000LLU;
|
||||||
@ -69,7 +97,12 @@ main(void)
|
|||||||
alignment = 0x40000000LU;
|
alignment = 0x40000000LU;
|
||||||
sz = 0x84000001LU;
|
sz = 0x84000001LU;
|
||||||
#endif
|
#endif
|
||||||
r = JEMALLOC_P(allocm)(&p, NULL, sz, ALLOCM_ALIGN(alignment));
|
nsz = 0;
|
||||||
|
r = JEMALLOC_P(nallocm)(&nsz, sz, ALLOCM_ALIGN(alignment));
|
||||||
|
if (r != ALLOCM_SUCCESS)
|
||||||
|
fprintf(stderr, "Unexpected nallocm() error\n");
|
||||||
|
rsz = 0;
|
||||||
|
r = JEMALLOC_P(allocm)(&p, &rsz, sz, ALLOCM_ALIGN(alignment));
|
||||||
if (r == ALLOCM_SUCCESS) {
|
if (r == ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Expected error for allocm(&p, %zu, 0x%x)\n",
|
"Expected error for allocm(&p, %zu, 0x%x)\n",
|
||||||
@ -82,12 +115,22 @@ main(void)
|
|||||||
#else
|
#else
|
||||||
sz = 0xfffffff0LU;
|
sz = 0xfffffff0LU;
|
||||||
#endif
|
#endif
|
||||||
r = JEMALLOC_P(allocm)(&p, NULL, sz, ALLOCM_ALIGN(alignment));
|
nsz = 0;
|
||||||
|
r = JEMALLOC_P(nallocm)(&nsz, sz, ALLOCM_ALIGN(alignment));
|
||||||
|
if (r == ALLOCM_SUCCESS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Expected error for nallocm(&nsz, %zu, 0x%x)\n",
|
||||||
|
sz, ALLOCM_ALIGN(alignment));
|
||||||
|
}
|
||||||
|
rsz = 0;
|
||||||
|
r = JEMALLOC_P(allocm)(&p, &rsz, sz, ALLOCM_ALIGN(alignment));
|
||||||
if (r == ALLOCM_SUCCESS) {
|
if (r == ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Expected error for allocm(&p, %zu, 0x%x)\n",
|
"Expected error for allocm(&p, %zu, 0x%x)\n",
|
||||||
sz, ALLOCM_ALIGN(alignment));
|
sz, ALLOCM_ALIGN(alignment));
|
||||||
}
|
}
|
||||||
|
if (nsz != rsz)
|
||||||
|
fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
|
||||||
|
|
||||||
for (i = 0; i < NITER; i++)
|
for (i = 0; i < NITER; i++)
|
||||||
ps[i] = NULL;
|
ps[i] = NULL;
|
||||||
@ -101,21 +144,43 @@ main(void)
|
|||||||
sz < 3 * alignment && sz < (1U << 31);
|
sz < 3 * alignment && sz < (1U << 31);
|
||||||
sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
|
sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
|
||||||
for (i = 0; i < NITER; i++) {
|
for (i = 0; i < NITER; i++) {
|
||||||
r = JEMALLOC_P(allocm)(&ps[i], NULL, sz,
|
nsz = 0;
|
||||||
|
r = JEMALLOC_P(nallocm)(&nsz, sz,
|
||||||
ALLOCM_ALIGN(alignment) | ALLOCM_ZERO);
|
ALLOCM_ALIGN(alignment) | ALLOCM_ZERO);
|
||||||
if (r != ALLOCM_SUCCESS) {
|
if (r != ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error for size %zu (0x%zx): %d\n",
|
"nallocm() error for size %zu"
|
||||||
|
" (0x%zx): %d\n",
|
||||||
sz, sz, r);
|
sz, sz, r);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
rsz = 0;
|
||||||
|
r = JEMALLOC_P(allocm)(&ps[i], &rsz, sz,
|
||||||
|
ALLOCM_ALIGN(alignment) | ALLOCM_ZERO);
|
||||||
|
if (r != ALLOCM_SUCCESS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"allocm() error for size %zu"
|
||||||
|
" (0x%zx): %d\n",
|
||||||
|
sz, sz, r);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (rsz < sz) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Real size smaller than"
|
||||||
|
" expected\n");
|
||||||
|
}
|
||||||
|
if (nsz != rsz) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"nallocm()/allocm() rsize"
|
||||||
|
" mismatch\n");
|
||||||
|
}
|
||||||
if ((uintptr_t)p & (alignment-1)) {
|
if ((uintptr_t)p & (alignment-1)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%p inadequately aligned for"
|
"%p inadequately aligned for"
|
||||||
" alignment: %zu\n", p, alignment);
|
" alignment: %zu\n", p, alignment);
|
||||||
}
|
}
|
||||||
JEMALLOC_P(sallocm)(ps[i], &tsz, 0);
|
JEMALLOC_P(sallocm)(ps[i], &rsz, 0);
|
||||||
total += tsz;
|
total += rsz;
|
||||||
if (total >= (MAXALIGN << 1))
|
if (total >= (MAXALIGN << 1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user