annotate lib/malloca.c @ 39235:6a04b04905e5

malloca, xmalloca: Make multithread-safe. Reported by Florian Weimer <fweimer@redhat.com>. Implements an idea by Ondřej Bílka <neleai@seznam.cz>. * lib/malloca.h (malloca): In the stack allocation case, return a pointer that is a multiple of 2 * sa_alignment_max. (sa_increment): Remove enum item. * lib/xmalloca.h (xmalloca): In the stack allocation case, return a pointer that is a multiple of 2 * sa_alignment_max. * lib/malloca.c (NO_SANITIZE_MEMORY): Remove macro. (MAGIC_NUMBER, MAGIC_SIZE, preliminary_header, HEADER_SIZE, header, HASH_TABLE_SIZE, mmalloca_results): Remove. (small_t): New type. (mmalloca, free): Rewritten. * lib/malloca.valgrind: Remove file. * modules/malloca (Files): Remove it. (Depends-on): Remove verify.
author Bruno Haible <bruno@clisp.org>
date Fri, 02 Feb 2018 19:32:02 +0100
parents 24e347e0e326
children fc9a55e09027
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Safe automatic memory allocation.
39199
24e347e0e326 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 38844
diff changeset
2 Copyright (C) 2003, 2006-2007, 2009-2018 Free Software Foundation, Inc.
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2003, 2018.
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 2, or (at your option)
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 any later version.
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
38844
a8586d5e30d2 all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 38683
diff changeset
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
34231
39cd7b3c3f75 * lib/malloca.c (_GL_USE_STDLIB_ALLOC, malloc): Likewise.
Paul Eggert <eggert@cs.ucla.edu>
parents: 33770
diff changeset
18 #define _GL_USE_STDLIB_ALLOC 1
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 #include <config.h>
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 /* Specification. */
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include "malloca.h"
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 /* The speed critical point in this file is freea() applied to an alloca()
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 result: it must be fast, to match the speed of alloca(). The speed of
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 mmalloca() and freea() in the other case are not critical, because they
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
27 are only invoked for big memory sizes.
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
28 Here we use a bit in the address as an indicator, an idea by Ondřej Bílka.
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
29 malloca() can return three types of pointers:
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
30 - Pointers ≡ 0 mod 2*sa_alignment_max come from stack allocation.
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
31 - Pointers ≡ sa_alignment_max mod 2*sa_alignment_max come from heap
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
32 allocation.
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
33 - NULL comes from a failed heap allocation. */
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
35 /* Type for holding very small pointer differences. */
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
36 typedef unsigned char small_t;
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 void *
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 mmalloca (size_t n)
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 {
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 #if HAVE_ALLOCA
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
42 /* Allocate one more word, used to determine the address to pass to freea(),
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
43 and room for the alignment ≡ sa_alignment_max mod 2*sa_alignment_max. */
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
44 size_t nplus = n + sizeof (small_t) + 2 * sa_alignment_max - 1;
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 if (nplus >= n)
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 {
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
48 char *mem = (char *) malloc (nplus);
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
50 if (mem != NULL)
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
51 {
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
52 char *p =
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
53 (char *)((((uintptr_t)mem + sizeof (small_t) + sa_alignment_max - 1)
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
54 & ~(uintptr_t)(2 * sa_alignment_max - 1))
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
55 + sa_alignment_max);
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
56 /* Here p >= mem + sizeof (small_t),
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
57 and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
58 hence p + n <= mem + nplus.
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
59 So, the memory range [p, p+n) lies in the allocated memory range
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
60 [mem, mem + nplus). */
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
61 ((small_t *) p)[-1] = p - mem;
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
62 /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */
32112
dc7644a1c024 Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 28623
diff changeset
63 return p;
dc7644a1c024 Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 28623
diff changeset
64 }
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 }
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 /* Out of memory. */
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 return NULL;
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 #else
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 # if !MALLOC_0_IS_NONNULL
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 if (n == 0)
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 n = 1;
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 # endif
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 return malloc (n);
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 #endif
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 }
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 #if HAVE_ALLOCA
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
78 void
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 freea (void *p)
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 {
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
81 /* Determine whether p was a non-NULL pointer returned by mmalloca(). */
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
82 if ((uintptr_t) p & sa_alignment_max)
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 {
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
84 void *mem = (char *) p - ((small_t *) p)[-1];
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
85 free (mem);
28623
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 }
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 }
227e2944ac3f Move to here from allocsa.c.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 #endif
39235
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
89
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
90 /*
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
91 * Hey Emacs!
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
92 * Local Variables:
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
93 * coding: utf-8
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
94 * End:
6a04b04905e5 malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents: 39199
diff changeset
95 */