lintian doesn't like orphan packages with uploaders...
[debian/amanda] / ndmp-src / ndml_fhh.c
1 /*
2  * Copyright (c) 1998,1999,2000
3  *      Traakan, Inc., Los Altos, CA
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *      The heap is managed like this:
35  *
36  *                      +----------------+
37  *      table ------>   |     entry      |  <----- heap_top
38  *                      |    -------     |
39  *                      |     entry      |
40  *                      |    -------     |
41  *                      |     entry      |
42  *                      |    -------     |
43  *      allo_ent --->   |     .....      |
44  *              |       |                |
45  *              V       |                |
46  *                      ~                ~
47  *                      ~                ~
48  *              ^       |                |
49  *              |       |                |
50  *      allo_item--->   |     ....       |
51  *                      |    -------     |
52  *                      |     item       |
53  *                      |    -------     |
54  *                      |     item       |
55  *                      |    -------     |
56  *                      |     item       |
57  *                      +----------------+  <----- heap_end
58  *
59  * n_entry = allo_ent - table;
60  */
61
62
63 #include "ndmlib.h"
64
65
66
67
68 int
69 ndmfhh_initialize (struct ndmfhheap *fhh)
70 {
71         NDMOS_MACRO_ZEROFILL (fhh);
72
73         return NDMFHH_RET_OK;
74 }
75
76 int
77 ndmfhh_commission (struct ndmfhheap *fhh, void *heap, unsigned size)
78 {
79         fhh->heap_base = heap;
80         fhh->heap_size = size;
81         fhh->heap_end = (char*)heap + size;
82
83         /* Align everything */
84         fhh->heap_top = (void*) (((long)heap + (NDMOS_CONST_ALIGN-1))
85                                                 &~ (NDMOS_CONST_ALIGN-1));
86         fhh->heap_bot = (void*)
87                 ((long)((char*)heap+size) &~ (NDMOS_CONST_ALIGN-1));
88
89         ndmfhh_reset (fhh);
90
91         return NDMFHH_RET_OK;
92 }
93
94 #define SLOP    32
95
96 int
97 ndmfhh_prepare (struct ndmfhheap *fhh,
98   int fhtype, int entry_size,
99   unsigned n_item, unsigned total_size_of_items)
100 {
101         void *                  pe;
102         void *                  pi;
103         unsigned                items_need;
104
105         if (fhh->heap_base == 0)
106                 return NDMFHH_RET_NO_HEAP;
107
108         if (fhh->allo_entry == fhh->heap_top) {
109                 fhh->fhtype = fhtype;
110                 fhh->entry_size = entry_size;
111         } else {
112                 if (fhh->fhtype != fhtype)
113                         return NDMFHH_RET_TYPE_CHANGE;
114
115                 if (fhh->entry_size != entry_size)
116                         return NDMFHH_RET_ENTRY_SIZE_MISMATCH;
117         }
118
119         items_need = total_size_of_items + n_item * NDMOS_CONST_ALIGN + SLOP;
120
121         pe = (char*)fhh->allo_entry + fhh->entry_size;
122         pi = (char*)fhh->allo_item - items_need;
123
124         if (pe >= pi)
125                 return NDMFHH_RET_OVERFLOW;
126
127         /* it'll fit! */
128         return NDMFHH_RET_OK;
129 }
130
131 void *
132 ndmfhh_add_entry (struct ndmfhheap *fhh)
133 {
134         void *          p;
135
136         p = fhh->allo_entry;
137         if ((char*)fhh->allo_entry + fhh->entry_size < (char*)fhh->allo_item) {
138                 fhh->allo_entry = (char *)p + fhh->entry_size;
139                 return p;
140         } else {
141                 return 0;
142         }
143
144 }
145
146 void *
147 ndmfhh_add_item (struct ndmfhheap *fhh, unsigned size)
148 {
149         void *          p;
150
151         size += (NDMOS_CONST_ALIGN-1);
152         size &= ~(NDMOS_CONST_ALIGN-1);
153
154         p = (char*)fhh->allo_item - size;
155         if (p > fhh->allo_entry) {
156                 fhh->allo_item = p;
157                 return p;
158         } else {
159                 return 0;
160         }
161 }
162
163 void *
164 ndmfhh_save_item (struct ndmfhheap *fhh, void *item, unsigned size)
165 {
166         void *          p;
167
168         p = ndmfhh_add_item (fhh, size);
169         if (p) {
170                 NDMOS_API_BCOPY (item, p, size);
171         }
172         return p;
173 }
174
175 int
176 ndmfhh_reset (struct ndmfhheap *fhh)
177 {
178         fhh->allo_entry = fhh->heap_top;
179         fhh->allo_item = fhh->heap_bot;
180
181         return NDMFHH_RET_OK;
182 }
183
184 int
185 ndmfhh_get_table (struct ndmfhheap *fhh,
186   int *fhtype_p, void **table_p, unsigned *n_entry_p)
187 {
188         unsigned                n;
189
190         *fhtype_p = fhh->fhtype;
191         *table_p = fhh->heap_top;
192         n = (char*)fhh->allo_entry - (char*)fhh->heap_top;
193         if (n > 0)
194                 n /= fhh->entry_size;
195
196         *n_entry_p = n;
197
198         return NDMFHH_RET_OK;
199 }
200