日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

contiki源码阅读之mmem.c

發(fā)布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 contiki源码阅读之mmem.c 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

上次我們說了list,這次我們就借著mmem.c的代碼來用一下這個鏈表。

代碼目錄是./core/lib/mmem.c

結(jié)構(gòu)體定義如下

struct mmem {struct mmem *next;unsigned int size;void *ptr; };請注意,第一個成員必須是指針,這樣才可以借用list的代碼。

第二個成員是要申請的字節(jié)數(shù),第三個成員是指針,指向返回內(nèi)存的首地址。

插句話,對于單片機,如果想內(nèi)存管理(不考慮虛擬地址,只考慮物理地址),主要有兩種方法。一種是引出堆的指針,在此基礎(chǔ)上自己封裝,把這個堆管理起來(沒有嘗試過這種方法,也沒有讀到這方面的資料,留待以后研究。)還有一種方法,就是簡單的定義一片全局變量,把這些空間管理起來。今天討論的是第二種方法。

#ifdef MMEM_CONF_SIZE #define MMEM_SIZE MMEM_CONF_SIZE #else #define MMEM_SIZE 4096 #endifLIST(mmemlist); unsigned int avail_memory; static char memory[MMEM_SIZE];
這里定義了全局?jǐn)?shù)組,4096個字節(jié)。

定義了全局變量avail_memory,用來記錄還剩余多少個字節(jié)沒有分配。

定義了一個鏈表(上次已經(jīng)介紹過相關(guān)代碼了)。


void mmem_init(void) {list_init(mmemlist);avail_memory = MMEM_SIZE; }
初始化函數(shù),初始化鏈表并且設(shè)置全局變量avail_memory=4096,4K個字節(jié)。

在上次的list.h文件中,可以看到作者這樣的注釋:

A linked list is made up of elements where the first element ?must be a pointer. This pointer is used by the linked list library?to form lists of the elements.

這呼應(yīng)了開頭的話,因為list里面就是一個指針,所以用戶的結(jié)構(gòu)體必須把指針作為第一個成員,這樣才能在不同指針(用戶的結(jié)構(gòu)體和 struct list)之間自由轉(zhuǎn)換而不會發(fā)生錯位。


int mmem_alloc(struct mmem *m, unsigned int size) {/* Check if we have enough memory left for this allocation. */if(avail_memory < size) {return 0;}/* We had enough memory so we add this memory block to the end ofthe list of allocated memory blocks. */list_add(mmemlist, m);/* Set up the pointer so that it points to the first available bytein the memory block. */m->ptr = &memory[MMEM_SIZE - avail_memory];//這句賦值,把那段全局?jǐn)?shù)組和m里面的指針聯(lián)系起來了,有了m,就能找到那片內(nèi)存/* Remember the size of this memory block. */m->size = size;/* Decrease the amount of available memory. */avail_memory -= size;/* Return non-zero to indicate that we were able to allocatememory. */return 1; }這就是內(nèi)存分配函數(shù)。


void mmem_free(struct mmem *m) {struct mmem *n;if(m->next != NULL) {/* Compact the memory after the allocation that is to be removedby moving it downwards. */memmove(m->ptr, m->next->ptr,&memory[MMEM_SIZE - avail_memory] - (char *)m->next->ptr);/* Update all the memory pointers that points to memory that isafter the allocation that is to be removed. */for(n = m->next; n != NULL; n = n->next) {n->ptr = (void *)((char *)n->ptr - m->size);}}avail_memory += m->size;/* Remove the memory block from the list. */list_remove(mmemlist, m); }內(nèi)存的釋放。首先看看要釋放的是不是鏈表的最后一個元素,如果是,那么就簡單了,把字節(jié)數(shù)還回去,再把這塊內(nèi)存從鏈表上脫離。

如果不是,就要進(jìn)行字節(jié)的拷貝。把這個內(nèi)存之后的所有內(nèi)容(內(nèi)存的末尾減去后面的內(nèi)存塊的起始地址)向前面移動(移動的距離剛好是這個內(nèi)存塊的大小)。

但是這樣還沒有完,因為后面的內(nèi)存塊移動了,所以要修改每個內(nèi)存塊的指針,指針的值也要相應(yīng)減少m->size個字節(jié)。

這樣做的好處是什么,就是沒有內(nèi)存碎片。因為每次釋放,都會把后面的內(nèi)容移動到前面,填補釋放的空洞。




總結(jié)

以上是生活随笔為你收集整理的contiki源码阅读之mmem.c的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。