alloc.c revision 1.10.70.2 1 1.10.70.1 martin /* $NetBSD: alloc.c,v 1.10.70.2 2020/04/21 19:37:32 martin Exp $ */
2 1.2 tls
3 1.1 jtc /*
4 1.6 mycroft * Copyright (c) 2002 Marc Espie.
5 1.6 mycroft *
6 1.6 mycroft * Redistribution and use in source and binary forms, with or without
7 1.6 mycroft * modification, are permitted provided that the following conditions
8 1.6 mycroft * are met:
9 1.6 mycroft * 1. Redistributions of source code must retain the above copyright
10 1.6 mycroft * notice, this list of conditions and the following disclaimer.
11 1.6 mycroft * 2. Redistributions in binary form must reproduce the above copyright
12 1.6 mycroft * notice, this list of conditions and the following disclaimer in the
13 1.6 mycroft * documentation and/or other materials provided with the distribution.
14 1.6 mycroft *
15 1.6 mycroft * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
16 1.6 mycroft * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 1.6 mycroft * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 1.6 mycroft * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
19 1.6 mycroft * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 1.6 mycroft * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 1.6 mycroft * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.6 mycroft * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.6 mycroft * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.6 mycroft * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 1.6 mycroft * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.1 jtc */
27 1.1 jtc
28 1.4 hubertf /*
29 1.6 mycroft * area-based allocation built on malloc/free
30 1.4 hubertf */
31 1.10 lukem #include <sys/cdefs.h>
32 1.10.70.1 martin __RCSID("$NetBSD: alloc.c,v 1.10.70.2 2020/04/21 19:37:32 martin Exp $");
33 1.4 hubertf
34 1.6 mycroft #include "sh.h"
35 1.1 jtc
36 1.6 mycroft struct link {
37 1.6 mycroft struct link *prev;
38 1.6 mycroft struct link *next;
39 1.1 jtc };
40 1.1 jtc
41 1.1 jtc Area *
42 1.6 mycroft ainit(Area *ap)
43 1.1 jtc {
44 1.6 mycroft ap->freelist = NULL;
45 1.1 jtc return ap;
46 1.1 jtc }
47 1.1 jtc
48 1.1 jtc void
49 1.6 mycroft afreeall(Area *ap)
50 1.1 jtc {
51 1.6 mycroft struct link *l, *l2;
52 1.1 jtc
53 1.6 mycroft for (l = ap->freelist; l != NULL; l = l2) {
54 1.6 mycroft l2 = l->next;
55 1.6 mycroft free(l);
56 1.1 jtc }
57 1.6 mycroft ap->freelist = NULL;
58 1.1 jtc }
59 1.1 jtc
60 1.6 mycroft #define L2P(l) ( (void *)(((char *)(l)) + sizeof(struct link)) )
61 1.6 mycroft #define P2L(p) ( (struct link *)(((char *)(p)) - sizeof(struct link)) )
62 1.6 mycroft
63 1.7 christos /* coverity[+alloc] */
64 1.1 jtc void *
65 1.6 mycroft alloc(size_t size, Area *ap)
66 1.1 jtc {
67 1.6 mycroft struct link *l;
68 1.4 hubertf
69 1.6 mycroft l = malloc(sizeof(struct link) + size);
70 1.6 mycroft if (l == NULL)
71 1.6 mycroft internal_errorf(1, "unable to allocate memory");
72 1.6 mycroft l->next = ap->freelist;
73 1.6 mycroft l->prev = NULL;
74 1.6 mycroft if (ap->freelist)
75 1.6 mycroft ap->freelist->prev = l;
76 1.6 mycroft ap->freelist = l;
77 1.4 hubertf
78 1.6 mycroft return L2P(l);
79 1.1 jtc }
80 1.1 jtc
81 1.9 christos /* coverity[+alloc] */
82 1.9 christos /* coverity[+free : arg-0] */
83 1.1 jtc void *
84 1.6 mycroft aresize(void *ptr, size_t size, Area *ap)
85 1.1 jtc {
86 1.6 mycroft struct link *l, *l2, *lprev, *lnext;
87 1.4 hubertf
88 1.6 mycroft if (ptr == NULL)
89 1.6 mycroft return alloc(size, ap);
90 1.4 hubertf
91 1.6 mycroft l = P2L(ptr);
92 1.6 mycroft lprev = l->prev;
93 1.6 mycroft lnext = l->next;
94 1.6 mycroft
95 1.6 mycroft l2 = realloc(l, sizeof(struct link) + size);
96 1.6 mycroft if (l2 == NULL)
97 1.6 mycroft internal_errorf(1, "unable to allocate memory");
98 1.6 mycroft if (lprev)
99 1.6 mycroft lprev->next = l2;
100 1.6 mycroft else
101 1.6 mycroft ap->freelist = l2;
102 1.6 mycroft if (lnext)
103 1.6 mycroft lnext->prev = l2;
104 1.4 hubertf
105 1.6 mycroft return L2P(l2);
106 1.1 jtc }
107 1.1 jtc
108 1.8 christos /* coverity[+free : arg-0] */
109 1.1 jtc void
110 1.6 mycroft afree(void *ptr, Area *ap)
111 1.1 jtc {
112 1.6 mycroft struct link *l;
113 1.1 jtc
114 1.6 mycroft if (!ptr)
115 1.4 hubertf return;
116 1.4 hubertf
117 1.6 mycroft l = P2L(ptr);
118 1.4 hubertf
119 1.6 mycroft if (l->prev)
120 1.6 mycroft l->prev->next = l->next;
121 1.6 mycroft else
122 1.6 mycroft ap->freelist = l->next;
123 1.6 mycroft if (l->next)
124 1.6 mycroft l->next->prev = l->prev;
125 1.1 jtc
126 1.6 mycroft free(l);
127 1.1 jtc }
128