本シリーズのトップページ |
---|
https://qiita.com/robozushi10/items/ca7c25dab3c279ba4e2b |
はじめに
本記事の趣旨は「01 概要」に記しているが、
要は 13年前(=2008年) に K&R をマネて実装した「自作メモリアロケータ」の振り返りである.
本項では次の (4)(5)(6) について記す.
(4) 「アクセッサ」は「動的メモリ獲得・解放」を持つ関数ポインタ「alloc」「free」を提供する.
⬇️
(5) ユーザはアクセッサの関数ポインタ「alloc」と「free」に対して、任意のメモリ操作関数を設定する.
⬇️
(6) ユーザはアクセッサを使って初回に必要なメモリプールを獲得する. (以後、拡張・縮小はできない).
詳細
(4) について
(4) 「アクセッサ」は「動的メモリ獲得・解放」を持つ関数ポインタ「alloc」「free」を提供する.
memman.h
/* ユーザが使用するアクセッサ */
typedef
struct _mem_inst_t
{
void * (* alloc) (int id, size_t size); /* メモリ獲得I/F */
void (* free) (int id, void * ptr); /* メモリ解放I/F */
void (* get_used_size)(void); /* 使用量取得I/F */
void (* get_rest_size)(void); /* 残量取得関I/F */
int id;
}
mem_inst_t;
(5) と (6) について
(5) ユーザはアクセッサの関数ポインタ「alloc」と「free」に対して、任意のメモリ操作関数を設定する.
(6) ユーザはアクセッサを使って初回に必要なメモリプールを獲得する. (以後、拡張・縮小はできない).
main.c
下記 🛑 が、アクセッサの構造体変数「alloc」「free」に登録したい情報を持つ構造体である.
下記 🏷️ より、アクセッサの「alloc」「free」に対して、使用したい関数ポインタを (変数req
に)
登録している. ここではシステム関数である malloc と free を登録している.
下記 📋 にて、獲得したいメモリプールのサイズを定義している. ここでは 4096 = 4K である.
下記 🔐 sem は、(クリティカルセクションである) アクセッサの「alloc」「free」での排他制御である.
末尾の「instance = Mman_new_inst(&req);
」 によって instance すなわちアクセッサが得られる.
int
main()
{
mem_inst_t * instance = NULL;
char * buf[1000];
int i = 0;
int j = 0;
req_mem_inst_t req;🛑
/* セマフォについても管理モジュールを作成し,内部で資源情報を
* 保持すると良いが,ここでは作成していない */
sem_init /* セマフォの初期化 */
(
&Sem, /* セマフォ変数の初期化 */
0, /* 0:スレッドでセマフォ共有, 非0:プロセスで共有 */
1 /* 並列処理数 */
);
req.functor_alloc = &malloc, 🏷️
req.functor_free = &free, 🏷️
req.pool_size = 4096, 📋
req.key = "main",
req.sem = &Sem; 🔐
req.pshared = 0;
req.value = 0;
#if 1
instance = Mman_new_inst(&req);