//本人实在太懒了,没写一行注释,哈哈,没时间写,只是一个课堂练习
/
//makefile文件
OBJS=mainApp.o mini_malloc.o
malloc : mainApp.o mini_malloc.o
gcc -g -o malloc ${OBJS}
mainApp.o : mainApp.c mini_malloc.h
gcc -c -g mainApp.c
mini_malloc.o : mini_malloc.c mini_malloc.h
gcc -c -g mini_malloc.c
/
//mini_malloc.h头文件
#include <stdio.h>
#include <stdlib.h>
#define MAXMEM 100000
#define NODESIZE (sizeof(Node))
typedef unsigned int size_t;
typedef struct Node {
char _used;
struct Node *_prev;
struct Node *_next;
struct Node *_usedprev;
struct Node *_usednext;
struct Node *_freeprev;
struct Node *_freenext;
} Node;
extern Node *L;
extern char *P;
void *mini_malloc(size_t size);
void mini_free(void *addr);
/
//mainApp.c测试malloc性能,相当棒的一段测试代码,老师写的,我是看不懂了
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "mini_malloc.h"
#define MAXSIZE 0x1000
#define REPEAT 100
#define MEMPOOL 10000
#define DISPLAYMEM
typedef struct UnitTestNode {
size_t _size;
void* _ptr;
struct UnitTestNode* _next;
} UnitTestNode;
static UnitTestNode* head = NULL;
static UnitTestNode* tail = NULL;
static int mem = 0;
static int max_mem = 0;
static int count_succeed = 0;
static int count_failed = 0;
static int count_free = 0;
static double time_succeed = 0.0;
static double time_failed = 0.0;
static double time_free = 0.0;
int insert(size_t size) {
clock_t start, finish;
void* ptr = NULL;
start = clock();
ptr = mini_malloc(size);
finish = clock();
if (ptr == NULL) {
++count_failed;
time_failed += (double)(finish - start) * 1000 / CLOCKS_PER_SEC;
return 0;
}
++count_succeed;
time_succeed += (double)(finish - start) * 1000 / CLOCKS_PER_SEC;
mem += size;
if (mem > max_mem) {
max_mem = mem;
}
memset(ptr, 0xff, size);
if (tail != NULL) {
tail->_next = (UnitTestNode*)malloc(sizeof(UnitTestNode));
tail = tail->_next;
} else {
tail = (UnitTestNode*)malloc(sizeof(UnitTestNode));
head = tail;
}
tail->_size = size;
tail->_ptr = ptr;
tail->_next = NULL;
return 1;
}
void delete(void) {
clock_t start, finish;
UnitTestNode* pNode = NULL;
if(head != NULL) {
pNode = head;
head = head->_next;
if (head == NULL) {
tail = NULL;
}
start = clock();
mini_free(pNode->_ptr);
finish = clock();
++count_free;
time_free += (double)(finish - start) * 1000 / CLOCKS_PER_SEC;
mem -= pNode->_size;
free(pNode);
}
}
int blank(size_t size) {
UnitTestNode* pNode = NULL;
insert(size);
pNode = tail;
if (insert(size)) {
tail->_next = head;
head = tail;
tail = pNode;
tail->_next = NULL;
return 1;
} else {
return 0;
}
}
void print(int mark) {
#ifdef DISPLAYMEM
int i, line_max, line_step;
line_max = MEMPOOL;
line_step = 150;
printf("#%d |", mark);
for (i = 0; i < line_max; i += line_step) {
if (mem < line_max) {
if (i < mem) {
printf(".");
} else {
printf(" ");
}
} else {
if (i + line_max < mem) {
printf(":");
} else {
printf(".");
}
}
}
printf("|/n");
#endif
}
int main(int argc, char ** argv) {
int i, n;
srand(time(NULL));
// Test 0
for (i = 0; i < REPEAT * 10; ++i) {
insert(sizeof(UnitTestNode));
if (i % REPEAT == 0) {
print(0);
}
}
for (i = 0; i < REPEAT * 10; ++i) {
delete();
if (i % REPEAT == 0) {
print(0);
}
}
// Test 1
for (n = MAXSIZE; n > 0; n >>= 1) {
for (i = 0; i < REPEAT; ++i) {
if (rand() % 2) {
delete();
}
insert(n);
}
print(1);
}
for (n = 1; n <= MAXSIZE; n <<= 1) {
for (i = 0; i < REPEAT; ++i) {
if (rand() % 2) {
delete();
}
insert(n);
}
print(1);
}
// Test 2
for (n = 1; n <= MAXSIZE; n <<= 1) {
for (i = 0; i < REPEAT; ++i) {
if (rand() % 2) {
delete();
}
insert((rand() % n) + 1);
}
print(2);
}
while (head != NULL) {
delete();
}
print(2);
for (n = 1; n <= MAXSIZE; n <<= 1) {
for (i = 0; i < REPEAT; ++i) {
if (rand() % 2) {
delete();
}
insert((rand() % n) + 1);
}
print(2);
}
// Test 3
for (i = 0; i <= REPEAT * 10; ++i) {
if (rand() % 2) {
delete();
}
insert((rand() % REPEAT) + 1);
if (i % REPEAT == 0) {
print(3);
}
}
while (head != NULL) {
delete();
}
print(3);
for (i = 0; i <= REPEAT * 10; ++i) {
if (rand() % 2) {
delete();
}
insert((rand() % REPEAT) + 1);
if (i % REPEAT == 0) {
print(3);
}
}
// Test 4
while (head != NULL) {
delete();
}
print(4);
for (i = 0; i < MEMPOOL; ++i) {
if (blank(1) == 0) {
break;
}
if (i % (MEMPOOL / 12) == 0) {
print(4);
}
}
while(--i) {
delete();
}
print(4);
for (i = 0; i < REPEAT * 10; ++i) {
insert(MEMPOOL / 2);
if (i % REPEAT == 0) {
print(4);
}
}
// Test 5
for (i = 0; i <= REPEAT * 10; ++i) {
if (rand() % 4) {
delete();
}
insert(sizeof(UnitTestNode));
if (i % 60 == 0) {
print(5);
}
}
while (head != NULL) {
delete();
}
print(5);
for (i = 0; i <= MEMPOOL; ++i) {
insert(sizeof(char));
if (i % 600 == 0) {
print(5);
}
}
printf("%d times succeed malloc", count_succeed);
if (count_succeed != 0) {
printf(", which average costs %.3f ms./n", time_succeed / count_succeed);
} else {
printf("./n");
}
printf("%d times failed malloc", count_failed);
if (count_failed != 0) {
printf(", which average costs %.3f ms./n", time_failed / count_failed);
} else {
printf("./n");
}
printf("%d times free", count_free);
if (count_free != 0) {
printf(", which average costs %.3f ms./n", time_free / count_free);
} else {
printf("./n");
}
printf("%d memories used, %d memories used at the peak./n", mem, max_mem);
return 0;
}
/
//mini_malloc内存分配与释放
#include "mini_malloc.h"
extern char *P = '/0';
extern Node *L = NULL;
Node *uNode = NULL;
Node *fNode = NULL;
void DLpushfront(Node *pNode, char obj);
void DLdelete(Node **head, char obj);
void init_malloc()
{
P = (char *)malloc(MAXMEM);
L = (Node *)P;
L->_used = '/0';
L->_prev = NULL;
L->_next = NULL;
L->_usedprev = NULL;
L->_usednext = NULL;
L->_freeprev = NULL;
L->_freenext = NULL;
fNode = L;
}
void *mini_malloc(size_t size)
{
if (L == NULL)
init_malloc();
size_t fsize = 0;
Node *head = fNode;
while (head) {
if (head->_used == '/0') {
if (head->_next != NULL) {
fsize = (char *)(head->_next) - (char *)head - NODESIZE;
}
else {
fsize = P + MAXMEM - (char *)head - NODESIZE;
}
if (fsize >= size) {
head->_used = '1';
DLpushfront(head, 'u');
DLdelete(&head, 'f');
if (fsize - size > NODESIZE) {
Node *node = (Node *)((char *)head + NODESIZE + size);
node->_used = '/0';
node->_prev = head;
node->_next = NULL;
node->_freenext = NULL;
if (head->_next != NULL) {
node->_next = head->_next;
head->_next->_prev = node;
}
DLpushfront(node, 'f');
head->_next = node;
}
return (void *)((char *)head + NODESIZE);
}
}
head = head->_freenext;
}
}
void mini_free(void *addr)
{
if (uNode == NULL)
return;
Node *Used = uNode;
Node *node = NULL;
while (Used) {
if ((Node *)((char *)addr - NODESIZE) == Used) {
Used->_used = '/0';
node = Used;
DLdelete(&Used, 'u');
if (Used->_next != NULL && Used->_next->_used == '/0') {
DLdelete(&(Used->_next), 'f');
DLdelete(&(Used->_next), 'm');
}
if (Used->_prev != NULL && Used->_prev->_used == '/0') {
node = Used->_prev;
DLdelete(&node, 'f');
DLdelete(&Used, 'm');
}
DLpushfront(node, 'f');
return;
}
Used = Used->_usednext;
}
}
void DLpushfront(Node *pNode, char obj)
{
if (pNode == NULL) return;
switch (obj) {
case 'm':
if (L == NULL) {
L = pNode;
L->_prev = NULL;
L->_next = NULL;
}
else {
pNode->_next = L;
L->_prev = pNode;
L = pNode;
L->_prev = NULL;
}
break;
case 'u':
if (uNode == NULL) {
uNode = pNode;
uNode->_usedprev = NULL;
uNode->_usednext = NULL;
}
else {
pNode->_usednext = uNode;
uNode->_usedprev = pNode;
uNode = pNode;
uNode->_usedprev = NULL;
}
break;
case 'f':
if (fNode == NULL) {
fNode = pNode;
fNode->_freeprev = NULL;
fNode->_freenext = NULL;
}
else {
pNode->_freenext = fNode;
fNode->_freeprev = pNode;
fNode = pNode;
fNode->_freeprev = NULL;
}
break;
}
}
void DLdelete(Node **head, char obj)
{
if (*head == NULL) return;
Node *T = *head;
switch (obj) {
case 'm':
if (T->_prev != NULL) {
if (T->_next != NULL) {
T->_prev->_next = T->_next;
T->_next->_prev = T->_prev;
}
else
T->_prev->_next = NULL;
}
else {
printf("ERROR/n");
}
break;
case 'u':
if (T->_usedprev != NULL) {
if (T->_usednext != NULL) {
T->_usedprev->_usednext = T->_usednext;
T->_usednext->_usedprev = T->_usedprev;
}
else
T->_usedprev->_usednext = NULL;
}
else {
if (T->_usednext != NULL) {
uNode = T->_usednext;
uNode->_usedprev = NULL;
}
else
uNode = NULL;
}
break;
case 'f':
if (T->_freeprev != NULL) {
if (T->_freenext != NULL) {
T->_freeprev->_freenext = T->_freenext;
T->_freenext->_freeprev = T->_freeprev;
}
else
T->_freeprev->_freenext = NULL;
}
else {
if (T->_freenext != NULL) {
fNode = T->_freenext;
fNode->_freeprev = NULL;
}
else
fNode = NULL;
}
break;
}
}