summaryrefslogtreecommitdiffstats
path: root/private/mvdm/suballoc/suballoc.txt
blob: 03dfc9813e50d24c3b2618e2e3b6d815e38727fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*++

Copyright (c) 1992  Microsoft Corporation

Module Name:

    suballoc.c

Abstract:

    This module contains code for managing a paritially commited address
    space.  It handles allocation of chunks of memory smaller than the 
    commit granularity.  It commits and decommits memory as needed using
    the supplied function for committing and decommitting memory.  The 
    structures used for tracking the address space are allocated outside
    of the specified addresss space.

Author:

    Dave Hastings (daveh) creation-date 21-Jan-1994
    
Notes:

    Since this package does not actually access memory in the address space
    it is managing, it will work as well with real linear addresses or 
    "Intel Addresses" such as would be encountered with the Insignia Emulator
    on risc.

Revision History:


--*/

//
// Constants
// 

//
// Smallest chunk that will be sub allocated
// 1024 was chosen currently, because that is the
// smallest chunk XMS will allocate.
//
#define SUBALLOC_GRANULARITY        1024

//
// The size of the character array require to hold the 
// bits defining whether the individual allocation entities
// in the commited chunk are allocated or free
//
// BUGBUG Assert that COMMIT_GRANULARITY is a multiple of SUBALLOC_GRANULARITY
//
#define SUBALLOC_BITFIELD_SIZE      COMMIT_GRANULARITY / SUBALLOC_GRANULARITY

//
// Types
//

//
// Routine for committing a specific region of of the address
// space.  Although the return type is NTSTATUS, the only value
// that is checked is 0 (for STATUS_SUCCESS).  If STATUS_SUCCESS
// is returned, it is assumed that the function worked. If not,
// it is assumed that it failed.  No special meaning is attached to
// particular non-zero values.
//
typedef
NTSTATUS 
(*PSACOMMITROUTINE)(
    ULONG BaseAddress,
    ULONG Size
    );

//
// Structure for tracking the address space.  Each chunk of 
// memory of SUBALLOC_GRANULARITY in size is represented by
// a bit.  Each chunk of memory of COMMIT_GRANULARITY is 
// represented by one element of the array of bitfields.
// The FreeCheck array half of the union allows us to check
// whether the entire committed chunk is free more quickly.
//
// ?? Should we add a field to indicate whether the chunk is 
//    committed?  We can always check for all allocated bits
//    zero, and use that as an indication that the chunk is 
//    not committed.
//
// BUGBUG Assert that the bits fit into memory the way we think
// they do.
//
typedef struct _SubAllocation {
    PSACOMMITROUTINE CommitRoutine;
    ULONG BaseAddress;
    ULONG Size;
    union {
        //
        // bitfield with one bit per chunk.  Bit set indicates
        // allocated.  Bit clear indicates free.  All bits 
        // clear indicates un committed
        //
        UINT Allocated[SUBALLOC_BITFIELD_SIZE] : 1;
        //
        // Hopefully a faster way to check all bits.
        //
        UINT FreeCheck[SUBALLOC_BITFIELD_SIZE / sizeof(UINT)];
    } CommitedChunk;
} SUBALLOCATIONDATA, *PSUBALLOCATIONDATA


PVOID
SAInitialize(
    ULONG BaseAddress,
    ULONG Size,
    PSACOMMITROUTINE CommitRoutine
    )
/*++

Routine Description:

    This function performs initialization of the sub allocation package
    for the specified addresss range.  It allocates the data structures
    necessary to track the allocations

Arguments:

    BaseAddress -- Supplies the base address of the address space to
        sub allocate.
    Size -- Supplies the size in bytes of the address space to sub allocate.
    CommitRoutine -- Supplies a pointer to the routine used to commit regions
        of the address space.

Return Value:

    If the function was successful it returns a pointer to the sub-allocation
    data structures.  Otherwise it returns NULL.
    
--*/
{

}

BOOL 
SAQueryFree(
    PVOID SubAllocation,
    PULONG FreeBytes
    )    
/*++

Routine Description:

    This routine returns the number of free bytes in the 
    sub allocated address space.

Arguments:
    
    SubAllocation -- Supplies the pointer returned by SAInitialize
    FreeBytes -- Returns the number of free bytes
   
Return Value:

    TRUE -- if successful, and FreeBytes contains the number of free bytes.
    FALSE otherwise
    
--*/
{

}

BOOL
SAAllocate(
    PVOID SubAllocation,
    ULONG Size,
    PULONG Address
    )
/*++

Routine Description:

    This function allocates a portion of the address space described by 
    SubAllocation.  If necessary, it will commit additional blocks. Address is 
    rounded down to the next lower SUBALLOC_GRANULARITY boundary.
    size is rounded up to the next higher multiple of SUBALLOC_GRANULARITY.

Arguments:

    SubAllocation -- Supplies the pointer returned by SAInitialize.
    Size -- Supplies the size in bytes of the region to allocate.
    Address -- Returns the address of the region allocated.

Return Value:

    TRUE if successful.  If false is returned, no address is returned.
    
Notes:

    Zero is a valid value for the returned address.

--*/
{

}

BOOL
SAFree(
    PVOID SubAllocation,
    ULONG Size,
    ULONG Address
    )
/*++

Routine Description:

    This routine frees a sub-allocated chunk of memory.  If the 
    entire commited block (or blocks) that the specified chunk
    belongs to are free, the chunks are decommitted.  Address is 
    rounded down to the next lower SUBALLOC_GRANULARITY boundary.
    size is rounded up to the next higher multiple of SUBALLOC_GRANULARITY.

Arguments:

    SubAllocation -- Supplies the pointer returned by SAInitialize.
    Size -- Supplies the size in bytes of the region to free.
    Address -- Supplies the address of the region to free.

Return Value:

    TRUE if successful.
    
Notes:

    It is possible to free a different size at a particular 
    address than was allocated.  This will not cause the 
    SubAllocation package any problems.
    
--*/
{

}

BOOL
SAReallocate(
    PVOID SubAllocation,
    ULONG OriginalSize,
    ULONG OriginalAddress,
    ULONG NewSize,
    PULONG NewAddress
    )
/*++

Routine Description:

    This routine reallocates a sub allocated block of memory.
    The sizes are rounded up to the next SUBALLOC_GRANULARITY.
    The Original address is rounded down to the next SUBALLOC_GRANULARITY
    boundary.  Only min(OriginalSize, NewSize) bytes of data are copied to
    the new block.  The block changed in place if possible.

Arguments:

    SubAllocation -- Supplies the pointer returned by SAInitialize.
    OriginalSize -- Supplies the old size in bytes of the block.
    OriginalAddress -- Supplies the old address of the block.
    NewSize -- Supplies the new size in bytes of the block.
    NewAddress -- Returns the new address of the block.

Return Value:

    True if successful.  If unsucessful, no allocation is changed.
    
Notes:

    If the caller does not supply the correct original size for the block,
    some memory may be lost, and the block may be moved unnecessarily.
    
--*/
{

}