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));
}