malloc.c準系統完成. 啟用磁碟重組函數的時候回出現吐核現象,目前原因不明,這種動態隨機的故障十分難於調試,今天估計就只能進行到這步. 沒有採用我之前設想的任何一種方案,那些方案都太過繁雜,而是使用簡單的最佳適配法,釋放的時候有一個向後的磁碟重組,只能整理後面部分,前面部分不能整理,在malloc中,找不到滿足需求的塊後先進行磁碟重組,就是這個磁碟重組開啟,就有機率吐核.不開啟我懷疑free裡面的磁碟重組也有機率吐核,只是機率小於malloc裡面開啟的.動態問題太難於調試了.
/* malloc.c */
/* * * *///#include <vm/mm.h>//#include <vm/malloc.h>#include "malloc.h"extern unsigned long get_free_page(void);#include <stddef.h>static mlT mmlist= {0,NULL,NULL,FREE};mlTp mmList = &mmlist;/* 遞迴,遞迴果然好用*/mlTp add(mlTp mmList,mlTp mm){ if(mmList == NULL){ mm->root = NULL; mm->next = NULL; return mm; } else if(mmList->size >= mm->size){ mm->root = mmList->root; mmList->root = mm; mm->next = mmList; return mm; } else{ mmList->next = add(mmList->next,mm); mmList->next->root = mmList; } return mmList;}mlTp find(mlTp mmList,unsigned long size){ while(mmList != NULL){ if(mmList->size >= size) break; mmList = mmList->next; } return mmList;}mlTp del(mlTp mm){ if(mm != NULL){ mm->root->next = mm->next; if(mm->next != NULL) mm->next->root = mm->root; } return mm;}mlTp unite(mlTp mm){ if(mm != NULL){ mlTp nextm = (void *)mm + mm->size + sizeof(mlT); //如果mm和nextm在一個頁面,並且nextm空閑,則合并mm,nextm if(((unsigned long)nextm>>12) == ((unsigned long)mm>>12)) if(nextm->state == FREE){ del(nextm); printf("\n====== A:%p S:%lx ST:%d =====\n",nextm,nextm->size,nextm->state); printf("\n====== A:%p S:%lx ST:%d =====\n",mm,mm->size,mm->state); mm->size += nextm->size + sizeof(mlT); } } return mm;}mlTp clean(mlTp mmList){ mlTp mm = mmList->next; mlTp nextm = NULL; while(mm != NULL){ nextm = mm->next; del(mm); mm = unite(mm); mmList = add(mmList,mm); mm = nextm; } return mmList;}void *Mymalloc(unsigned long size){ mlTp mm = NULL; //4的倍數分配大小 size = ((size+3)>>2)<<2; if(NULL == (mm = find(mmList,size))){ mmList = clean(mmList); while(NULL == (mm = find(mmList,size))){ mlTp nm = NULL; //new memory nm = (void *)get_free_page(); if(nm == NULL) return NULL; nm->next = NULL; nm->root = NULL; nm->state = FREE; nm->size = (1<<12) - sizeof(mlT); mmList = add(mmList,nm); } } del(mm); if(mm->size >=(size + 4 + sizeof(mlT))){ mlTp nm = (void *)mm + size + sizeof(mlT); nm->state = FREE; nm->root = NULL; nm->size = mm->size - size -sizeof(mlT); mmList = add(mmList,nm); mm->size = size; } mm->state = BUSY; return (void *)mm + sizeof(mlT);}void Myfree(void *p){ mlTp mm = NULL; mlTp nextm = NULL; if(p != NULL){ mm = p - sizeof(mlT); mm = unite(mm); mm->state = FREE; mmList = add(mmList,mm); }}
/* malloc.h */
/* * 2011-12-9 */#ifndef __MALLOC_H__#define __MALLOC_H__typedef struct mnode{ unsigned long size; struct mnode *next; struct mnode *root; enum{ FREE = 0, BUSY = 1, }state;}mlT,*mlTp;extern void *Mymalloc(unsigned long size);void Myfree(void *p);#endif
下面是一個測試函數
/* test.c */
#include <stdio.h>#include "malloc.h"#include <stdlib.h>#include <time.h>extern mlTp mmList;unsigned long get_free_page(void){ return (((unsigned long)malloc(1<<13) + 0xfff)>>12)<<12;}int showMMap(mlTp mm){ if(mm != NULL){ printf("{A:%lX,S:%lX,R:%lx} \e[33m->\e[00m ",(long)mm,mm->size,(unsigned long)mm->root); return showMMap(mm->next)+1; } return 0;}int showM(void *p){ if(p != NULL){ mlTp mm = p - sizeof(mlT); printf("\n\e[35m{ A:%p S:%lx ST:%d}\e[0m\n",mm,mm->size,mm->state); } return 0;}int main(void){ void *p[10] = {NULL}; srand(time(NULL)); for(int i = 0;i<10000;i++){ int size = rand()%1000+1; size = ((size + 3)>>2)<<2; p[rand()%10] = Mymalloc(size); //printf("\e[31m\n--%x\n\e[00m",size); //showMMap(mmList); //printf("NULL\n"); if(!(i%3)){ int n = rand()%10; // showM(p[n]); Myfree(p[n]); p[n] = NULL; // showMMap(mmList); } } printf("NULL\nE:%x\n",showMMap(mmList));}