Mercurial > gnulib
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 |
rev | line source |
---|---|
28623 | 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 | 4 |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2, or (at your option) | |
8 any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
38844 | 16 along with this program; if not, see <https://www.gnu.org/licenses/>. */ |
28623 | 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 | 19 #include <config.h> |
20 | |
21 /* Specification. */ | |
22 #include "malloca.h" | |
23 | |
24 /* The speed critical point in this file is freea() applied to an alloca() | |
25 result: it must be fast, to match the speed of alloca(). The speed of | |
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 | 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 | 37 |
38 void * | |
39 mmalloca (size_t n) | |
40 { | |
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 | 45 |
46 if (nplus >= n) | |
47 { | |
39235
6a04b04905e5
malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents:
39199
diff
changeset
|
48 char *mem = (char *) malloc (nplus); |
28623 | 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 | 65 } |
66 /* Out of memory. */ | |
67 return NULL; | |
68 #else | |
69 # if !MALLOC_0_IS_NONNULL | |
70 if (n == 0) | |
71 n = 1; | |
72 # endif | |
73 return malloc (n); | |
74 #endif | |
75 } | |
76 | |
77 #if HAVE_ALLOCA | |
39235
6a04b04905e5
malloca, xmalloca: Make multithread-safe.
Bruno Haible <bruno@clisp.org>
parents:
39199
diff
changeset
|
78 void |
28623 | 79 freea (void *p) |
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 | 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 | 86 } |
87 } | |
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 */ |