Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

276 lines
6.8 KiB

/*++
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.
--*/
{
}