Line | Count | Source |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /*------------------------------------------------------------------------- |
14 | | * |
15 | | * Created: H5HLint.c |
16 | | * |
17 | | * Purpose: Local heap internal routines. |
18 | | * |
19 | | *------------------------------------------------------------------------- |
20 | | */ |
21 | | |
22 | | /****************/ |
23 | | /* Module Setup */ |
24 | | /****************/ |
25 | | |
26 | | #include "H5HLmodule.h" /* This source code file is part of the H5HL module */ |
27 | | |
28 | | /***********/ |
29 | | /* Headers */ |
30 | | /***********/ |
31 | | #include "H5private.h" /* Generic Functions */ |
32 | | #include "H5Eprivate.h" /* Error handling */ |
33 | | #include "H5FLprivate.h" /* Free lists */ |
34 | | #include "H5HLpkg.h" /* Local Heaps */ |
35 | | |
36 | | /****************/ |
37 | | /* Local Macros */ |
38 | | /****************/ |
39 | | |
40 | | /******************/ |
41 | | /* Local Typedefs */ |
42 | | /******************/ |
43 | | |
44 | | /********************/ |
45 | | /* Package Typedefs */ |
46 | | /********************/ |
47 | | |
48 | | /********************/ |
49 | | /* Local Prototypes */ |
50 | | /********************/ |
51 | | |
52 | | /*********************/ |
53 | | /* Package Variables */ |
54 | | /*********************/ |
55 | | |
56 | | /*****************************/ |
57 | | /* Library Private Variables */ |
58 | | /*****************************/ |
59 | | |
60 | | /*******************/ |
61 | | /* Local Variables */ |
62 | | /*******************/ |
63 | | |
64 | | /* Declare a free list to manage the H5HL_t struct */ |
65 | | H5FL_DEFINE_STATIC(H5HL_t); |
66 | | |
67 | | /*------------------------------------------------------------------------- |
68 | | * Function: H5HL__new |
69 | | * |
70 | | * Purpose: Create a new local heap object |
71 | | * |
72 | | * Return: Success: non-NULL pointer to new local heap |
73 | | * Failure: NULL |
74 | | * |
75 | | *------------------------------------------------------------------------- |
76 | | */ |
77 | | H5HL_t * |
78 | | H5HL__new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size) |
79 | 420 | { |
80 | 420 | H5HL_t *heap = NULL; /* New local heap */ |
81 | 420 | H5HL_t *ret_value = NULL; |
82 | | |
83 | 420 | FUNC_ENTER_PACKAGE |
84 | | |
85 | | /* check arguments */ |
86 | 420 | assert(sizeof_size > 0); |
87 | 420 | assert(sizeof_addr > 0); |
88 | 420 | assert(prfx_size > 0); |
89 | | |
90 | | /* Allocate new local heap structure */ |
91 | 420 | if (NULL == (heap = H5FL_CALLOC(H5HL_t))) |
92 | 0 | HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed"); |
93 | | |
94 | | /* Initialize non-zero fields */ |
95 | 420 | heap->sizeof_size = sizeof_size; |
96 | 420 | heap->sizeof_addr = sizeof_addr; |
97 | 420 | heap->prfx_size = prfx_size; |
98 | | |
99 | | /* Set the return value */ |
100 | 420 | ret_value = heap; |
101 | | |
102 | 420 | done: |
103 | 420 | if (!ret_value && heap != NULL) |
104 | 0 | if (NULL == (heap = H5FL_FREE(H5HL_t, heap))) |
105 | 0 | HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "can't free heap memory"); |
106 | | |
107 | 420 | FUNC_LEAVE_NOAPI(ret_value) |
108 | 420 | } /* end H5HL__new() */ |
109 | | |
110 | | /*------------------------------------------------------------------------- |
111 | | * Function: H5HL__inc_rc |
112 | | * |
113 | | * Purpose: Increment ref. count on heap |
114 | | * |
115 | | * Return: SUCCEED (Can't fail) |
116 | | * |
117 | | *------------------------------------------------------------------------- |
118 | | */ |
119 | | herr_t |
120 | | H5HL__inc_rc(H5HL_t *heap) |
121 | 561 | { |
122 | 561 | FUNC_ENTER_PACKAGE_NOERR |
123 | | |
124 | | /* check arguments */ |
125 | 561 | assert(heap); |
126 | | |
127 | | /* Increment heap's ref. count */ |
128 | 561 | heap->rc++; |
129 | | |
130 | 561 | FUNC_LEAVE_NOAPI(SUCCEED) |
131 | 561 | } /* end H5HL__inc_rc() */ |
132 | | |
133 | | /*------------------------------------------------------------------------- |
134 | | * Function: H5HL__dec_rc |
135 | | * |
136 | | * Purpose: Decrement ref. count on heap |
137 | | * |
138 | | * Return: SUCCEED/FAIL |
139 | | * |
140 | | *------------------------------------------------------------------------- |
141 | | */ |
142 | | herr_t |
143 | | H5HL__dec_rc(H5HL_t *heap) |
144 | 561 | { |
145 | 561 | herr_t ret_value = SUCCEED; |
146 | | |
147 | 561 | FUNC_ENTER_PACKAGE |
148 | | |
149 | | /* check arguments */ |
150 | 561 | assert(heap); |
151 | | |
152 | | /* Decrement heap's ref. count */ |
153 | 561 | heap->rc--; |
154 | | |
155 | | /* Check if we should destroy the heap */ |
156 | 561 | if (heap->rc == 0 && FAIL == H5HL__dest(heap)) |
157 | 0 | HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap"); |
158 | | |
159 | 561 | done: |
160 | 561 | FUNC_LEAVE_NOAPI(ret_value) |
161 | 561 | } /* end H5HL__dec_rc() */ |
162 | | |
163 | | /*------------------------------------------------------------------------- |
164 | | * Function: H5HL__dest |
165 | | * |
166 | | * Purpose: Destroys a heap in memory. |
167 | | * |
168 | | * Return: SUCCEED/FAIL |
169 | | * |
170 | | *------------------------------------------------------------------------- |
171 | | */ |
172 | | herr_t |
173 | | H5HL__dest(H5HL_t *heap) |
174 | 420 | { |
175 | 420 | herr_t ret_value = SUCCEED; |
176 | | |
177 | 420 | FUNC_ENTER_PACKAGE |
178 | | |
179 | | /* check arguments */ |
180 | 420 | assert(heap); |
181 | | |
182 | | /* Verify that node is unused */ |
183 | 420 | assert(heap->prots == 0); |
184 | 420 | assert(heap->rc == 0); |
185 | 420 | assert(heap->prfx == NULL); |
186 | 420 | assert(heap->dblk == NULL); |
187 | | |
188 | | /* Use DONE errors here to try to free as much as possible */ |
189 | 420 | if (heap->dblk_image) |
190 | 420 | if (NULL != (heap->dblk_image = H5FL_BLK_FREE(lheap_chunk, heap->dblk_image))) |
191 | 0 | HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap data block image"); |
192 | 836 | while (heap->freelist) { |
193 | 416 | H5HL_free_t *fl; |
194 | | |
195 | 416 | fl = heap->freelist; |
196 | 416 | heap->freelist = fl->next; |
197 | 416 | if (NULL != (fl = H5FL_FREE(H5HL_free_t, fl))) |
198 | 0 | HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap free list"); |
199 | 416 | } |
200 | | |
201 | 420 | if (NULL != (heap = H5FL_FREE(H5HL_t, heap))) |
202 | 0 | HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap"); |
203 | | |
204 | 420 | FUNC_LEAVE_NOAPI(ret_value) |
205 | 420 | } /* end H5HL__dest() */ |