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 #define BATCH_MAX_PAGES 64
66
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 * pass this block to free(). Otherwise, calling Batch_Put()
81 * has no effect.
82 */
83 unsigned int independent:1;
84
85 mike 1.1 /* Size of the allocation */
86 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 mike 1.1 /* Number of pages */
107 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 mike 1.1
128 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 mike 1.1 memset(ptr, 0, size);
149
150 return ptr;
151 }
152
153 void Batch_Put(
154 Batch* self,
155 void* ptr);
156
157 MI_Char* Batch_Zdup(
158 Batch* self,
159 const MI_Char* str);
160
161 char* Batch_Strdup(
162 Batch* self,
163 const char* str);
164
165 MI_Char* Batch_Strdup2(
166 Batch* self,
167 const char* str);
168
169 mike 1.1 /* protocol support */
170 typedef struct _Header_BatchInfoItem
171 {
172 void* pagePointer;
173 size_t pageSize;
174 }
175 Header_BatchInfoItem;
176
177 size_t Batch_GetPageCount(
178 Batch* self);
179
180 void* Batch_GetPageByIndex(
181 Batch* self,
182 size_t index);
183
184 size_t Batch_GetPageInfo(
185 Batch* self,
186 Header_BatchInfoItem* buffer);
187
188 MI_Boolean Batch_CreateBatchByPageInfo(
189 Batch** self,
190 mike 1.1 const Header_BatchInfoItem* buffer,
191 size_t pages);
192
193 MI_Boolean Batch_FixPointer(
194 Batch* batch,
195 const Header_BatchInfoItem* ptrAdjustmentInfo,
196 size_t ptrAdjustmentInfoCount,
197 void** ptrInOut);
198
199 /* Add this block to list of individual blocks */
200 MI_INLINE void Batch_AttachPage(
201 Batch* self,
202 Page* page)
203 {
204 page->u.s.next = self->pages;
205 self->pages = page;
206 page->u.s.independent = 0;
207 }
208
209 END_EXTERNC
210
211 mike 1.1 #endif /* _omi_batch_h */
|