Simple Memory Allocation Algorithm

Source: Internet
Author: User

Implement a simple Memory Allocation Module with simple fragment functions

/* Start of main. c */

# Include "memory. h"

# Define MEMBODY_SIZE 640

Char membody [MEMBODY_SIZE] = {0 ,};

Int main ()
{
Void * mem1, * mem2, * mem3;
Int I;
Printf ("main !!! \ N ");
Simple_mem_init (membody, MEMBODY_SIZE );

Apsaradb for mem1 = simple_new (200 );
Apsaradb for mem2 = simple_new (200 );
Mem3 = simple_new (200 );
Simple_delete (mem1 );
Simple_delete (mem2 );
Simple_delete (mem3 );

Apsaradb for mem1 = simple_new (300 );
Simple_delete (mem1 );

For (I = 0; I ++ ){
If (! Simple_new (10 ))
Break;
}

Return 0;
}

/* End of Main. C */

/* Start of memory. H */

# Ifndef memory_h

# Define memory_h

/* Not very useful, but only some defines */

# Include "common. H"

Void simple_delete (char * data );
Void simple_delete_array (char * data );

Void simple_memset (char * data, char Val, int32 size );
Char * simple_new (int32 size );

Bool simple_mem_init (char * MEM, int32 size );
# Endif

/* End of memory. H */

/* Start of memory. C */

# Include "memory. h"

// Sizeof (MEM_ALLOC_INFO) must be mem_slice_size aligned
Typedef struct {
Int32 size;
} MEM_ALLOC_INFO;

# Define mem_slice_size 4 // must be greater than 4 and shoule be multile of 4

# Define mem_slice_size_is_2_index // define this if mem_slice_size = 2 ^ n

# Ifdef mem_slice_size_is_2_index
// Mem_slice_size = 2 ^ mem_slice_size_shift
# Define mem_slice_size_shift 2
# Endif

# Define bitsof (type) (int32) (sizeof (type) <3 ))
// The last on is greater than mem_block_free_list_size * mem_slice_size
# Define mem_block_free_list_size (0x80)

# Ifdef mem_slice_size_is_2_index
# Define roundup_2_mem_slice_size (size) + mem_slice_size-1) & (-mem_slice_size ))
# Else
# Define roundup_2_mem_slice_size (size) + mem_slice_size-1)-(size) + mem_slice_size-1) % mem_slice_size ))
# Endif

// {4, 8, 12, 16 ...}
// The last is a list that with various size but greater
// Mem_slice_size * mem_block_free_list_size
Static char * mem_block_free_list [mem_block_free_list_size] = {0 ,};
Static unsigned char mem_valible_idx_flag [mem_block_free_list_size/(bitsof (char)] = {0 ,};
// Stats
Static int32 mem_block_free_cnt_list [mem_block_free_list_size] = {0 ,};
Static int32 mem_block_alloc_cnt_list [mem_block_free_list_size] = {0 ,};
Static int32 mem_block_alloc_fail_cnt_list [mem_block_free_list_size] = {0 ,};

Static void add_new_block (char * mem, int32 size );
Static char * simple_new_internal (int32 alloc_size );
Static char * malloc_by_idx (int32 idx, int32 alloc_size );
Static int32 collect_mem (char * m );
Static void mem_block_set (int32 idx, char * mem );
Static void process_partion_mem (char * mem, int32 size );

Static char * membody;
Static int32 membody_size;

# Define mem_used_flag 0x1
# Define mem_flag_mask 0x3

# Define mem_size (mem )\
(* (Int32 *) (mem) & (-4 ))

# Define mem_is_used (mem )\
(* (Int32 *) (mem) & mem_used_flag)

# Define mem_set_freed (mem )\
(* (Int32 *) (mem) = (* (int32 *) (mem) & (-2 ));

# Define mem_set_used (mem )\
(* (Int32 *) (mem) = (* (int32 *) (mem) | mem_used_flag)

# Define mem_size_idx (idx )\
(Idx) * (mem_slice_size ))

# Define mem_block (idx )\
Mem_block_free_list [idx]

# Define mem_next (mem )\
(* (Int32 *) (mem + sizeof (int32 )))

# Define mem_next_get (mem )\
(Char *) mem_next (mem)

# Define mem_next_set (mem, next )\
Mem_next (mem) = next

// (Mem_slice_size = 4)
Static int32 mem_idx (int32 size)
{
# Ifdef mem_slice_size_is_2_index
Int32 idx = (size)> mem_slice_size_shift );
# Else
Int32 idx = size/mem_slice_size;
# Endif
If (idx> = mem_block_free_list_size)
Idx = mem_block_free_list_size-1;
Return idx;
}

# Define mem_size_idx_min \
Mem_idx (sizeof (MEM_ALLOC_INFO) + mem_slice_size-1)

Static void mem_size_set (char * mem, int32 size)
{
Size = size | (* (int32 *) (mem) & mem_flag_mask );
(* (Int32 *) (mem) = size;
}

Static void mem_block_set (int32 idx, char * mem)
{
Int32 x = idx> 3;
Int32 y = idx & 7;
Mem_block_free_list [idx] = mem;
If (mem! = NULL ){
Mem_valible_idx_flag [x] =
Mem_valible_idx_flag [x] | (1 <y );
} Else {
Mem_valible_idx_flag [x] =
Mem_valible_idx_flag [x] & (~ (1 <y ));
}
}

Static void alloc_stats (int32 size)
{
Mem_block_alloc_cnt_list [mem_idx (size)] ++;
}

Static void alloc_fail_stats (int32 size)
{
Mem_block_alloc_fail_cnt_list [mem_idx (size)] ++;
}

Static void free_stats (int32 size)
{
Mem_block_free_cnt_list [mem_idx (size)] ++;
}

// The first funtion must be called when memmory alloc works
Bool simple_mem_init (char * mem, int32 size)
{
If (! Mem |! Size)
Return false;
Membody = mem;
Membody_size = size;
Add_new_block (mem, size );
Return true;
}

Static void mem_set_alloc_inf (char * mem, int32 size)
{
Mem_size_set (mem, size );
Mem_set_used (mem );
}

Static bool mem_in (char * addr)
{
If (ADDR <membody | ADDR> = membody + membody_size)
Return false;
Return true;
}
// Mem is in free list
Static void remove_free_mem (char * MEm)
{
Char * pre = 0, * cur = NULL;
Int32 idx = mem_idx (mem_size (MEM ));
Cur = mem_block (idx );
While (cur! = MEm ){
Pre = cur;
Cur = mem_next_get (cur );
}

If (cur! = MEm ){
Crashme ("Invalid Data !!! ");
Return;
}

If (pre! = NULL)
Mem_next_set (pre, mem_next_get (cur ));
Else if (cur = mem_block (idx )){
Char * next = mem_next_get (cur );
Mem_block_set (idx, mem_next_get (cur ));
}
Mem_next_set (mem, NULL );
}

Static void merge_mem (char * mem)
{
Remove_free_mem (mem + mem_size (mem ));
Mem_size_set (mem, mem_size (mem) + mem_size (mem )));
}

Static int32 collect_mem (char * m)
{
Int32 size = mem_size (m );
If (! Mem_is_used (m ))
Remove_free_mem (m );
While (mem_in (m + size)
&&! Mem_is_used (m + size )){
Merge_mem (m );
Size = mem_size (m );
}
Add_new_block (m, size );
Return size;
}

Void simple_delete (char * data)
{
Char * m = (char *) data-sizeof (MEM_ALLOC_INFO );
If (! Mem_in (m)
|! Mem_is_used (m ))
Return;
Free_stats (mem_size (m ));
Collect_mem (m );
}

Void simple_delete_array (char * data)
{
Simple_delete (data );
}

Void simple_memset (char * data,
Char val, int32 size)
{
Int32 I;
For (I = 0; I <size; I ++)
Data [I] = val;
}

Static void add_new_block (char * mem, int32 size)
{
Int32 idx = mem_idx (size );
Mem_next_set (mem, mem_block (idx ));
Mem_block_set (idx, mem );
Mem_set_freed (mem );
Mem_size_set (mem, size );

}

Static char * post_alloc (int32 idx,
Int32 alloc_size)
{
# Ifdef mem_slice_size_is_2_index
Int32 remain = (idx <mem_slice_size_shift)-alloc_size;
# Else
Int32 remain = idx * mem_slice_size-alloc_size;
# Endif
Char * memnext = mem_next_get (mem_block (idx ));
Add_new_block (mem_block (idx) + alloc_size,
Remain );
Return memnext;
}

Static char * find_best_match (int32 alloc_size)
{
Char * nextmem;
Int32 diff = 0x7fffffff;
Char * bestmem = NULL;
Char * pre1 = NULL, * pre2 = NULL;
For (nextmem = mem_block (mem_block_free_list_size-1 );
Nextmem! = NULL;
Pre1 = nextmem, nextmem = mem_next (nextmem )){
If (mem_size (nextmem)> = alloc_size
& (Mem_size (nextmem)-alloc_size) <diff ){
Pre2 = pre1;
Diff = mem_size (nextmem)-alloc_size;
Bestmem = nextmem;
If (diff <0x10)
Break;
}
}

If (bestmem! = NULL ){
If (pre2! = NULL)
Mem_next_set (pre2, mem_next_get (bestmem ));
Else
Mem_block_set (mem_block_free_list_size-1, mem_next_get (bestmem ));
}

Return bestmem;
}

Static int32 collect (int32 idx, int32 alloc_size)
{
Char * m = mem_block (idx );
Int32 size;
While (m! = NULL ){
Size = collect_mem (m );
If (size> = alloc_size)
Return mem_idx (size );
M = mem_next_get (m );
}
Return-1;
}

// When compact and find a memory bigger than alloc_size
// Just return idx
Static int32 mem_compact (int32 alloc_size)
{
Int32 idx;
Int32 validi = 0;

For (validi = (mem_block_free_list_size> 3)-1;
Validi> = 0;
Validi --){
If (mem_valible_idx_flag [validi] = 0)
Continue;
For (idx = (validi + 1) <3)-1;
Idx >=( validi <3 );
Idx --){
If (mem_block (idx )! = NULL ){
Int32 result = collect (idx, alloc_size );
If (result> = 0)
Return result;
}

}
}
Return-1;
}

Static char * big_mem_alloc (int32 alloc_size)
{
Char * bestmem = find_best_match (alloc_size );

If (! Bestmem ){
Int32 idx = mem_compact (alloc_size );
If (idx> = 0)
Return malloc_by_idx (idx, alloc_size );
Alloc_fail_stats (alloc_size );
CrashMe ("out of memory ");
Return NULL;
}
Process_partion_mem (bestmem + alloc_size, mem_size (bestmem)-alloc_size );
Mem_set_alloc_inf (bestmem, alloc_size );
Return bestmem + sizeof (mem_alloc_info );
}

Static int32 next_valible_idx (int32 idx)
{
Int32 I, CNT;
For (I = idx/bitsof (char); I <(mem_block_free_list_size> 3); I ++ ){
If (mem_valible_idx_flag [I]! = 0
& Mem_valible_idx_flag [I] >=( 1 <(idx & 7 ))){
CNT = (I <3) + (idx & 7 );
Return CNT;
}
Idx = 0;
}
Return mem_block_free_list_size-1; // always try last item
}

Static void process_partion_mem (char * mem, int32 size)
{
If (size <= 0)
Return;
Mem_size_set (mem, size );
Mem_set_used (mem );
Collect_mem (mem );
}

Static char * malloc_by_idx (int32 idx, int32 alloc_size)
{
Char * result = 0;
If (idx = mem_block_free_list_size-1)
Return big_mem_alloc (alloc_size );

Result = mem_block (idx );
Mem_block_set (idx, mem_next_get (mem_block (idx )));
# Ifdef mem_slice_size_is_2_index
Process_partion_mem (result + alloc_size,
(Idx <mem_slice_size_shift)-alloc_size );
# Else
Process_partion_mem (result + alloc_size,
Idx * mem_slice_size-alloc_size );
# Endif
Mem_set_alloc_inf (result,
Alloc_size );
Return result + sizeof (mem_alloc_info );
}

Static char * simple_new_internal (int32 alloc_size)
{
Int32 idx = mem_idx (alloc_size );
Int32 tmp = next_valible_idx (idx );
Idx = tmp> idx? Tmp: idx;

Alloc_stats (alloc_size );

For (idx; idx <mem_block_free_list_size-1; idx ++ ){
If (mem_block (idx )! = NULL ){
Break;
}
}

Return malloc_by_idx (idx, alloc_size );
}

Char * simple_new (int32 size)
{
Char * result = 0;
Int32 alloc_size = size + sizeof (MEM_ALLOC_INFO );
If (! Size)
Return NULL;

Alloc_size = roundup_2_mem_slice_size (alloc_size );
Return simple_new_internal (alloc_size );
}

/* End of memory. C */

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.