本シリーズのトップページ |
---|
https://qiita.com/robozushi10/items/ca7c25dab3c279ba4e2b |
はじめに
本記事の趣旨は「01 概要」に記しているが、
要は 13年前(=2008年) に K&R をマネて実装した「自作メモリアロケータ」の振り返りである.
本項では次の (7) のうち、「メモリ解放」処理について記す.
(7) 以後、ユーザはアクセッサを介してメモリプールからメモリ獲得・解放をする
詳細
(7) について
(7) 以後、ユーザはアクセッサを介してメモリプールからメモリ獲得・解放をする
main.c
下記🛑での i には解放したいメモリサイズである.
int
main()
{
略
#if 1
instance = Mman_new_inst(&req);
for(j = 0; j < 500; j++)
{
for(i = 0; i < 1000; i++)
{
buf[i] = instance->alloc(0,i);
}
for(i = 0; i < 1000; i++) /* alloc よりも小さい値にするとメモリリークが確認出来る */
{
instance->free(0, buf[i]); // 🛑メモリ解放処理. 第1引数「0」は自身の id である
}
}
memman.c
上記 🛑 の free の実体が下記 Mman_free である.
書籍「K&R」の free をマネた部分である.
void
Mman_free(int id, void * ptr)
{
mman_t * p = mman_get_rsrc(id);
Mmc_free(id, ptr, p->functor_free);
}
memman_core.c
以下は、上記 🤹 の Mman_free に進むと、下記 mmc_free()
に繋がる.
mmc_free()
の 第3引数が free() へのポインタである.
コード内の「robozushi10: need sem lock
」や「〜 unlock
」というコメントの箇所は、
それぞれ排他ロックと解放処理を加えるつもりだったようである.
が, (13年前の私は) 未実装のまま放置してしまった模様.
なお、排他制御をしている理由は、クリティカルセクション保護のためである.
/* メモリ解放関数。実際には free せずにフリーリストにつなぐだけ */
static void
mmc_free(int id, void * p, void * functor)
{
Header * bp = (Header *)p;
Header * hp = ((Header *)p)-1;
(void) functor;
/* robozushi10: need sem look */
MMAN_DBP("[id:%d]mmc_free(): mmc_free(%p)\n", id, p);
hp->s.ptr = NULL;
#ifdef DEBUG_CHK_MEMLEAK
Mmc_debug_rm_addr((unsigned)p);
#endif /* DEBUG_CHK_MEMLEAK */
MMAN_DBP("[id:%d]mmc_free(): call add_freelist(%p)\n", id, bp);
add_freelist(id, (void *)bp);
/* robozushi10: need sem unlook */
}