1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #ifndef _omi_batch_h
26 #define _omi_batch_h
27
28 #include "config.h"
29 #include <string.h>
30 #include <common.h>
31
32 BEGIN_EXTERNC
33
34 /*
35 **==============================================================================
36 **
37 ** Batch
38 **
39 ** This type defines a fast O(1) batch allocator. Chunks are allocated
40 ** incrementally and then released as a batch. Clients of this interface
41 ** allocate and deallocate memory as shown here.
42 **
43 mike 1.1 ** Batch batch;
44 ** char* ptr;
45 **
46 ** SystemAlloc_Init(&batch);
47 ** ptr = Batch_Get(&batch, 16);
48 **
49 ** Chunks are released all at once (in batch) like this.
50 **
51 ** Batch_Destroy(&batch);
52 **
53 ** All allocations exceeding the maximum block size or maximum total size
54 ** of the batch are allocated on the heap. These blocks can be released
55 ** released individually with:
56 **
57 ** Batch_Put(&batch, ptr);
58 **
59 ** Pointers passed to this function that are not on the heap are ignored,
60 ** so it is safe to call Put() in the general case.
61 **
62 **==============================================================================
63 */
64 mike 1.1
|
65 krisbash 1.3 #define BATCH_MAX_PAGES INFINITE
|
66 mike 1.1
67 #define BATCH_INITIALIZER { NULL, NULL, NULL, 0, BATCH_MAX_PAGES }
68
69 /* Represents a page of memory */
70 typedef struct _Page
71 {
72 union
73 {
74 struct _Page_s
75 {
76 struct _Page* next;
77
78 /* If non-zero, this page may be independenty released (contains
79 * a single block). If so, then passing it to Batch_Put() will
|
80 krisbash 1.3 * pass this block to PAL_Free(). Otherwise, calling Batch_Put()
|
81 mike 1.1 * has no effect.
82 */
83 unsigned int independent:1;
84
|
85 krisbash 1.3 /* Size of the allocation (not including page header) */
|
86 mike 1.1 unsigned int size:31;
87 }
88 s;
89 char alignment[(sizeof(struct _Page_s) + 7) & ~7];
90 }
91 u;
92 }
93 Page;
94
95 typedef struct _Batch
96 {
97 /* Pointer to next available byte of current page */
98 char* avail;
99
100 /* Pointer to last byte of available memory */
101 char* end;
102
103 /* Pointer to page list */
104 Page* pages;
105
106 /* Number of pages */
107 mike 1.1 size_t numPages;
108
109 /* Maximum number of pages */
110 size_t maxPages;
111 }
112 Batch;
113
114 MI_INLINE void Batch_Init(
115 Batch* self,
116 size_t maxPages)
117 {
118 memset(self, 0, sizeof(Batch));
119 self->maxPages = maxPages;
120 }
121
122 void Batch_InitFromBuffer(
123 Batch* self,
124 void* data,
125 size_t size,
126 size_t maxPages);
127
128 mike 1.1 void Batch_Destroy(
129 Batch* self);
130
131 Batch* Batch_New(
132 size_t maxPages);
133
134 void Batch_Delete(
135 Batch* self);
136
137 void* Batch_Get(
138 Batch* self,
139 size_t size);
140
141 MI_INLINE void* Batch_GetClear(
142 Batch* self,
143 size_t size)
144 {
145 void* ptr = Batch_Get(self, size);
146
147 if (ptr)
148 memset(ptr, 0, size);
149 mike 1.1
150 return ptr;
151 }
152
153 void Batch_Put(
154 Batch* self,
155 void* ptr);
156
|
157 krisbash 1.3 _Check_return_
158 ZChar* Batch_Tcsdup(
|
159 mike 1.1 Batch* self,
|
160 krisbash 1.3 const ZChar* str);
|
161 mike 1.1
|
162 krisbash 1.3 _Check_return_
|
163 mike 1.1 char* Batch_Strdup(
164 Batch* self,
165 const char* str);
166
|
167 krisbash 1.3 #if defined(CONFIG_ENABLE_WCHAR)
168 ZChar* Batch_StrTcsdup(
|
169 mike 1.1 Batch* self,
170 const char* str);
|
171 krisbash 1.3 #else
172 MI_INLINE ZChar* Batch_StrTcsdup(
173 Batch* self,
174 const char* str)
175 {
176 return Batch_Strdup(self, str);
177 }
178 #endif
179
180 #if defined(CONFIG_ENABLE_WCHAR)
181 char* Batch_ZStrdup(
182 Batch* self,
183 const ZChar* str);
184 #else
185 MI_INLINE char* Batch_ZStrdup(
186 Batch* self,
187 const ZChar* str)
188 {
189 return Batch_Strdup(self, str);
190 }
191 #endif
|
192 mike 1.1
193 /* protocol support */
194 typedef struct _Header_BatchInfoItem
195 {
196 void* pagePointer;
197 size_t pageSize;
198 }
199 Header_BatchInfoItem;
200
201 size_t Batch_GetPageCount(
202 Batch* self);
203
204 void* Batch_GetPageByIndex(
205 Batch* self,
206 size_t index);
207
208 size_t Batch_GetPageInfo(
209 Batch* self,
210 Header_BatchInfoItem* buffer);
211
212 MI_Boolean Batch_CreateBatchByPageInfo(
213 mike 1.1 Batch** self,
214 const Header_BatchInfoItem* buffer,
215 size_t pages);
216
217 MI_Boolean Batch_FixPointer(
218 Batch* batch,
219 const Header_BatchInfoItem* ptrAdjustmentInfo,
220 size_t ptrAdjustmentInfoCount,
221 void** ptrInOut);
222
223 /* Add this block to list of individual blocks */
224 MI_INLINE void Batch_AttachPage(
225 Batch* self,
226 Page* page)
227 {
228 page->u.s.next = self->pages;
229 self->pages = page;
230 page->u.s.independent = 0;
231 }
232
233 END_EXTERNC
234 mike 1.1
235 #endif /* _omi_batch_h */
|