Sync with trunk r63192.
[reactos.git] / lib / rtl / heapuser.c
1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * FILE: lib/rtl/heap.c
4 * PURPOSE: RTL Heap backend allocator (user mode only functions)
5 * PROGRAMMERS: Copyright 2010 Aleksey Bragin
6 */
7
8 /* INCLUDES *****************************************************************/
9
10 #include <rtl.h>
11 #include <heap.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
17
18
19 /* Usermode only! */
20 VOID
21 NTAPI
22 RtlpAddHeapToProcessList(PHEAP Heap)
23 {
24 PPEB Peb;
25
26 /* Get PEB */
27 Peb = RtlGetCurrentPeb();
28
29 /* Acquire the lock */
30 RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
31
32 //_SEH2_TRY {
33 /* Check if max number of heaps reached */
34 if (Peb->NumberOfHeaps == Peb->MaximumNumberOfHeaps)
35 {
36 // TODO: Handle this case
37 ASSERT(FALSE);
38 }
39
40 /* Add the heap to the process heaps */
41 Peb->ProcessHeaps[Peb->NumberOfHeaps] = Heap;
42 Peb->NumberOfHeaps++;
43 Heap->ProcessHeapsListIndex = (USHORT)Peb->NumberOfHeaps;
44 // } _SEH2_FINALLY {
45
46 /* Release the lock */
47 RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
48
49 // } _SEH2_END
50 }
51
52 /* Usermode only! */
53 VOID
54 NTAPI
55 RtlpRemoveHeapFromProcessList(PHEAP Heap)
56 {
57 PPEB Peb;
58 PHEAP *Current, *Next;
59 ULONG Count;
60
61 /* Get PEB */
62 Peb = RtlGetCurrentPeb();
63
64 /* Acquire the lock */
65 RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
66
67 /* Check if we don't need anything to do */
68 if ((Heap->ProcessHeapsListIndex == 0) ||
69 (Heap->ProcessHeapsListIndex > Peb->NumberOfHeaps) ||
70 (Peb->NumberOfHeaps == 0))
71 {
72 /* Release the lock */
73 RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
74
75 return;
76 }
77
78 /* The process actually has more than one heap.
79 Use classic, lernt from university times algorithm for removing an entry
80 from a static array */
81
82 Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
83 Next = Current + 1;
84
85 /* How many items we need to shift to the left */
86 Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);
87
88 /* Move them all in a loop */
89 while (--Count)
90 {
91 /* Copy it and advance next pointer */
92 *Current = *Next;
93
94 /* Update its index */
95 (*Current)->ProcessHeapsListIndex -= 1;
96
97 /* Advance pointers */
98 Current++;
99 Next++;
100 }
101
102 /* Decrease total number of heaps */
103 Peb->NumberOfHeaps--;
104
105 /* Zero last unused item */
106 Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
107 Heap->ProcessHeapsListIndex = 0;
108
109 /* Release the lock */
110 RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
111 }
112
113 VOID
114 NTAPI
115 RtlInitializeHeapManager(VOID)
116 {
117 PPEB Peb;
118
119 /* Get PEB */
120 Peb = RtlGetCurrentPeb();
121
122 /* Initialize heap-related fields of PEB */
123 Peb->NumberOfHeaps = 0;
124
125 /* Initialize the process heaps list protecting lock */
126 RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
127 }
128