INF: How to Change the MS-DOS Memory Allocation Strategy

ID Number: Q58919

3.x 4.x 5.00 5.10 6.00 6.00a 6.00ax 7.00

MS-DOS

Summary:

When MS-DOS allocates memory for your program, it uses a firstfit

allocation strategy by default. You can change MS-DOS's default

strategy to a bestfit, lastfit, or back to firstfit strategy with a

call to interrupt 21h function 58h.

More Information:

A firstfit strategy forces MS-DOS to search from low addresses in

memory to high addresses, and allocate the first available block of

memory large enough for the requested allocation.

A bestfit strategy forces MS-DOS to search all addresses in memory and

allocate the smallest block still large enough to fill the requested

allocation.

A lastfit strategy forces MS-DOS to search from high addresses in

memory to low addresses, and allocate the first available block of

memory large enough for the requested allocation.

The bestfit algorithm is the slowest to execute since all free memory

is searched, but results in the least memory fragmentation during

multiple allocations and frees. Conversely, the firstfit and lastfit

strategies are fastest to execute, but result in a higher degree of

memory fragmentation.

Note that changing the allocation strategy only noticeably changes the

way that a call to _dos_allocmem(), halloc(), or interrupt 21h

function 48h allocates memory from MS-DOS. The malloc() and calloc()

families of routines allocate memory from the memory pool assigned to

your program by MS-DOS. They are affected by MS-DOS's internal

allocation strategy only when the free memory pool for your program is

empty and MS-DOS is required to add new memory to your program's pool.

Sample Code

-----------

/* The following two functions, written with C 6.0 or QuickC 2.0

in-line assembly, respectively set and get the MS-DOS allocation

strategy:

*/

#define ALLOCATION_STRATEGY 0x58

#define GET_STRATEGY 0x00

#define SET_STRATEGY 0x01

/********************************************************/

/* Set_fittype - Set MS-DOS allocation strategy */

/* Parameters : strategy_type, defined as: */

/* FIRSTFIT = 0x00 */

/* DEFAULT = 0x00 */

/* BESTFIT = 0x01 */

/* LASTFIT = 0x02 */

/* Return Value : */

/* -2 = Invalid Allocation strategy */

/* -1 = Invalid Function to Int 21h Func 58h */

/* Should never happen. */

/* Otherwise, returns newly set strategy */

/********************************************************/

int set_fittype ( unsigned strategy_type )

{

int return_value;

if (( strategy_type < 0 ) || ( strategy_type > 2))

{

return ( -2 ) ;

}

else

{

_asm {

mov ah, ALLOCATION_STRATEGY

mov al, SET_STRATEGY

mov bx, strategy_type

int 21h

jnc no_error ; Branch if no error

mov ax, -1 ; Return -1 on error

no_error:

mov return_value, ax ; -1 if error, otherwise

; returns current strategy

}

}

return ( return_value ) ;

}

/********************************************************/

/* Get_fittype - Returns current allocation strategy. */

/* Parameters : None */

/* Return Value : */

/* 0 = Firstfit strategy */

/* 1 = Bestfit strategy */

/* 2 = Lastfit strategy */

/********************************************************/

int get_fittype ( void )

{

unsigned return_value;

_asm {

mov ah, ALLOCATION_STRATEGY

mov al, GET_STRATEGY

int 21h

jnc no_error ; Branch if no error

mov ax, -1 ; Return -1 on error

no_error:

mov return_value, ax ; -1 on error, otherwise

; current strategy

}

return ( return_value ) ;

}

If your compiler supports in-line assembly, you should use the above

functions because of their speed since they do not require the C

overhead.

If you are using any of our compilers that do not support in-line

assembly code, such as C 5.0, C 5.1, QuickC 1.0, and QuickC 1.01, the

above functions can be translated as follows:

#include <dos.h> /* as well as the other #includes listed above */

int set_fittype ( unsigned strategy_type )

{

union REGS inregs, outregs;

int return_value;

if (( strategy_type < 0 ) || ( strategy_type > 2))

{

return ( -2 ) ;

}

else

{

inregs.h.ah = ALLOCATION_STRATEGY ;

inregs.h.al = SET_STRATEGY ;

inregs.x.bx = strategy_type ;

int86 ( 0x21, &inregs, &outregs ) ;

if ( outregs.x.cflag )

return ( -1 ) ;

else

return ( outregs.x.ax ) ;

}

}

int get_fittype ( void )

{

union REGS inregs, outregs;

unsigned return_value;

inregs.h.ah = ALLOCATION_STRATEGY

inregs.h.al = GET_STRATEGY

int86 ( 0x21, &inregs, &outregs ) ;

if ( outregs.x.cflag )

return ( -1 ) ;

else

return ( outregs.x.ax ) ;

}

Additional reference words: 5.10 6.00 6.00a 6.00ax 7.00