summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2012-02-29 20:56:37 (GMT)
committerJason Evans <je@fb.com>2012-02-29 20:56:37 (GMT)
commit7e15dab94d3f008b0a6c296ad7afec9ed47ff1ac (patch)
tree3d1f5fe55bf7e48a26c645f2dd141d27b89703d2
parent4bb09830133ffa8b27a95bc3727558007722c152 (diff)
downloadjemalloc-7e15dab94d3f008b0a6c296ad7afec9ed47ff1ac.zip
jemalloc-7e15dab94d3f008b0a6c296ad7afec9ed47ff1ac.tar.gz
jemalloc-7e15dab94d3f008b0a6c296ad7afec9ed47ff1ac.tar.bz2
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.
-rw-r--r--doc/jemalloc.xml.in38
-rw-r--r--include/jemalloc/internal/jemalloc_internal.h.in4
-rw-r--r--include/jemalloc/jemalloc.h.in1
-rw-r--r--src/jemalloc.c22
-rw-r--r--test/allocm.c91
5 files changed, 131 insertions, 25 deletions
diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in
index e7cc628..6aa412a 100644
--- a/doc/jemalloc.xml.in
+++ b/doc/jemalloc.xml.in
@@ -41,6 +41,7 @@
<refname>rallocm</refname>
<refname>sallocm</refname>
<refname>dallocm</refname>
+ <refname>nallocm</refname>
-->
<refpurpose>general purpose memory allocation functions</refpurpose>
</refnamediv>
@@ -154,6 +155,12 @@
<paramdef>void *<parameter>ptr</parameter></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
</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>
</funcsynopsis>
</refsynopsisdiv>
@@ -301,8 +308,9 @@ for (i = 0; i < nbins; i++) {
<para>The <function>allocm<parameter/></function>,
<function>rallocm<parameter/></function>,
- <function>sallocm<parameter/></function>, and
- <function>dallocm<parameter/></function> functions all have a
+ <function>sallocm<parameter/></function>,
+ <function>dallocm<parameter/></function>, and
+ <function>nallocm<parameter/></function> functions all have a
<parameter>flags</parameter> argument that can be used to specify
options. The functions only check the options that are contextually
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
<parameter>*ptr</parameter> to the base address of the allocation, and
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
allocation at <parameter>*ptr</parameter> to be at least
@@ -364,7 +374,8 @@ for (i = 0; i < nbins; i++) {
language="C"><parameter>size</parameter> +
<parameter>extra</parameter>)</code> bytes, though inability to allocate
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> &gt;
<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
memory referenced by <parameter>ptr</parameter> to be made available for
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>
</refsect1>
<refsect1 id="tuning">
@@ -1857,11 +1877,13 @@ malloc_conf = "xmalloc:true";]]></programlisting>
<title>Experimental API</title>
<para>The <function>allocm<parameter/></function>,
<function>rallocm<parameter/></function>,
- <function>sallocm<parameter/></function>, and
- <function>dallocm<parameter/></function> functions return
+ <function>sallocm<parameter/></function>,
+ <function>dallocm<parameter/></function>, and
+ <function>nallocm<parameter/></function> functions return
<constant>ALLOCM_SUCCESS</constant> on success; otherwise they return an
- error value. The <function>allocm<parameter/></function> and
- <function>rallocm<parameter/></function> functions will fail if:
+ error value. The <function>allocm<parameter/></function>,
+ <function>rallocm<parameter/></function>, and
+ <function>nallocm<parameter/></function> functions will fail if:
<variablelist>
<varlistentry>
<term><errorname>ALLOCM_ERR_OOM</errorname></term>
diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in
index c21c218..aa07346 100644
--- a/include/jemalloc/internal/jemalloc_internal.h.in
+++ b/include/jemalloc/internal/jemalloc_internal.h.in
@@ -548,10 +548,6 @@ sa2u(size_t size, size_t alignment, size_t *run_size_p)
* 96 | 1100000 | 32
* 144 | 10100000 | 32
* 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);
/*
diff --git a/include/jemalloc/jemalloc.h.in b/include/jemalloc/jemalloc.h.in
index 580a5ec..428c0d3 100644
--- a/include/jemalloc/jemalloc.h.in
+++ b/include/jemalloc/jemalloc.h.in
@@ -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)
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
};
diff --git a/src/jemalloc.c b/src/jemalloc.c
index ccc3a20..34fd1aa 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -1586,6 +1586,28 @@ JEMALLOC_P(dallocm)(void *ptr, int flags)
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.
*/
diff --git a/test/allocm.c b/test/allocm.c
index 59d0002..762e350 100644
--- a/test/allocm.c
+++ b/test/allocm.c
@@ -15,24 +15,33 @@ main(void)
{
int r;
void *p;
- size_t sz, alignment, total, tsz;
+ size_t nsz, rsz, sz, alignment, total;
unsigned i;
void *ps[NITER];
fprintf(stderr, "Test begin\n");
- sz = 0;
- r = JEMALLOC_P(allocm)(&p, &sz, 42, 0);
+ sz = 42;
+ 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) {
fprintf(stderr, "Unexpected allocm() error\n");
abort();
}
- if (sz < 42)
+ if (rsz < sz)
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)
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) {
fprintf(stderr, "Unexpected allocm() error\n");
abort();
@@ -40,11 +49,20 @@ main(void)
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
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) {
fprintf(stderr, "Unexpected allocm() error\n");
abort();
}
+ if (nsz != rsz)
+ fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS)
fprintf(stderr, "Unexpected dallocm() error\n");
@@ -55,12 +73,22 @@ main(void)
alignment = 0x80000000LU;
sz = 0x80000000LU;
#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) {
fprintf(stderr,
"Expected error for allocm(&p, %zu, 0x%x)\n",
sz, ALLOCM_ALIGN(alignment));
}
+ if (nsz != rsz)
+ fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
#if LG_SIZEOF_PTR == 3
alignment = 0x4000000000000000LLU;
@@ -69,7 +97,12 @@ main(void)
alignment = 0x40000000LU;
sz = 0x84000001LU;
#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) {
fprintf(stderr,
"Expected error for allocm(&p, %zu, 0x%x)\n",
@@ -82,12 +115,22 @@ main(void)
#else
sz = 0xfffffff0LU;
#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) {
fprintf(stderr,
"Expected error for allocm(&p, %zu, 0x%x)\n",
sz, ALLOCM_ALIGN(alignment));
}
+ if (nsz != rsz)
+ fprintf(stderr, "nallocm()/allocm() rsize mismatch\n");
for (i = 0; i < NITER; i++)
ps[i] = NULL;
@@ -101,21 +144,43 @@ main(void)
sz < 3 * alignment && sz < (1U << 31);
sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
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);
+ if (r != ALLOCM_SUCCESS) {
+ fprintf(stderr,
+ "nallocm() error for size %zu"
+ " (0x%zx): %d\n",
+ sz, sz, r);
+ exit(1);
+ }
+ rsz = 0;
+ r = JEMALLOC_P(allocm)(&ps[i], &rsz, sz,
ALLOCM_ALIGN(alignment) | ALLOCM_ZERO);
if (r != ALLOCM_SUCCESS) {
fprintf(stderr,
- "Error for size %zu (0x%zx): %d\n",
+ "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)) {
fprintf(stderr,
"%p inadequately aligned for"
" alignment: %zu\n", p, alignment);
}
- JEMALLOC_P(sallocm)(ps[i], &tsz, 0);
- total += tsz;
+ JEMALLOC_P(sallocm)(ps[i], &rsz, 0);
+ total += rsz;
if (total >= (MAXALIGN << 1))
break;
}