欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
lwip-mem_init和mem_malloc詳解

[cpp] view plain copy

#define MEM_ALIGNMENT           

//對齊方式為4字節對齊  

#ifndef LWIP_MEM_ALIGN_SIZE  

#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))   

//實(shí)現待分配數據空間的內存對齊  

#endif  

#ifndef LWIP_MEM_ALIGN            

//地址對齊,對齊方式也為4字節對齊  

#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))  

#endif  

/* MEM_SIZE: the size of the heap memory. If the application will send 

a lot of data that needs to be copied, this should be set high. */  

#define MEM_SIZE                (8*1024)      

//堆的總空間大小,此后在這個(gè)基礎上劃分堆,將在這個(gè)空間進(jìn)行內存分配,內存塊結構體和數據都是在這個(gè)空間上的  

//mem為內存塊的結構體,next;,prev都為內存塊索引  

struct mem {  

/** index (-> ram[next]) of the next struct */ //ram為堆的首地址,相當于數組的首地址,索引基地址  

mem_size_t next;                  //next為下一個(gè)內存塊的索引  

/** index (-> ram[next]) of the next struct */  

mem_size_t prev;                  //prev為前一個(gè)內存塊的索引                          

/** 1: this area is used; 0: this area is unused */  

u8_t used;                        //標志此內存塊已被分配  

};  

static struct mem *ram_end;  

/** All allocated blocks will be MIN_SIZE bytes big, at least! 

* MIN_SIZE can be overridden to suit your needs. Smaller values save space, 

* larger values could prevent too small blocks to fragment the RAM too much. */  

#ifndef MIN_SIZE  

#define MIN_SIZE             12   

//內存塊大小的最小限制,不能小于12  

#endif /* MIN_SIZE */  

/* some alignment macros: we define them here for better source code layout */  

#define MIN_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MIN_SIZE)    

//將MIN_SIZE按4字節對齊,即把12按4字節對齊  

#define SIZEOF_STRUCT_MEM    LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))  

//將mem大小按4字節對齊  

#define MEM_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEM_SIZE)  

//將堆的總空間按4字節對齊,MEM_SIZE在前面,為8*1024  

//內存對齊解釋看我的博文:http://blog.csdn.net/lg2lh/article/details/34853883  

/** the heap. we need one struct mem at the end and some room for alignment */  

static u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT];   

//實(shí)際開(kāi)的堆內存空間,MEM_SIZE_ALIGNED為對齊后的數據空間為8192  

//堆內存的大小為MEM_SIZE_ALIGNED+(2*SIZEOF_STRUCT_MEM)+MEM_ALIGNMENT=8192+2*MEN結構體的大小+4  

void  

mem_init(void)  

{  

struct mem *mem;    

//定義一個(gè)mem結構體指針變量  

LWIP_ASSERT("Sanity check alignment",  

(SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0);  

/* align the heap */  

ram = LWIP_MEM_ALIGN(ram_heap);     

//將堆空間首地址ram_heap按4字節地址對齊  

/* initialize the start of the heap */  

mem = (struct mem *)ram;    

//將堆空間ram 首地址強制轉換成mem結構體類(lèi)型,作為首個(gè)內存塊,但這個(gè)內存塊還未使用  

mem->next = MEM_SIZE_ALIGNED;  

//把首個(gè)內存塊的next指針指向了堆空間的最后一個(gè)地址(MEM_SIZE_ALIGNED為8*1024),后面實(shí)際在mem_malloc時(shí)會(huì )動(dòng)態(tài)調整next索引,  

//從而得到實(shí)際分配內存空間即為 mem->next減去該內存塊mem的地址  

//待分配內存塊的next索引總是指向堆空間最后,好像也不一定,但是按照思路是這樣的。  

mem->prev = 0;  

//初始化,因為是第一個(gè)內存塊,所以前一個(gè)內存塊不存在,故初始化為0  

mem->used = 0;  

//該內存塊沒(méi)有被分配,待分配狀態(tài)  

/* initialize the end of the heap */  

ram_end = (struct mem *)&ram[MEM_SIZE_ALIGNED];  

//例化一個(gè)堆空間末尾內存塊,該內存塊指向最后一個(gè)地址,標志結尾用的已被分配,不可再分配了  

ram_end->used = 1;   

//該內存塊已被分配  

ram_end->next = MEM_SIZE_ALIGNED;    

//因為后續再無(wú)內存塊故,next索引指向最后,即自己  

ram_end->prev = MEM_SIZE_ALIGNED;    

//這個(gè)我也不知道啊  

mem_sem = sys_sem_new(1);  

/* initialize the lowest-free pointer to the start of the heap */  

lfree = (struct mem *)ram;      

//初始化空閑對指針,此時(shí)首個(gè)內存塊是空閑的  

MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);  

}  

void *  

mem_malloc(mem_size_t size)  

{  

mem_size_t ptr, ptr2;  

struct mem *mem, *mem2;  

#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT  

u8_t local_mem_free_count = 0;  

#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */  

LWIP_MEM_ALLOC_DECL_PROTECT();  

if (size == 0) {  

return NULL;  

}  

//size為0的話(huà)返回null 分配不成功  

/* Expand the size of the allocated memory region so that we can 

adjust for alignment. */  

size = LWIP_MEM_ALIGN_SIZE(size);  

//將待分配數據按4字節進(jìn)行對齊  

if(size < MIN_SIZE_ALIGNED) {   

//如果待分配空間小于MIN_SIZE_ALIGNED(12),則返回分配空間也要為12,最小分配空間為12  

/* every data block must be at least MIN_SIZE_ALIGNED long */  

size = MIN_SIZE_ALIGNED;  

}  

if (size > MEM_SIZE_ALIGNED) {  

//如果待分配空間大于MEM_SIZE_ALIGNED(8*1024),超出堆空間,則返回NULL,無(wú)法分配  

return NULL;  

}  

/* protect the heap from concurrent access */  

sys_arch_sem_wait(mem_sem, 0);  

LWIP_MEM_ALLOC_PROTECT(); //未定義  

#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT  

/* run as long as a mem_free disturbed mem_malloc */  

do {  

local_mem_free_count = 0;  

#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */  

/* Scan through the heap searching for a free block that is big enough, 

* beginning with the lowest free block. 

*/  

//ptr初值=空閑內存塊地址與堆內存首地址之差,如果ptr+size小于堆空間總大小8*1024,則可實(shí)現相應大小  

//的內存塊分配,其中ptr實(shí)際為已分配了的空間大小,size為待分配的空間大小,兩個(gè)和一定要小于總空間,才可以實(shí)現分配.  

//判斷完成后,將ptr賦值為該內存塊next所指地址  

for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size;  

ptr = ((struct mem *)&ram[ptr])->next) {  

//將待分配的這個(gè)內存空間初始化為內存塊結構體                         

mem = (struct mem *)&ram[ptr];  

#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT //未定義  

mem_free_count = 0;  

LWIP_MEM_ALLOC_UNPROTECT();  

/* allow mem_free to run */  

LWIP_MEM_ALLOC_PROTECT();  

if (mem_free_count != 0) {  

local_mem_free_count = mem_free_count;  

}  

mem_free_count = 0;  

#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */  

//ptr為已分配了的內存空間  

//后面你會(huì )發(fā)現,待分配內存塊的mem->next始終指向堆空間的最后,即MEM_SIZE_ALIGNED。  

//內存塊未被使用,此時(shí)mem為待分配內存塊,故mem->next指向MEM_SIZE_ALIGNED,  

//剩余分配空間(MEM_SIZE_ALIGNED-已分配空間-MEM結構體大?。┮笥谝峙淇臻gsize  

if ((!mem->used) &&                  

(mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {  

/* mem is not used and at least perfect fit is possible: 

* mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */  

//剩余分配空間(MEM_SIZE_ALIGNED-已分配空間-2*MEM結構體大小-12)  

//要大于要待分配空間size,則才可以進(jìn)行內存分配。  

if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {                                       

/* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing 

* at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') 

* -> split large block, create empty remainder, 

* remainder must be large enough to contain MIN_SIZE_ALIGNED data: if 

* mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, 

* struct mem would fit in but no data between mem2 and mem2->next 

* @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty 

*       region that couldn't hold data, but when mem->next gets freed, 

*       the 2 regions would be combined, resulting in more free memory 

*/  

//ptr2指向新的待分配內存空間  

ptr2 = ptr + SIZEOF_STRUCT_MEM + size;   

/* create mem2 struct */  

//mem2為新的待分配內存塊結構體  

mem2 = (struct mem *)&ram[ptr2];  

//新的內存塊mem2未被使用  

mem2->used = 0;      

//新的待分配的內存塊mem2的next索引指向堆空間的最后,即MEM_SIZE_ALIGNED       

mem2->next = mem->next;  

//而新的內存塊的prev索引是我們這次正在分配的模塊索引,即ptr     

mem2->prev = ptr;        

/* and insert it between mem and mem->next */  

//把本次分配的mem內存塊的next索引重新定位,指向新的待分配的模塊的索引,不再指向堆空間最后  

mem->next = ptr2;        

mem->used = 1;//本內存塊被使用  

//我之前分析的都是新的待分配內存塊next索引應該始終指向堆空間最后的,這里竟然判斷了,可能存在不指向最后的情況  

//具體原因還沒(méi)分析。如果新的待分配內存塊mem2的next索引未指向最后,則需要將它所指向的索引內存塊的prev索引指向  

//他自己ptr2。  

if (mem2->next != MEM_SIZE_ALIGNED) {    

((struct mem *)&ram[mem2->next])->prev = ptr2;  

}  

MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));  

} else {//如果沒(méi)有滿(mǎn)足對應if條件,則直接分配完改內存塊即可,也不用指向下一個(gè)待分配的內存塊,因為沒(méi)有空間可以再分配了  

/* (a mem2 struct does no fit into the user data space of mem and mem->next will always 

* be used at this point: if not we have 2 unused structs in a row, plug_holes should have 

* take care of this). 

* -> near fit or excact fit: do not split, no mem2 creation 

* also can't move mem->next directly behind mem, since mem->next 

* will always be used at this point! 

mem->used = 1;  

MEM_STATS_INC_USED(used, mem->next - ((u8_t *)mem - ram));  

if (mem == lfree) {//將空閑指針索引指向新的待分配內存塊索引ram[lfree->next],即ptr2  

/* Find next free block after mem and update lowest free pointer */  

while (lfree->used && lfree != ram_end) {  

LWIP_MEM_ALLOC_UNPROTECT();  

/* prevent high interrupt latency... */  

LWIP_MEM_ALLOC_PROTECT();  

lfree = (struct mem *)&ram[lfree->next];  

LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));  

}  

LWIP_MEM_ALLOC_UNPROTECT();  

sys_sem_signal(mem_sem);  

LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",  

(mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);  

LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",  

((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);  

LWIP_ASSERT("mem_malloc: sanity check alignment",  

(((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);  

return (u8_t *)mem + SIZEOF_STRUCT_MEM;//返回分配結果,即已分配內存塊數據空間的首地址。  

#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT  

/* if we got interrupted by a mem_free, try again */  

} while(local_mem_free_count != 0);  

#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */  

LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));  

MEM_STATS_INC(err);  

LWIP_MEM_ALLOC_UNPROTECT();  

sys_sem_signal(mem_sem);  

return NULL;  

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
lwip之內存管理
LWIP內存池memp.c文件學(xué)習
嵌入式以太網(wǎng):Lwip內存管理之內存堆
帶你用純C實(shí)現一個(gè)內存池(圖文結合)
模擬內存動(dòng)態(tài)分配學(xué)習
實(shí)用算法解讀之RT-Thread鏈表堆管理器
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久