ReactOS 0.4.15-dev-7994-gb388cb6
cmalloc.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmalloc.c
5 * PURPOSE: Routines for allocating and freeing registry structures
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS *******************************************************************/
16
20
23
24/* FUNCTIONS *****************************************************************/
25
26CODE_SEG("INIT")
27VOID
30{
31 /* Make sure we didn't already do this */
32 if (!CmpAllocInited)
33 {
34 /* Setup the lock and list */
38 }
39}
40
41CODE_SEG("INIT")
42VOID
45{
46 /* Initialize the delay allocation list and lock */
49}
50
51VOID
54{
55 ULONG i;
56 PCM_ALLOC_PAGE AllocPage;
57 PAGED_CODE();
58
59 /* Sanity checks */
60 ASSERT(IsListEmpty(&Kcb->KeyBodyListHead) == TRUE);
61 for (i = 0; i < 4; i++) ASSERT(Kcb->KeyBodyArray[i] == NULL);
62
63 /* Check if it wasn't privately allocated */
64 if (!Kcb->PrivateAlloc)
65 {
66 /* Free it from the pool */
67 CmpFree(Kcb, TAG_KCB);
68 return;
69 }
70
71 /* Acquire the private allocation lock */
73
74 /* Sanity check on lock ownership */
75 CMP_ASSERT_HASH_ENTRY_LOCK(Kcb->ConvKey);
76
77 /* Add us to the free list */
78 InsertTailList(&CmpFreeKCBListHead, &Kcb->FreeListEntry);
79
80 /* Get the allocation page */
81 AllocPage = CmpGetAllocPageFromKcb(Kcb);
82
83 /* Sanity check */
84 ASSERT(AllocPage->FreeCount != CM_KCBS_PER_PAGE);
85
86 /* Increase free count */
87 if (++AllocPage->FreeCount == CM_KCBS_PER_PAGE)
88 {
89 /* Loop all the entries */
90 for (i = 0; i < CM_KCBS_PER_PAGE; i++)
91 {
92 /* Get the KCB */
93 Kcb = (PVOID)((ULONG_PTR)AllocPage +
94 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
95 i * sizeof(CM_KEY_CONTROL_BLOCK));
96
97 /* Remove the entry */
98 RemoveEntryList(&Kcb->FreeListEntry);
99 }
100
101 /* Free the page */
102 CmpFree(AllocPage, TAG_KCB);
103 }
104
105 /* Release the lock */
107}
108
110NTAPI
112{
113 PLIST_ENTRY NextEntry;
114 PCM_KEY_CONTROL_BLOCK CurrentKcb;
115 PCM_ALLOC_PAGE AllocPage;
116 ULONG i;
117 PAGED_CODE();
118
119 /* Check if private allocations are initialized */
120 if (CmpAllocInited)
121 {
122 /* They are, acquire the bucket lock */
124
125 /* See if there's something on the free KCB list */
126SearchKcbList:
128 {
129 /* Remove the entry */
131
132 /* Get the KCB */
133 CurrentKcb = CONTAINING_RECORD(NextEntry,
135 FreeListEntry);
136
137 /* Get the allocation page */
138 AllocPage = CmpGetAllocPageFromKcb(CurrentKcb);
139
140 /* Decrease the free count */
141 ASSERT(AllocPage->FreeCount != 0);
142 AllocPage->FreeCount--;
143
144 /* Make sure this KCB is privately allocated */
145 ASSERT(CurrentKcb->PrivateAlloc == 1);
146
147 /* Release the allocation lock */
149
150 /* Return the KCB */
151 return CurrentKcb;
152 }
153
154 /* Allocate an allocation page */
155 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_KCB);
156 if (AllocPage)
157 {
158 /* Set default entries */
159 AllocPage->FreeCount = CM_KCBS_PER_PAGE;
160
161 /* Loop each entry */
162 for (i = 0; i < CM_KCBS_PER_PAGE; i++)
163 {
164 /* Get this entry */
165 CurrentKcb = (PVOID)((ULONG_PTR)AllocPage +
166 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
167 i * sizeof(CM_KEY_CONTROL_BLOCK));
168
169 /* Set it up */
170 CurrentKcb->PrivateAlloc = TRUE;
171 CurrentKcb->DelayCloseEntry = NULL;
173 &CurrentKcb->FreeListEntry);
174 }
175
176 /* Now go back and search the list */
177 goto SearchKcbList;
178 }
179
180 /* Release the allocation lock */
182 }
183
184 /* Allocate a KCB only */
185 CurrentKcb = CmpAllocate(sizeof(CM_KEY_CONTROL_BLOCK), TRUE, TAG_KCB);
186 if (CurrentKcb)
187 {
188 /* Set it up */
189 CurrentKcb->PrivateAlloc = 0;
190 CurrentKcb->DelayCloseEntry = NULL;
191 }
192
193 /* Return it */
194 return CurrentKcb;
195}
196
197PVOID
198NTAPI
200{
202 PCM_ALLOC_PAGE AllocPage;
203 ULONG i;
204 PLIST_ENTRY NextEntry;
205 PAGED_CODE();
206
207 /* Lock the allocation buckets */
209
210 /* Look for an item on the free list */
211SearchList:
213 {
214 /* Get the current entry in the list */
216
217 /* Grab the item */
218 Entry = CONTAINING_RECORD(NextEntry, CM_DELAY_ALLOC, ListEntry);
219
220 /* Clear the list */
221 Entry->ListEntry.Flink = Entry->ListEntry.Blink = NULL;
222
223 /* Grab the alloc page */
225
226 /* Decrease free entries */
227 ASSERT(AllocPage->FreeCount != 0);
228 AllocPage->FreeCount--;
229
230 /* Release the lock */
232 return Entry;
233 }
234
235 /* Allocate an allocation page */
236 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_CM);
237 if (AllocPage)
238 {
239 /* Set default entries */
240 AllocPage->FreeCount = CM_DELAYS_PER_PAGE;
241
242 /* Loop each entry */
243 for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
244 {
245 /* Get this entry and link it */
246 Entry = (PVOID)((ULONG_PTR)AllocPage +
247 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
248 i * sizeof(CM_DELAY_ALLOC));
250 &Entry->ListEntry);
251
252 /* Clear the KCB pointer */
253 Entry->Kcb = NULL;
254 }
255
256 /* Do the search again */
257 goto SearchList;
258 }
259
260 /* Release the lock */
262 return NULL;
263}
264
265VOID
266NTAPI
268{
270 PCM_ALLOC_PAGE AllocPage;
271 ULONG i;
272 PAGED_CODE();
273
274 /* Lock the table */
276
277 /* Add the entry at the end */
279
280 /* Get the alloc page */
282 ASSERT(AllocPage->FreeCount != CM_DELAYS_PER_PAGE);
283
284 /* Increase the number of free items */
285 if (++AllocPage->FreeCount == CM_DELAYS_PER_PAGE)
286 {
287 /* Page is totally free now, loop each entry */
288 for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
289 {
290 /* Get the entry and unlink it */
291 AllocEntry = (PVOID)((ULONG_PTR)AllocPage +
292 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
293 i * sizeof(CM_DELAY_ALLOC));
294 RemoveEntryList(&AllocEntry->ListEntry);
295 }
296
297 /* Now free the page */
298 CmpFree(AllocPage, TAG_CM);
299 }
300
301 /* Release the lock */
303}
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
struct _CM_DELAY_ALLOC CM_DELAY_ALLOC
#define CM_KCBS_PER_PAGE
Definition: cm.h:123
struct _CM_DELAY_ALLOC * PCM_DELAY_ALLOC
#define CM_DELAYS_PER_PAGE
Definition: cm.h:125
struct _CM_KEY_CONTROL_BLOCK CM_KEY_CONTROL_BLOCK
#define CmpGetAllocPageFromDelayAlloc(a)
Definition: cm_x.h:276
#define CmpGetAllocPageFromKcb(k)
Definition: cm_x.h:270
#define CMP_ASSERT_HASH_ENTRY_LOCK(k)
Definition: cm_x.h:251
LIST_ENTRY CmpFreeKCBListHead
Definition: cmalloc.c:19
BOOLEAN CmpAllocInited
Definition: cmalloc.c:17
LIST_ENTRY CmpFreeDelayItemsListHead
Definition: cmalloc.c:22
PVOID NTAPI CmpAllocateDelayItem(VOID)
Definition: cmalloc.c:199
KGUARDED_MUTEX CmpAllocBucketLock
Definition: cmalloc.c:18
VOID NTAPI CmpInitCmPrivateAlloc(VOID)
Definition: cmalloc.c:29
VOID NTAPI CmpInitCmPrivateDelayAlloc(VOID)
Definition: cmalloc.c:44
VOID NTAPI CmpFreeKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmalloc.c:53
VOID NTAPI CmpFreeDelayItem(PVOID Entry)
Definition: cmalloc.c:267
PCM_KEY_CONTROL_BLOCK NTAPI CmpAllocateKeyControlBlock(VOID)
Definition: cmalloc.c:111
KGUARDED_MUTEX CmpDelayAllocBucketLock
Definition: cmalloc.c:21
#define TAG_KCB
Definition: cmlib.h:213
#define TAG_CM
Definition: cmlib.h:212
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define ASSERT(a)
Definition: mode.c:44
base of all file and directory entries
Definition: entries.h:83
ULONG FreeCount
Definition: cm.h:348
LIST_ENTRY ListEntry
Definition: cm.h:358
ULONG PrivateAlloc
Definition: cm.h:273
LIST_ENTRY FreeListEntry
Definition: cm.h:302
PVOID DelayCloseEntry
Definition: cm.h:305
Definition: typedefs.h:120
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59