#include"xylib/xiuye"
#include<sys/types.h>
#include<unistd.h>
#include<cstdio>
using namespace xiuye;
#define align4(x) (((((x)-1)>>2)<<2)+4)
#define align8(x) (((((x)-1)>>3)<<3)+8)
#define ptr_size sizeof(size_t)
#define align(x) (((((x)-1)/ptr_size)*ptr_size)+ptr_size)
typedef unsigned char byte;
typedef struct s_block *t_block;
struct s_block{
size_t size;
t_block prev;
t_block next;
int free;
void *ptr;
// byte data[1];
};
#define BLOCK_SIZE sizeof(struct s_block)
/* Of course , update the BLOCK_SIZE macro */
// # define BLOCK_SIZE 12 /* 3*4 ... */
void *base = NULL;
t_block get_block(void*p){
// byte *tmp = (byte)p;
// return (p = tmp -= BLOCK_SIZE);
return (t_block)p - 1;
}
int valid_addr(void *p){
if(base){
if(p>base && p<sbrk(0)/*last break ptr*/){
return p == get_block(p)->ptr;
}
}
return 0;
}
t_block find_block(t_block *last,size_t size){
t_block b = (t_block)base;
while(b&&!(b->free&&b->size>=size)){
*last = b;
b = b->next;
}
return b;
}
t_block extend_heap(t_block last,size_t s){
t_block b = (t_block)sbrk(0);
if(sbrk(BLOCK_SIZE+s) == (void*)-1){
return NULL;
}
b->size = s;
b->next = NULL;
b->prev = last;
b->ptr = b+1;//block + data,so +1
if(last){
last->next = b;
}
b->free = 0;
return b;
}
void split_block(t_block b,size_t s){
// n = (t_block)(b->data+s);
t_block new_block = (t_block)(b+1+s);
new_block->size = b->size-s-BLOCK_SIZE;
new_block->next = b->next;
new_block->prev = b;
new_block->free = 1;
new_block->ptr = new_block+1;
b->size = s;
b->next = new_block;
if(new_block->next){
new_block->next->prev = new_block;
}
}
void *malloc(size_t size){
t_block b,last;
size_t s;
s = align(size);
if(base){
last = (t_block)base;
b = find_block(&last,s);
if(b){
if((b->size-s) >= (BLOCK_SIZE+ptr_size)){
split_block(b,s);
}
b->free = 0;
}
else{
b = extend_heap(last,s);
if(!b){
return NULL;
}
}
}else{
b = extend_heap(NULL,s);
if(!b){
return NULL;
}
base = b;
}
return b+1;
// void *p;
// p = sbrk(0);
// if(sbrk(size) == (void*)-1){
// return NULL;
// }
// return p;
}
void *calloc(size_t number,size_t size){
size_t *new_ptr;
size_t s,i;
new_ptr = (size_t*)malloc(number*size);
if(new_ptr){
s = align(number*size)/ptr_size;
for(i=0;i<s;i++){
new_ptr[i] = 0;
}
}
return new_ptr;
}
t_block fushion(t_block b){
if(b->next && b->next->free){
b->size += BLOCK_SIZE+b->next->size;
b->next = b->next->next;
if(b->next){
b->next->prev = b;
}
}
return b;
}
void free(void *p){
t_block b;
if(valid_addr(p)){
b = get_block(p);
b->free = 1;
if(b->prev && b->prev->free){
b = fushion(b->prev);
}
if(b->next){
fushion(b);
}
else{
if(b->prev){
b->prev->next = NULL;
}
else{
base = NULL;
}
brk(b);
}
}
}
void copy_block(t_block src,t_block dst){
size_t *sdata,*ddata;
size_t i;
sdata = (size_t*)src->ptr;
ddata = (size_t*)dst->ptr;
for(i=0;i*ptr_size<src->size && i*ptr_size<dst->size;i++){
ddata[i] = sdata[i];
}
}
void out_ptr_block(void *p){
t_block q = get_block(p);
println("block:",q,"size:",q->size,"prev:",q->prev,"next:",q->next,"free",q->free,"ptr:",q->ptr);
}
int main(){
//估计和 标准库 malloc filename 冲突了等原因!
//不能用
// line(111111);
printf("%d\n",BLOCK_SIZE);
printf("int:%d\n",sizeof(int));
printf("t_block:%d\n",sizeof(t_block));
printf("s_block:%d\n",sizeof(struct s_block));
char s[1];
printf("char s[1] s:%d\n",sizeof(s));
printf("long:%d\n",sizeof(long));
println(align4(1),align4(2),align4(3),align4(4),align4(5));
println(sizeof(size_t));
s_block b;
println(sizeof(b.size),sizeof(b.next),sizeof(b.free));
println(align(1),align(2),align(3),align(4),align(5)/8);
int *p1;
println(p1,p1+1,p1+2);
char s1[1];
char s2[10];
println(sizeof(s1),sizeof(s2));
int *p = (int*)malloc(sizeof(int));
out_ptr_block(p);
println(p,*p);
*p = 100;
println(p,*p);
free(p);
out_ptr_block(p);
int *pa = (int*)calloc(10,sizeof(int));
out_ptr_block(pa);
// for(int i=0;i<10;i++){
// println(i,pa[i],sizeof(pa[i]),sizeof(pa));
// }
println(pa);
free(pa);
out_ptr_block(pa);
return 0;
}
40
int:4
t_block:8
s_block:40
char s[1] s:1
long:8
4 4 4 4 8
8
8 8 4
8 8 8 8 1
0 0x4 0x8
1 10
block: 0x21cec28 size: 8 prev: 0x21bd000 next: 0 free 0 ptr: 0x21cec50
0x21cec50 0
0x21cec50 100
block: 0x21cec28 size: 8 prev: 0x21bd000 next: 0 free 1 ptr: 0x21cec50
block: 0x21cec28 size: 40 prev: 0x21bd000 next: 0 free 0 ptr: 0x21cec50
0x21cec50
block: 0x21cec28 size: 40 prev: 0x21bd000 next: 0 free 1 ptr: 0x21cec50