ReactOS  0.4.14-dev-77-gd9e7c48
memory.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Drivers
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: drivers/sac/driver/memory.c
5  * PURPOSE: Driver for the Server Administration Console (SAC) for EMS
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "sacdrv.h"
12 
13 /* GLOBALS ********************************************************************/
14 
18 
19 /* FUNCTIONS ******************************************************************/
20 
21 BOOLEAN
22 NTAPI
24 {
26  SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
27 
28  /* Allocate a nonpaged heap for us to use */
33  if (GlobalMemoryList)
34  {
35  /* Initialize a lock for it */
37 
38  /* Initialize the head of the list */
43 
44  /* Initialize the first free entry */
46  Entry->Signature = LOCAL_MEMORY_SIGNATURE;
47  Entry->Tag = FREE_POOL_TAG;
48  Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
49 
50  /* All done */
51  SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n");
52  return TRUE;
53  }
54 
55  /* No pool available to manage our heap */
56  SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n");
57  return FALSE;
58 }
59 
60 VOID
61 NTAPI
63 {
64  PSAC_MEMORY_LIST Next;
65  KIRQL OldIrql;
66  SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
67 
68  /* Acquire the memory lock while freeing the list(s) */
70  while (GlobalMemoryList)
71  {
73 
74  /* While outside of the lock, save the next list and free this one */
76  Next = GlobalMemoryList->Next;
78 
79  /* Reacquire the lock and see if there was another list to free */
81  GlobalMemoryList = Next;
82  }
83 
84  /* All done */
86  SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n");
87 }
88 
89 PVOID
90 NTAPI
92  IN ULONG Tag,
93  IN PCHAR File,
94  IN ULONG Line)
95 {
96  PVOID p;
97  p = ExAllocatePoolWithTag(NonPagedPool, PoolSize, 'HACK');
98  RtlZeroMemory(p, PoolSize);
99  SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", p);
100  return p;
101 #if 0
102  KIRQL OldIrql;
103  PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor;
104  PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
105  ULONG GlobalSize, ActualSize;
106  PVOID Buffer;
107 
109  SAC_DBG(SAC_DBG_MM, "Entering.\n");
110 
111  /* Acquire the memory allocation lock and align the size request */
113  PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
114 
115 #if _USE_SAC_HEAP_ALLOCATOR_
116  GlobalDescriptor = GlobalMemoryList;
118  while (GlobalDescriptor)
119  {
121 
122  LocalDescriptor = GlobalDescriptor->LocalDescriptor;
123 
124  GlobalSize = GlobalDescriptor->Size;
125  while (GlobalSize)
126  {
127  ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
128 
129  if ((LocalDescriptor->Tag == FREE_POOL_TAG) &&
130  (LocalDescriptor->Size >= PoolSize))
131  {
132  break;
133  }
134 
135  GlobalSize -= (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
136 
137  LocalDescriptor =
138  (PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
139  LocalDescriptor->Size +
140  sizeof(SAC_MEMORY_ENTRY));
141  }
142 
143  GlobalDescriptor = GlobalDescriptor->Next;
144  }
145 
146  if (!GlobalDescriptor)
147  {
149 
150  ActualSize = min(
151  PAGE_SIZE,
152  PoolSize + sizeof(SAC_MEMORY_ENTRY) + sizeof(SAC_MEMORY_LIST));
153 
154  SAC_DBG(SAC_DBG_MM, "Allocating new space.\n");
155 
157  ActualSize,
160  if (!NewDescriptor)
161  {
162  SAC_DBG(SAC_DBG_MM, "No more memory, returning NULL.\n");
163  return NULL;
164  }
165 
167 
169  NewDescriptor->LocalDescriptor = (PSAC_MEMORY_ENTRY)(NewDescriptor + 1);
170  NewDescriptor->Size = ActualSize - 16;
172 
174 
175  LocalDescriptor = NewDescriptor->LocalDescriptor;
176  LocalDescriptor->Signature = LOCAL_MEMORY_SIGNATURE;
177  LocalDescriptor->Tag = FREE_POOL_TAG;
178  LocalDescriptor->Size =
180  }
181 
182  SAC_DBG(SAC_DBG_MM, "Found a good sized block.\n");
183  ASSERT(LocalDescriptor->Tag == FREE_POOL_TAG);
184  ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
185 
186  if (LocalDescriptor->Size > (PoolSize + sizeof(SAC_MEMORY_ENTRY)))
187  {
188  NextDescriptor =
189  (PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
190  PoolSize +
191  sizeof(SAC_MEMORY_ENTRY));
192  if (NextDescriptor->Tag == FREE_POOL_TAG)
193  {
194  NextDescriptor->Tag = FREE_POOL_TAG;
195  NextDescriptor->Signature = LOCAL_MEMORY_SIGNATURE;
196  NextDescriptor->Size =
197  (LocalDescriptor->Size - PoolSize - sizeof(SAC_MEMORY_ENTRY));
198 
199  LocalDescriptor->Size = PoolSize;
200  }
201  }
202 #else
203  /* Shut the compiler up */
204  NewDescriptor = GlobalDescriptor = NULL;
206  ActualSize = GlobalSize;
207  NextDescriptor = (PVOID)ActualSize;
208  NewDescriptor = (PVOID)NextDescriptor;
209 
210  /* Use the NT pool allocator */
211  LocalDescriptor = ExAllocatePoolWithTag(NonPagedPool,
212  PoolSize + sizeof(*LocalDescriptor),
213  Tag);
214  LocalDescriptor->Size = PoolSize;
215 #endif
216  /* Set the tag, and release the lock */
217  LocalDescriptor->Tag = Tag;
219 
220  /* Update our performance counters */
222  InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size);
223 
224  /* Return the buffer and zero it */
225  SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", LocalDescriptor);
226  Buffer = LocalDescriptor + 1;
227  RtlZeroMemory(Buffer, PoolSize);
228  return Buffer;
229 #endif
230 }
231 
232 VOID
233 NTAPI
235 {
236 #if 0
237  PSAC_MEMORY_ENTRY NextDescriptor;
238  PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor;
239  PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY));
241  PSAC_MEMORY_LIST GlobalDescriptor;
242  KIRQL OldIrql;
243  SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor);
244 
245  /* Make sure this was a valid entry */
246  ASSERT(LocalDescriptor->Size > 0);
247  ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
248 
249  /* Update performance counters */
251  InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size);
252 
253  /* Acquire the memory allocation lock */
254  GlobalDescriptor = GlobalMemoryList;
256 
257 #if _USE_SAC_HEAP_ALLOCATOR_
258  while (GlobalDescriptor)
259  {
261 
262  FoundDescriptor = NULL;
263 
264  ThisDescriptor = GlobalDescriptor->LocalDescriptor;
265 
266  GlobalSize = GlobalDescriptor->Size;
267  while (GlobalSize)
268  {
269  ASSERT(ThisDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
270 
271  if (ThisDescriptor == LocalDescriptor) break;
272 
273  GlobalSize -= (ThisDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
274 
275  ThisDescriptor =
276  (PSAC_MEMORY_ENTRY)((ULONG_PTR)ThisDescriptor +
277  ThisDescriptor->Size +
278  sizeof(SAC_MEMORY_ENTRY));
279  }
280 
281  if (ThisDescriptor == LocalDescriptor) break;
282 
283  GlobalDescriptor = GlobalDescriptor->Next;
284  }
285 
286  if (!GlobalDescriptor)
287  {
289  SAC_DBG(SAC_DBG_MM, "Could not find block.\n");
290  return;
291  }
292 
293  ASSERT(ThisDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
294 
295  if (LocalDescriptor->Tag == FREE_POOL_TAG)
296  {
298  SAC_DBG(SAC_DBG_MM, "Attempted to free something twice.\n");
299  return;
300  }
301 
302  LocalSize = LocalDescriptor->Size;
303  LocalDescriptor->Tag = FREE_POOL_TAG;
304 
305  if (GlobalSize > (LocalSize + sizeof(SAC_MEMORY_ENTRY)))
306  {
307  NextDescriptor =
308  (PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
309  LocalSize +
310  sizeof(SAC_MEMORY_ENTRY));
311  if (NextDescriptor->Tag == FREE_POOL_TAG)
312  {
313  NextDescriptor->Tag = 0;
314  NextDescriptor->Signature = 0;
315 
316  LocalDescriptor->Size +=
317  (NextDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
318  }
319  }
320 
321  if ((FoundDescriptor) && (FoundDescriptor->Tag == FREE_POOL_TAG))
322  {
323  LocalDescriptor->Signature = 0;
324  LocalDescriptor->Tag = 0;
325 
326  FoundDescriptor->Size +=
327  (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
328  }
329 #else
330  /* Shut the compiler up */
331  LocalSize = GlobalSize = 0;
332  ThisDescriptor = (PVOID)LocalSize;
333  NextDescriptor = (PVOID)GlobalSize;
334  GlobalDescriptor = (PVOID)ThisDescriptor;
335  FoundDescriptor = (PVOID)GlobalDescriptor;
336  GlobalDescriptor = (PVOID)NextDescriptor;
337  NextDescriptor = (PVOID)FoundDescriptor;
338 
339  /* Use the NT pool allocator*/
340  ExFreePool(LocalDescriptor);
341 #endif
342 
343  /* Release the lock, delete the address, and return */
345 #endif
346  SAC_DBG(SAC_DBG_MM, "exiting: 0x%p.\n", *Block);
347  ExFreePoolWithTag(*Block, 'HACK');
348  *Block = NULL;
349 }
signed char * PCHAR
Definition: retypes.h:7
Definition: sacdrv.h:190
VOID NTAPI MyFreePool(IN PVOID *Block)
Definition: memory.c:234
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
LONG TotalAllocations
Definition: memory.c:15
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
ULONG Tag
Definition: sacdrv.h:193
struct _Entry Entry
Definition: kefuncs.h:640
struct _SAC_MEMORY_ENTRY SAC_MEMORY_ENTRY
SIZE_T NTAPI LocalSize(HLOCAL hMem)
Definition: heapmem.c:1777
#define ALLOC_BLOCK_TAG
Definition: sacdrv.h:137
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:29
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG Size
Definition: sacdrv.h:194
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
#define INITIAL_BLOCK_TAG
Definition: sacdrv.h:138
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
unsigned char BOOLEAN
BOOLEAN NTAPI InitializeMemoryManagement(VOID)
Definition: memory.c:23
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define LOCAL_MEMORY_SIGNATURE
Definition: sacdrv.h:143
void * PVOID
Definition: retypes.h:9
#define InterlockedExchangeAdd
Definition: interlocked.h:181
LONG TotalBytesFreed
Definition: memory.c:15
struct _SAC_MEMORY_LIST * Next
Definition: sacdrv.h:201
VOID NTAPI FreeMemoryManagement(VOID)
Definition: memory.c:62
#define SAC_DBG_MM
Definition: sacdrv.h:35
uint64_t ULONGLONG
Definition: typedefs.h:65
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ULONG Signature
Definition: sacdrv.h:192
struct _SAC_MEMORY_ENTRY * PSAC_MEMORY_ENTRY
#define SAC_MEMORY_LIST_SIZE
Definition: sacdrv.h:149
LONG TotalBytesAllocated
Definition: memory.c:15
struct _SAC_MEMORY_LIST SAC_MEMORY_LIST
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: ncftp.h:79
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define SAC_DBG(x,...)
Definition: sacdrv.h:37
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define FREE_POOL_TAG
Definition: sacdrv.h:140
LONG TotalFrees
Definition: memory.c:15
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define InterlockedIncrement
Definition: armddk.h:53
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
PVOID NTAPI ExAllocatePoolWithTagPriority(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag, IN EX_POOL_PRIORITY Priority)
Definition: expool.c:2915
#define min(a, b)
Definition: monoChain.cc:55
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
ULONG Signature
Definition: sacdrv.h:198
PSAC_MEMORY_LIST GlobalMemoryList
Definition: memory.c:17
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
PSAC_MEMORY_ENTRY LocalDescriptor
Definition: sacdrv.h:199
unsigned int ULONG
Definition: retypes.h:1
#define SAC_DBG_ENTRY_EXIT
Definition: sacdrv.h:32
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
KSPIN_LOCK MemoryLock
Definition: memory.c:16
#define GLOBAL_MEMORY_SIGNATURE
Definition: sacdrv.h:144
Definition: File.h:15
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID NTAPI MyAllocatePool(IN SIZE_T PoolSize, IN ULONG Tag, IN PCHAR File, IN ULONG Line)
Definition: memory.c:91
GLfloat GLfloat p
Definition: glext.h:8902
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352