mmap ãããã¡ã¤ã«åãã« malloc ãä½ã£ã¦ã¿ã
ãã¡ã¤ã«ã mmap ããä»®æ³ã¡ã¢ãªã¢ãã¬ã¹ã®ä¸ã§ããã¼ã¿æ§é ãæä½ãã¦ããã®ã¾ã¾ãã¡ã¤ã«ã«ä¿åãããã¨æããããã¨ã¯ããã¾ããã§ããããã
å®éã«ãã£ã¦ã¿ããã¨ããã¨ãmmap ãããä»®æ³ã¡ã¢ãªé åã®ç©ºã空éã®ç®¡çãèªåã§è¡ããªããã°ãªããããã¡ã¤ã«ã mmap ãããé åããã¡ã¢ãªã確ä¿ãã¦ããã malloc ã®ãããªä»çµã¿ãå¿ è¦ã¨ãããã¨ã«æ°ã¥ãã¾ããã
é常㮠malloc ã¯å é¨çã«ç¬èªã§ brk ã®ãããªã·ã¹ãã ã³ã¼ã«ãå®è¡ãã¦ãOS ããã¡ã¢ãªé åã確ä¿ãã¦ããã®ã§ãç¬èªã«ãã¡ã¤ã«ã mmap ããé åã«ã¤ãã¦ã¯ã¡ã¢ãªç®¡çããã¦ããã¾ããã
ä»åã¯ãé常㮠malloc ã¨ç¬ç«ãã¦ãmmap ãããã¡ã¤ã«ã®ä»®æ³ã¡ã¢ãªé åã®ç®¡çããã¦ããã fmalloc ã¨ãã malloc ãä½ãã¾ããã
ãã¤ã³ãã¨ãã¦ã以前の記事ã«ãã fm_ptr ã¨ãããä»®æ³ã¡ã¢ãªã¢ãã¬ã¹ã¨ãã¡ã¤ã«å ã®ãªãã»ãããèªåã§å¤æãã¦ãããã¹ãã¼ããã¤ã³ã¿ã使ã£ã¦å®è£ ãã¾ãããfm_ptr ã«ã¤ãã¦ã¯éå»ã®è¨äºããåç §ãã ããã
ããã«ãããé常ã®ã¡ã¢ãªå é¨ã§å®çµããããã°ã©ã ãå¤§å¹ ã«å¤æ´ãããã¨ãªããã¡ã¢ãªãããããã¡ã¤ã«ãçµç±ãã¦ãã¡ã¤ã«ã¸ãã¼ã¿æ§é ã®ä¿åãã§ããããã«ãªãã¾ãã
ã½ã¼ã¹ã³ã¼ã㯠GitHub ã§å ¬éãã¦ããã¾ãã®ã§ããèå³ãããã¾ãããæ¯éã試ããã ããã
malloc ã«æ±ãããããã¨
malloc ã«ã¤ãã¦ã¯ä»¥ä¸ã®ãããªè¦ä»¶ãããã¨æããã¾ãã
- é度
- ã¡ã¢ãªé åã®å©ç¨å¹ç
- ãã«ãã³ã¢ã§ã®ã¹ã±ã¼ã©ããªãã£
ä¾ãã°ãå®è£ ã«ããã¾ããããªã¹ããããªã¼æ§é ã§ã¯ãæ°ãããã¼ãã追å ãããã¨ã«ãmalloc ã§ãã¼ãç¨ã®ã¡ã¢ãªã確ä¿ãã¾ãããªã®ã§ãç¹ã«ãã¼ããªã¥ã¼ã¹ãã¢çã®ãããªããã°ã©ã ã§ã¯ãmalloc ã®é度ã¯éè¦ã«ãªãã¾ãã
ã§ãããä¸è¨ã®è¦ä»¶ãéæããã®ã¯å®¹æã§ã¯ãªããç¬èªã§æ°ããå®ç¨ç㪠malloc ãå®è£ ããã®ã¯ã¨ã¦ãé£ããã§ãã
mmap ãããã¡ã¤ã«ç¨ã® malloc ã®ä½ãæ¹
é«éãã¤å¹çã®è¯ã malloc ãä¸ããä½ãã®ã¯ã¨ã¦ãé£ããã®ã§ãä»åã¯ãåºãå©ç¨ããã¦ãã ptmalloc ã¨ãã malloc ã®å®è£ ãæ¡å¼µãã¦ãã¡ã¢ãªãããããã¡ã¤ã«ã®ã¡ã¢ãªé åããã¡ã¢ãªç¢ºä¿ãè¡ããããã«ãã¾ããã
ptmalloc ã¯ãWolfram Gloger ããã¨ããæ¹ããDoug Lea ããã¨ããæ¹ã«ãã£ã¦å®è£ ããã dlmalloc ã¨å¼ã°ããå®è£ ãããã«ãã¹ã¬ããç°å¢ã«ããã¦ã¹ã±ã¼ã«ã§ããããã«æ¡å¼µãããã®ã§ããããã¯ãåºã GNU C ã©ã¤ãã©ãªã®ä¸é¨ã¨ãã¦å©ç¨ããã¦ãã malloc ã®å ã«ãªã£ã¦ãã¾ãã
ptmalloc ã¯ãæ¯è¼çæ°ãã jemalloc çã¨æ¯ã¹ã¦é ãã¨è¨ããã¦ãã¾ãããä¸è¬ã®äººãæ°ããå®è£ ããªããããã¯ããã«ç´ æ´ããããã®ã§ãããã¨ã¯ééãããã¾ããã
ä»åã¯ãæ¡å¼µã®ããããã®è¦³ç¹ãããptmalloc ãå ã«ãfmalloc ã¨ãã mmap ãããã¡ã¤ã«ç¨ã® malloc ãä½ã£ã¦ã¿ã¾ããã
fmalloc
fmalloc ã«ããããptmalloc ããã®å¤æ´ç¹ã¯ã主ã«ï¼ç¹ã§ãã
ä¸ã¤ç®ã¯ãptmalloc ã brk çã®ã·ã¹ãã ã³ã¼ã«ãå©ç¨ãã¦ãç¬èªã«ã¡ã¢ãªé åã確ä¿ãã¦ããç®æãå¤æ´ãã¦ã代ããã«ããã¡ã¤ã«ã mmap ããã¦ããã¡ã¢ãªé åããã¡ã¢ãªã確ä¿ããããã«ãã¾ããã
äºã¤ç®ã¯ãptmalloc ãå é¨ã®å®è£ ã«ç¨ãã¦ããæ§é ä½å é¨ã®ãã¤ã³ã¿å®£è¨ã fm_ptr ã«ç½®ãæãã¾ãããmalloc ã¯ã¡ã¢ãªé åãå°ãããã£ã³ã¯ã«åãã¦ç®¡çãã¾ããé常㮠malloc ã®å®è£ ã§ã¯ããã£ã³ã¯ã¸ã®ãã¤ã³ã¿ã¯ä»®æ³ã¡ã¢ãªã¢ãã¬ã¹ã§è¡¨ç¾ããã¦ãã¾ããããã®ãã¤ã³ã¿ã¯ã次å mmap ãããæã«ãåç §ã§ããå¿ è¦ãããã®ã§ããã¡ã¤ã«ãªãã»ããã®å¤ããã¡ã¤ã«ã«æ¸ãè¾¼ã¾ããå¿ è¦ãããã¾ãã
ä»åã¯ãmalloc å®è£ å é¨ã§ã®ãä»®æ³ã¡ã¢ãªã¢ãã¬ã¹ã¨ãã¡ã¤ã«ãªãã»ããã®å¤æãèªåã§è¡ãããã«ãfm_ptr ãå©ç¨ãã¾ããã
ãã®çµæãã³ã¡ã³ãã¢ã¦ããé¤ãã¦ç´ 4000 è¡ã»ã©ãã ptmalloc å®è£ ã®ãã¡ã150 è¡ç¨åº¦ã®å¤æ´ã§ãå®è£ ãã¡ã¢ãªãããããã¡ã¤ã«ç¨ã«é©ç¨ã§ãã¾ããããã®ä»ãAPI ã®å®è£ ãã ããã追å ã§åè¨ 250 è¡ç¨åº¦ã«ãªãã¾ããã
fm_ptr ã®ãããã§ããã¤ã³ã¿ãå ¨ç®æã«ã¤ãã¦æä½æ¥ã§å¤æããªãã¦ããã£ãã®ã§ãã ãã¶å®è£ ã®è² æ ã軽æ¸ãããã¨æã£ã¦ãã¾ãã
API
è¤æ°ã®ã¡ã¢ãªãããããã¡ã¤ã«ãæ±ããããã«ãfm_info ã¨ããæ§é ä½ã«å¯¾ãã¦ãä¸ã¤ã®ãã¡ã¤ã«ãã²ãä»ããããã«ãã¾ããã
以ä¸ã®é¢æ°ã§ãfm_info æ§é ä½ããfilepath ã§æå®ããããã¡ã¤ã«ã«å¯¾ãã¦ã²ãä»ãã¾ãããã®é¢æ°ã¯å é¨çã« mmap ãå®è¡ãã¾ãã
struct fm_info *fmalloc_init(const char *filepath, bool *init)
次ã«ãç¾å¨ãã©ã®ã¡ã¢ãªãããããã¡ã¤ã«ã«å¯¾ãã¦ä½æ¥ãè¡ã£ã¦ããããè¨å®ããããã®ä»¥ä¸ã®é¢æ°ãå®è¡ãã¾ããããã¯ãã¾ããªãã®ãããªãã®ã§ãã
void fmalloc_set_target(struct fm_info *fi)
以ä¸ããé常㮠malloc ã¨å¤§ããç°ãªãç¹ã§ããæ®ãã® API ã¯ä»¥ä¸ã®ï¼ã¤ã§ãfmalloc ã¯ãmalloc ã¨ãffree 㯠free ã¨å¯¾å¿ããæåãããå¯ä¸ã®ç°ãªãç¹ã¨ãã¦ãã¡ã¢ãªã®ç¢ºä¿ã¨è§£æ¾ã fmalloc_set_target ã§è¨å®ããã¡ã¢ãªãããããã¡ã¤ã«ã®ä»®æ³ã¡ã¢ãªé åã®ä¸ããè¡ãã¨ããç¹ã§ãã
void *fmalloc(size_t size) void ffree(void *addr)
ãã¡ã¤ã«ä¸ã®ãã¼ã¿ã®é ç½®
æ°¸ç¶ã¹ãã¬ã¼ã¸ãæ±ãããã°ã©ã ã®ç¹å¾´ã¨ãã¦ããã¼ã¿æ§é ã®éå§ä½ç½®ãã¹ã¼ãã¼ãããã¯ã®ãããªæ±ºã¾ã£ãå ´æã«ç½®ãã¦ããã¨ãããã¨ãããã¾ãã
fmalloc ã§ã¯ã以ä¸ã®ããã«ãã¼ã¿ãé ç½®ãã¾ãã
0 4KB 8KB end |-- fm_super --|-- for app --|-- ... malloc ...--|
æåã®ï¼KBã¯ãfmalloc ç¬èªã®ãã¼ã¿ãç½®ãã¦ããã¾ãã
ï¼KBããï¼KBã¾ã§ã¯ãã¢ããªã±ã¼ã·ã§ã³ã®ããã«éãã¦ããã¾ããããã«ã¢ããªã±ã¼ã·ã§ã³ã¯ãä¾ãã°é£çµãªã¹ãã§ããã°ãé£çµãªã¹ãã®å é ã®ãã¼ããé ç½®ãããã§ãã¾ãã
ï¼KB以éã®é å㯠fmalloc ã«ãã£ã¦ç®¡çããã¾ãã
å®éã®ããã°ã©ã
以ä¸ããå®éã« fmalloc ãé©ç¨ããé£çµãªã¹ãã®å®è£ ä¾ã§ãã以ä¸ã®ããã°ã©ã ã¯ãfmalloc ã®ã¬ãã¸ããªã«ãµã³ãã«ããã°ã©ã ã¨ãã¦å«ã¾ãã¦ãã¾ãã
以ä¸ã®ããã°ã©ã ãå®è¡ããã¨ãä¸åº¦ç®ã®å®è¡ã§ãï¼ããï¼ã¾ã§ã®å¤ããã¤ãã¼ããé£çµãªã¹ãã«è¿½å ãããã¡ã¤ã«ã«ä¿åãã¾ããäºåº¦ç®ä»¥éã®å®è¡ã§ã¯ããã¡ã¤ã«ããä¿åãããé£çµãªã¹ããèªã¿åºãã¦ãï¼ããï¼ã¾ã§ã®å¤ã表示ãã¾ãã
#include <fmalloc.hpp> /* list implementation */ struct node { int val; fm_ptr<struct node> next; } __attribute__((packed)); static void list_append(struct node *head, struct node *newnode) { struct node *n = head; while (n->next) { n = n->next; } n->next = newnode; } /* app reserved super block */ struct app_super { fm_ptr<struct node> head; }; /* example append operation */ static void append_nodes(struct node *head) { int i; printf("writing list data...\n"); for (i = 0; i < 10; i++) { struct node *n = (struct node *) fmalloc(sizeof(struct node)); n->val = i; n->next = NULL; list_append(head, n); } printf("done.\n"); } /* example read operation */ static void read_nodes(struct node *head) { struct node *n = head->next; printf("reading list data...\n"); while (n) { printf("%d\n", n->val); n = n->next; } printf("done.\n"); } int main(int argc, char const* argv[]) { struct app_super *super; bool init = false; struct fm_info *fi; if (argc < 2) { printf("please specify a data file\n"); exit(1); } fi = fmalloc_init(argv[1], &init); fmalloc_set_target(fi); /* fmalloc reserves 4KB ~ 8KB for app for locating super block */ super = (struct app_super *) ((unsigned long) fi->mem + PAGE_SIZE); if (init) { super->head = (struct node *) fmalloc(sizeof(struct node)); append_nodes(super->head); } else { if (super->head) { read_nodes(super->head); } } return 0; }
é常ã®é£çµãªã¹ãã¨ç°ãªãç¹ã¯ã主ã«ä»¥ä¸ã®ï¼ç¹ã¨æããã¾ãã
1. ãã¤ã³ã¿ã fm_ptr ã§å®£è¨ãã
2. fmalloc_init ãå®è¡ãã
3. fmalloc_set_target ãå®è¡ãã
4. ã¢ããªã±ã¼ã·ã§ã³ç¨ã®ã¹ã¼ãã¼ãããã¯ã«é£çµãªã¹ãã®å
é ãé
ç½®ãã
5. ãªã¹ãã®ãã¼ã確ä¿ã®ãããmalloc ã®ä»£ããã« fmalloc ãå®è¡ãã
ãã®ããã«ãfmalloc ã使ãã¨ãã¡ã¢ãªãããããã¡ã¤ã«ã«æ¯è¼çç°¡åã«ãã¼ã¿æ§é ãä¿åã§ããããã«ãªãã¾ãã