Mercurial > molko
annotate libcore/core/alloc.c @ 188:cbce9143bf87
core: allow realloc of 0 for duktape
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 06 Nov 2020 14:50:31 +0100 |
parents | f6497ec74b49 |
children | befa2e855d3b |
rev | line source |
---|---|
182
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * alloc.h -- custom allocators |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #include <assert.h> |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #include <errno.h> |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 #include <stdlib.h> |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 #include <string.h> |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 #include "alloc.h" |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 #include "error.h" |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 #include "panic.h" |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 static void * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 panic_alloc(size_t size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 { |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
31 void *mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 if (!(mem = malloc(size))) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 panicf("%s", strerror(errno)); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 return mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 } |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 static void * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 panic_realloc(void *ptr, size_t size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 { |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
42 void *mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 |
188
cbce9143bf87
core: allow realloc of 0 for duktape
David Demelier <markand@malikania.fr>
parents:
182
diff
changeset
|
44 if (!(mem = realloc(ptr, size)) && size != 0) |
182
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 panicf("%s", strerror(errno)); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 return mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 } |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
50 struct allocator allocator = { |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 .alloc = panic_alloc, |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
52 .realloc = panic_realloc, |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 .free = free |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 }; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 void * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 alloc(size_t n, size_t size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 { |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 assert(n != 0); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 assert(size != 0); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
61 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 size_t total = n * size; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 if (total / n != size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 return errorf("%s", strerror(ENOMEM)), NULL; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
66 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 return allocator.alloc(total); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 } |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 void * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 alloc_zero(size_t n, size_t size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 { |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 assert(n != 0); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 assert(size != 0); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 void *mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 size_t total = n * size; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 if (total / n != size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 return errorf("%s", strerror(ENOMEM)), NULL; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 if ((mem = allocator.alloc(total))) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 memset(mem, 0, total); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 return mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 } |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 void * |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 alloc_dup(const void *ptr, size_t size) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 { |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 assert(ptr); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 assert(size != 0); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 void *mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 if ((mem = allocator.alloc(size))) |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 memcpy(mem, ptr, size); |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 return mem; |
f6497ec74b49
core: add alloc module, closes #2512
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 } |