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