Vous êtes sur la page 1sur 5

/*-------------------------------------------------------------

name: my malloc

note: this implementation for embedded environment, that may or


may not have an os, and does not have malloc library.

version: 0.1

author: vigneshwara baliga

comments:
ah, if you were wondering� yes this is gpl ! ..of course it is,
so feel free to use it and modify it, if it does not, you just
work hard and get it working :-). also if possible do drop in
a email to me at vigneshwar.baliga at-gmail-com. well i do not
check this email very often :-) so do send me a scrap on orkut,
if i failed to respond in resenable time.

let�s say you can get access to physical memory for your task
and you have few more tasks. this memory is not for the stack
or atleast this part of the memory. so use appropriate part of
the ram for it.
so now you have decided, and your heap memory start address is
ram_addr = 0x00f0 0000, from 0x0 to ram_addr � 1 address is for
your stack or other things, and ram_addr onwards is for your
heap till (say) ram_end = 0x0140 0000, i.e. total of 5 mb and
lets say you have 5 tasks, so 1mb per task of heap memory.

in this case (version), i am assuming just one task which has


1 mb of ram space available, and the user can allocate max of
127 bytes (this limit is just for demonstration).
-------------------------------------------------------------*/

#define max_alloc 127 /* x111 1111 = 127 */


#define heap_start 0x00f00000
#define heap_end (0x00f00000 + (1 * 1024 * 1024))
#define used 0x01
#define un_used 0x00
#define min_alloc 1
#define heap_offset 2 /* offset after the heap pattern 0xdead */
#define heap_sign 0xdead /* heap signature, hardcoded now */
#define alloc_sign 0xbadb /* alloc signature, not used now */

enum bool {false = 0, true = 1}; /* just to be safe define it */


typedef unsigned char byte; /* if byte is not defined */
typedef null = (char *)0; /* no harm in defining it again */

char *my_heap_ptr = (char *) heap_start;


/* alternative method is to define a 1mb char array and point
this heap pointer to it, instead of physical ram address. */
char *curr_heap_ptr;

struct self_memo_mgmt
{
/* byte arr[2]; // set this to �0xbadb�, this is for next ver
// ..of memo mgmt, i'll call it alloc signature
*/
byte used:1;
byte size:7; /* max memory allocatable max_alloc */
};

/*-------------------------------------------------------------
function name: mem_init

comment: this function needs to be called before we start,


malloking our way to glory. so do it at powerup or before
you start the task, ok atleast before the first malloc.

parameter: void, or the heap signature of your own or based


on task name.

return: void, or you can return curr_heap_ptr

-------------------------------------------------------------*/
void mem_init(void)
{
curr_heap_ptr = my_heap_ptr;
* curr_heap_ptr++ = 0xde; /* 1 byte = heap_offset/2 */
* curr_heap_ptr++ = 0xad; /* 1 byte = heap_offset/2 */
}

/*-------------------------------------------------------------
function name: search_free_blk

comment: this function will search for any available free space
in the fragmented memory that we have now (at that point),
if the first available free space (even if greated than
required) that is found it will return a pointer to it, if
available size is present and does not exceed the heap_end.

parameter: size of memory required.

return: pointer to memory where free space is available.

-------------------------------------------------------------*/
char * search_free_blk(size)
{
struct self_memo_mgmt *memo_info;
curr_heap_ptr = my_heap_ptr + heap_offset;

/* if we are here, then either there is not sufficient


memory at the end and memory is fragmented. so we look
through the allocated space and see if any location has
used flag set to un_used.
okay!, if you are wondering, any stray pointer or
previous block pointer exceeds and over writes this ?
well, thats our problem, so write proper and defensive
code :-)
if we had implemented the alloc signature, we'd check
it here, and if it is not there or corrupted, then we
know what happened! but we can try to fix that too :-),
but thats in next to next version.
*/
/* note:
comment: not writing the code for this now, will do so when
i get time. sorry :-)

this is a good area to implement all the crazy algorithm you


can think of, including defragmenting the memory.
*/
}

/*-------------------------------------------------------------
function name: my_malloc

comment: this function will allocate the memory from the source,
that is either an array or physical, and return the pointer to it.

parameter: size of the memory to be allocated,


max memory allocatable is 127 bytes.

return: returns valid pointer pointing to memory allocated.


returns zero is no memory or size is invalid.

-------------------------------------------------------------*/
char *my_malloc(byte size)
{
struct self_memo_mgmt *memo_info;
char *temp;

if(size > 0) && (size < (max_alloc + 1) )


{
if((curr_heap_ptr + (size + sizeof(struct self_memo_mgmt))) > heap_end )
curr_heap_ptr = search_free_blk(size);

if(curr_heap_ptr != my_heap_ptr)
{
memo_info = (struct self_memo_mgmt *) curr_heap_ptr;
/* lock protected */
memo_info->used = used;
memo_info->size = (0x7f & size); /* just and it to be safe */
temp = curr_heap_ptr + sizeof(struct self_memo_mgmt);
curr_heap_ptr = temp + size;
/* lock release */
return temp;
}
else
{
/* we ran out of memory */
return null;
}
}
else
{
return null;
}
}

/*-------------------------------------------------------------
function name: my_free
comment: this function will free the memory pointed by the
pointer. null or invalid pointer will return 0 (zero).

parameter: char pointer.

return: size of the memory freed. my implementation is


different!!

-------------------------------------------------------------*/
byte my_free(char *ptr)
{
struct self_memo_mgmt *memo_info;
if(
(ptr >= (heap_start + heap_offset)) &&
(ptr <= (heap_end - (sizeof(struct self_memo_mgmt) + min_alloc) ) )
)
{
memo_info = (struct self_memo_mgmt *)(ptr - sizeof(struct self_memo_mgmt));
/* lock protected */
memo_info->used = un_used;
/* lock release */
/* note:
leave the size field as it is. we need it later.
if we had implemented the alloc signature, we'd check it here.
*/
return memo_info->size;
}
else
{
return 0;
}
}

/*-------------------------------------------------------------
function name: my_sizeof

comment: this function will return the size of memory pointed


to by the pointer.

parameter: char pointer. null pointer will return 0 (zero)

return: size of the memory pointed to by the pointer.

-------------------------------------------------------------*/
byte my_sizeof(char *ptr)
{
/*
not now, will implement it later.
*/
}

/*-------------------------------------------------------------
function name: my_memset

comment: this function will write the "value" passed upto the
"size" in memory pointed by a valid pointer.
parameter: valid pointer to memory. size of the memory to
set/written to and value to be written with.

return: size of memory of value written with.

-------------------------------------------------------------*/
byte my_memset(char *ptr, byte size, byte value)
{
/*
nope!, not going to implement this today.but if you plan
to do it, then check for valid ptr passed in.
see if we exceed the size, less is okay.
..and value should not be the alloc signature, if and
when we implement it.
*/
return size;
}

Vous aimerez peut-être aussi