您的位置:首页 > 其它

最佳适配内存分配算法(二)

2011-09-14 08:21 288 查看
最佳适配内存分配算法(二)

上次的blog
http://blog.csdn.net/leeshuheng/article/details/6736194
中的代码对最佳适配内存分配算法做了简单的演绎。

由于现实中程序经常分配小内存块,且常常重复分配和释放相同

大小的内存块,所以下面的代码对上述blog中代码做了如下优化,

具体内容请看后面的代码:

1. 每次free内存后,并未马上将其和临近的空闲

内存合并,而是直接插入bin中。直到free的

调用次数达到某个值,才进行内存块合并,这时

只合并大内存块;

2. 当由于没有大的空闲内存块而无法满足内存分配时,

进行空闲内存块合并,包括大内存块和小内存块

的合并;

3. 对大空闲块和小空闲块的查找做了不同处理;

4. 对锁进行了重新设计;

由于只是用于实验的原型代码,所以下面的代码存在如下问题:

1.对多进程和多线程支持的不好。

2.mem_alloc返回的是内存的偏移,而不是指针。

这主要是考虑了对共享内存的分配。

3.内存块散列的不好,大约有20个槽总是空的。

4.代码没经过仔细编写。许多代码是临时写的。

整个main.c中代码都是临时拼凑的。

代码显得凌乱,程序有bug。

5.还存在其他问题。

代码并未真正分配内存,只是在已分配的内存上作切割,是个

池式共享内存分配器。

代码在fedora 11上做了简单的测试。

编译: 使用make

执行: ./mytest 1

停止: Ctrl-C

下面是代码:

mem_alloc.h:

===========================================================

// 2011年 08月 24日 星期三 09:10:32 CST

// author: 李小丹(Li Shao Dan) 字殊恒(shuheng)

// K.I.S.S

// S.P.O.T

#ifndef MEM_ALLOC_H

#define MEM_ALLOC_H

#include <sys/ipc.h>

//#define SINGLE_PROCESS

#ifdef __cplusplus

extern "C" {

#endif

struct mem_info;

struct mem_info *mem_link_shm(key_t, size_t, int);

int mem_detach_shm(struct mem_info *);

struct mem_info *mem_init(void *, unsigned long, int);

void mem_destroy(struct mem_info *);

unsigned long mem_alloc(struct mem_info *, unsigned long);

void mem_free(struct mem_info *, unsigned long);

unsigned long mem_ptr_2_off(struct mem_info *, void *);

void *mem_off_2_ptr(struct mem_info *, unsigned long);

#ifdef __cplusplus

}

#endif

#endif

===========================================================

mem_alloc.c:

===========================================================

// 2011年 08月 24日 星期三 09:19:52 CST

// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)

// K.I.S.S

// S.P.O.T

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <assert.h>

#include <sys/shm.h>

#include "mem_alloc.h"

//#include "futex.h"

#include "mem_lock.h"

#ifdef SINGLE_PROCESS

#pragma message "not use lock"

#undef mem_lock_init

#undef mem_lock_lock

#undef mem_lock_unlock

//#undef futex_create

#define mem_lock_init(x)

#define mem_lock_lock(x)

#define mem_lock_unlock(x)

//#define futex_create(x)

#endif

#define BIN_NUMBER 128UL

#define BIN_SMALL_THRESHOLD 64

#define SIZE_SMALL_THRESHOLD 512UL

#define BIN_SIZE \

(unsigned long)(BIN_NUMBER * sizeof(unsigned long))

//#define LOW_SIZE (BIN_SIZE + sizeof(futex_t))

#define LOW_SIZE (BIN_SIZE + sizeof(mem_lock_t))

#define SMALLEST_SIZE \

((unsigned long)(sizeof(unsigned long) << 2))

#define CHAR_BIT_SHIFT 3

#define BIGBIN_SHIFT 8U

#define SMALL_SIZE_2_INDEX(x) (x >> CHAR_BIT_SHIFT)

#define BIG_SIZE_2_INDEX(s, i) \

{\

unsigned long x = s >> BIGBIN_SHIFT;\

if (x == 0)\

i = 0;\

else {\

unsigned long y = \

((unsigned long)sizeof(unsigned long)) \

* __CHAR_BIT__ - 1 - __builtin_clz(x); \

i = (int)((y << 1) + ((s >> (y + (BIGBIN_SHIFT - 1)))));\

i += BIN_SMALL_THRESHOLD; \

}\

}

#define TAG_SIZE (sizeof(unsigned long) << 1)

#define node_size(x) \

((x) & ~(1UL << ((sizeof(unsigned long) << CHAR_BIT_SHIFT) - 1)))

#define node_isused(x) \

((x) & (1UL << ((sizeof(unsigned long) << CHAR_BIT_SHIFT) - 1)))

#define node_used(x) \

((x) |= (1UL << ((sizeof(unsigned long) << CHAR_BIT_SHIFT) - 1)))

#define node_unused(x) \

((x) &= ~(1UL << ((sizeof(unsigned long) << CHAR_BIT_SHIFT) - 1)))

#define off_to_addr(x, y) ((x)->mem_block + (y))

#define off_to_node(p, off) \

(off ? (struct mem_node *)(p + off) : 0)

#define ptr_to_off(p, n) ((void *)n - (void *)p)

#define node_to_tail(p, s) \

(((void *)p) + s - sizeof(unsigned long))

#define node_tail_size(p, s) \

(*(unsigned long *)node_to_tail(p, s))

#define node_head_size(p) (*(unsigned long *)p)

#define node_prev_size(p) \

(*(unsigned long *)((void *)p - sizeof(unsigned long)))

#define node_to_next(p, s) (((void *)p) + s)

#define node_to_prev(p, n) \

((void *)n <= (void *)p + LOW_SIZE ? \

0 : ((void *)n) - node_prev_size(n))

#define node_list_next(p, node) \

(node->next ? \

(struct mem_node *)(p + node->next) : 0)

#define node_list_prev(p, node) \

(node->prev ? \

(struct mem_node *)(p + node->prev) : 0)

#define number_align(x, y) (((x) + (y) - 1) & ~((y) - 1))

#define align_8(x) number_align(x, 8)

struct mem_node {

unsigned long use_a_size;

unsigned long prev;

unsigned long next;

};

struct mem_info {

void *mem_block;

unsigned long block_size;

//futex_t *futex;

mem_lock_t *lock;

//long error;

int shmid;

unsigned long *mem_bin;

};

inline static unsigned long size_2_index(unsigned long);

inline static void __node_init(

struct mem_node *, unsigned long);

inline static int __node_insert(

struct mem_info *, unsigned long);

inline static unsigned long __node_merge(

struct mem_info *, unsigned long);

inline static unsigned long __node_merge_core(

struct mem_info *, unsigned long);

inline static unsigned long __node_merge_next(

struct mem_info *, unsigned long);

inline static int __node_can_merge_next(

struct mem_info *, unsigned long);

inline static unsigned long __node_merge_prev(

struct mem_info *, unsigned long);

inline static unsigned long __node_can_merge_prev(

struct mem_info *, unsigned long);

inline static unsigned long __node_remove(

struct mem_info *, unsigned long);

inline static unsigned long __node_split(

struct mem_info *,

unsigned long,

unsigned long);

inline static unsigned long __node_find(

struct mem_info *, unsigned long);

static struct mem_node *__node_find_min(

void *, unsigned long *, unsigned long);

#ifdef SMALL_SIZE_BOOST

static void __node_merge_all(struct mem_info *, int, int);

static struct mem_node *__node_find_low(

void *, unsigned long *, unsigned long, unsigned long);

static struct mem_node *__node_find_high(

void *, unsigned long *, unsigned long, unsigned long);

#endif

inline static unsigned long size_2_index(unsigned long s)

{

int idx;

if(s <= SIZE_SMALL_THRESHOLD)

idx = SMALL_SIZE_2_INDEX(s);

else

BIG_SIZE_2_INDEX(s, idx);

return idx;

}

static void __node_init(struct mem_node *p, unsigned long s)

{

p->use_a_size = s;

p->next = p->prev = 0;

node_tail_size(p, s) = s;

}

inline static int __node_insert(

struct mem_info *info, unsigned long off)

{

struct mem_node *p = info->mem_block + off;

p->next = p->prev = 0;

unsigned long s = node_size(p->use_a_size);

int idx = size_2_index(s);

p->next = info->mem_bin[idx];

info->mem_bin[idx] = off;

if(p->next) {

struct mem_node *next =

(struct mem_node *)

off_to_addr(info, p->next);

next->prev = off;

}

return 0;

}

inline static unsigned long __node_merge(

struct mem_info *info, unsigned long off)

{

off = __node_merge_core(info, off);

assert(off);

/*void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

node->prev = node->next = 0;*/

return off;

}

inline static unsigned long __node_merge_core(

struct mem_info *info, unsigned long off)

{

off = __node_merge_next(info, off);

off = __node_merge_prev(info, off);

return off;

}

inline static unsigned long __node_can_merge_prev(

struct mem_info *info, unsigned long off)

{

if(off >= LOW_SIZE) {

void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

//unsigned long cs = node_size(node->use_a_size);

struct mem_node *prev = node_to_prev(p, node);

void *high = p + LOW_SIZE;

if((void *)prev < high)

return 0;

return !node_isused(prev->use_a_size);

}

return 0;

}

inline static unsigned long __node_merge_prev(

struct mem_info *info, unsigned long off)

{

if(off >= LOW_SIZE) {

void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

unsigned long cs = node_size(node->use_a_size);

struct mem_node *prev = node_to_prev(p, node);

void *high = p + LOW_SIZE;

if((void *)prev < high)

return off;

if(!node_isused(prev->use_a_size)) {

unsigned long ps =

node_size(prev->use_a_size);

assert(ps);

__node_remove(info, off - ps);

unsigned long sum = cs + ps;

node_tail_size(prev, sum) = sum;

prev->use_a_size = sum;

return __node_merge_prev(info, off - ps);

}

return off;

}

assert(0);

return 0;

}

#ifdef SMALL_SIZE_BOOST

static void __node_merge_all(struct mem_info *info, int b, int e)

{

unsigned long *bin = info->mem_bin;

void *p = info->mem_block;

for(int i = b; i < e; ++i) {

for(struct mem_node *n =

off_to_node(p, bin[i]); n;) {

unsigned long off = ptr_to_off(p, n);

if(__node_can_merge_prev(info, off) ||

__node_can_merge_next(info, off)) {

__node_remove(info, off);

off = __node_merge(info, off);

__node_insert(info, off);

n = off_to_node(p, bin[i]);

} else {

n = node_list_next(p, n);

}

}

}

}

#endif

inline static int __node_can_merge_next(

struct mem_info *info, unsigned long off)

{

if(off < info->block_size) {

void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

unsigned long cs = node_size(node->use_a_size);

unsigned long hs = info->block_size;

if(off + cs >= hs)

return 0;

struct mem_node *next =

(struct mem_node *)node_to_next(

node, cs);

return !node_isused(next->use_a_size);

}

return 0;

}

inline static unsigned long __node_merge_next(

struct mem_info *info, unsigned long off)

{

if(off < info->block_size) {

void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

unsigned long cs = node_size(node->use_a_size);

unsigned long hs = info->block_size;

if(off + cs >= hs)

return off;

struct mem_node *next =

(struct mem_node *)node_to_next(

node, cs);

if(!node_isused(next->use_a_size)) {

__node_remove(info, off + cs);

unsigned long ns = node_size(

next->use_a_size);

assert(ns);

unsigned long sum = cs + ns;

node->use_a_size = sum;

node_tail_size(node, sum) = sum;

return __node_merge_next(

info, off);

}

return off;

}

assert(0);

return 0;

}

inline static unsigned long __node_remove(

struct mem_info *info, unsigned long off)

{

void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

if(node->prev) {

struct mem_node *prev =

(struct mem_node *)(p + node->prev);

prev->next = node->next;

} else {

unsigned long s = node_size(node->use_a_size);

int idx = size_2_index(s);

unsigned long *bin = info->mem_bin;

bin[idx] = node->next;

}

if(node->next) {

struct mem_node *next =

(struct mem_node *)(p + node->next);

next->prev = node->prev;

}

node->prev = node->next = 0;

return off;

}

inline static unsigned long __node_split(

struct mem_info *info,

unsigned long off,

unsigned long s)

{

void *p = info->mem_block;

struct mem_node *node =

(struct mem_node *)(p + off);

unsigned long ns = node_size(node->use_a_size);

if(s + SMALLEST_SIZE >= ns)

return off;

node->use_a_size = s;

node_tail_size(node, s) = s;

struct mem_node *next =

(struct mem_node *)node_to_next(node, s);

ns -= s;

next->use_a_size = ns;

node_tail_size(next, ns) = ns;

__node_insert(info, off + s);

return off;

}

static struct mem_node *__node_find_min(

void *p, unsigned long *bin, unsigned long s)

{

#ifdef SMALL_SIZE_BOOST

int idx = size_2_index(s);

struct mem_node *node = 0;

if(idx <= BIN_SMALL_THRESHOLD)

node = __node_find_low(p, bin, idx, s);

return (node ? node : __node_find_high(p, bin, idx, s));

#else

int idx = size_2_index(s);

struct mem_node *node, *nmin = 0;

unsigned long min, tmp;

for(unsigned i = idx; i < BIN_NUMBER; ++i) {

node = off_to_node(p, bin[i]);

if(node) min = node_size(node->use_a_size) + 1;

for(; node; node = node_list_next(p, node)) {

tmp = node_size(node->use_a_size);

if(tmp >= s && tmp < min) {

nmin = node;

min = tmp;

}

}

if(nmin)

return nmin;

}

return 0;

#endif

}

#ifdef SMALL_SIZE_BOOST

static struct mem_node *__node_find_high(

void *p, unsigned long *bin, unsigned long idx, unsigned long s)

{

//int idx = size_2_index(s);

struct mem_node *node, *nmin = 0;

unsigned long min, tmp;

for(unsigned i = idx; i < BIN_NUMBER; ++i) {

node = off_to_node(p, bin[i]);

if(node) min = node_size(node->use_a_size) + 1;

for(; node; node = node_list_next(p, node)) {

tmp = node_size(node->use_a_size);

if(tmp >= s && tmp < min) {

nmin = node;

min = tmp;

}

}

if(nmin)

return nmin;

}

return 0;

}

static struct mem_node *__node_find_low(

void *p, unsigned long *bin, unsigned long idx, unsigned long s)

{

//int idx = size_2_index(s);

struct mem_node *node;

for(unsigned long i = idx; i <= BIN_SMALL_THRESHOLD; ++i) {

for(node = off_to_node(p, bin[i]); node;

node = node_list_next(p, node)) {

if(node_size(node->use_a_size) >= s)

return node;

}

}

return 0;

}

#endif

// XXX hot spot

inline static unsigned long __node_find(

struct mem_info *info, unsigned long s)

{

unsigned long *bin = info->mem_bin;

void *p = info->mem_block;

struct mem_node *node;

#ifdef SMALL_SIZE_BOOST

int m = 2;

while(m){

#endif

if((node = __node_find_min(p, bin, s))) {

unsigned long ret = (void *)node - p;

unsigned long ns = node_size(node->use_a_size);

__node_remove(info, ret);

if(ns > s)

ret = __node_split(info, ret, s);

return ret;

}

//break;

#ifdef SMALL_SIZE_BOOST

if(--m) __node_merge_all(info, 0, (int)BIN_NUMBER);

//printf("%s: %s: %d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);

}

#endif

return 0;

}

unsigned long mem_alloc(struct mem_info *info, unsigned long s)

{

if(!s) return 0;

if((s = align_8(s + TAG_SIZE)) < SMALLEST_SIZE)

s = SMALLEST_SIZE;

unsigned long off;

//futex_lock(info->futex);

mem_lock_lock(info->lock);

if(!(off = __node_find(info, s))) {

//futex_unlock(info->futex);

mem_lock_unlock(info->lock);

return 0;

}

struct mem_node *node =

off_to_node(info->mem_block, off);

node_used(node->use_a_size);

//futex_unlock(info->futex);

mem_lock_unlock(info->lock);

return off + sizeof(unsigned long);

}

void mem_free(struct mem_info *info, unsigned long off)

{

off -= sizeof(unsigned long);

assert(off >= LOW_SIZE);

assert(off < info->block_size);

struct mem_node *node =

off_to_node(info->mem_block, off);

//futex_lock(info->futex);

mem_lock_lock(info->lock);

node_unused(node->use_a_size);

//node->prev = node->next = 0;

#ifndef SMALL_SIZE_BOOST

off = __node_merge(info, off);

#endif

__node_insert(info, off);

#ifdef SMALL_SIZE_BOOST

static int count = 0;

if(++count == 70) {

count = 0;

//printf("%s: %s: %d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);

__node_merge_all(info, BIN_SMALL_THRESHOLD, (int)BIN_NUMBER);

}

#endif

//futex_unlock(info->futex);

mem_lock_unlock(info->lock);

}

struct mem_info *mem_init(void *p, unsigned long s, int b)

{

if(s < LOW_SIZE + SMALLEST_SIZE)

return 0;

struct mem_info *info =

(struct mem_info *)

malloc(sizeof(struct mem_info));

//info->futex = (futex_t *)p;

info->lock = (mem_lock_t *)p;

//info->mem_bin = (unsigned long *)(p + sizeof(futex_t));

info->mem_bin = (unsigned long *)(p + sizeof(mem_lock_t));

info->mem_block = p;

info->block_size = s;

//info->error = 0;

info->shmid = -1;

//futex_create();

if(b) {

//futex_init(info->lock);

mem_lock_init(info->lock);

//futex_lock(info->futex);

mem_lock_lock(info->lock);

memset(info->mem_bin, 0, BIN_SIZE);

struct mem_node *node =

(struct mem_node *)(p + LOW_SIZE);

__node_init(node, info->block_size - LOW_SIZE);

__node_insert(info, LOW_SIZE);

//futex_unlock(info->futex);

mem_lock_unlock(info->lock);

}

return info;

}

void mem_destroy(struct mem_info *info)

{

//futex_lock(info->futex);

mem_lock_lock(info->lock);

if(info->shmid >= 0)

shmctl(info->shmid, IPC_RMID, 0);

free(info);

//futex_unlock(info->futex);

mem_lock_unlock(info->lock);

}

struct mem_info *mem_link_shm(key_t key, size_t s, int init)

{

int mid;

s += LOW_SIZE + SMALLEST_SIZE;

s = align_8(s);

if((mid = shmget(key, s, IPC_CREAT | 0666)) < 0) {

perror("shmget");

return 0;

}

void *p;

if((p = shmat(mid, 0, 0)) == (void *)-1) {

perror("shmat");

return 0;

}

struct mem_info *info =

mem_init(p, (unsigned long)s, init);

assert(info);

info->shmid = mid;

return info;

}

int mem_detach_shm(struct mem_info *info)

{

if(shmdt(info->mem_block)) {

perror("shmdt");

return -1;

}

return 0;

}

void *mem_off_2_ptr(struct mem_info *info, unsigned long off)

{

if(off >= LOW_SIZE)

return info->mem_block + off;

return 0;

}

unsigned long mem_ptr_2_off(struct mem_info *info, void *p)

{

unsigned long off;

if((off = p - info->mem_block) >= LOW_SIZE)

return off;

return 0;

}

===========================================================

mem_lock.h:

===========================================================

// 2011年 09月 13日 星期二 10:43:03 CST

// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)

// K.I.S.S

// S.P.O.T

#ifndef MEM_LOCK_H

#define MEM_LOCK_H

#include <unistd.h>

#include <sched.h>

#include <sys/syscall.h>

typedef struct __mem_lock {

unsigned long tid;

unsigned long lock;

} mem_lock_t;

inline static int mem_lock_init(mem_lock_t *);

inline static int mem_lock_lock(mem_lock_t *);

inline static int mem_lock_unlock(mem_lock_t *);

inline static int mem_lock_init(mem_lock_t *lk)

{

lk->tid = 0;

lk->lock = 0;

return 0;

}

#define SPIN_YIELD_INTERVAL 31U

inline static int mem_lock_lock(mem_lock_t *lk)

{

pid_t now = syscall(SYS_gettid);

pid_t old =

(pid_t)__sync_and_and_fetch(&lk->tid, ~0UL);

//if(__sync_bool_compare_and_swap(

// &lk->tid, now, now))

if(old == now)

return 1;

int c = 0;

while(__sync_lock_test_and_set(

&lk->lock, 1)) {

if(!(++c & SPIN_YIELD_INTERVAL))

sched_yield();

}

lk->tid = (unsigned long)now;

return 0;

}

inline static int mem_lock_unlock(mem_lock_t *lk)

{

unsigned long now =

(unsigned long)syscall(SYS_gettid);

unsigned long old =

__sync_and_and_fetch(&lk->tid, ~0UL);

//if(!__sync_bool_compare_and_swap(

// &lk->tid, now, now))

if(old != now)

return -1;

lk->tid = 0;

__sync_lock_release(&lk->lock);

return 0;

}

#endif

===========================================================

main.c:

===========================================================

// 2011年 08月 26日 星期五 10:17:33 CST

// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)

// K.I.S.S

// S.P.O.T

#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

#include <time.h>

#include <signal.h>

#include <string.h>

#include <unistd.h>

#include <pthread.h>

#include "mem_alloc.h"

#include "mem_lock.h"

//#ifndef SINGLE_PROCESS

#define BUF_SIZE (0x1FFFFFUL << 1)

//#else

//#define BUF_SIZE 0xFFFFFUL

//#endif

struct mem_info *info;

static void sig_handle(int);

void *do_work(void *);

int main(int argc, char *argv[])

{

if(argc != 2)

exit(1);

struct sigaction sa;

memset(&sa, 0, sizeof(sa));

sa.sa_handler = sig_handle;

sigemptyset(&sa.sa_mask);

if(sigaction(SIGINT, &sa, 0) < 0) {

perror("sigaction");

exit(1);

}

srand(time(0));

unsigned long as = BUF_SIZE;

//void *p = malloc(as);

key_t key = ftok("./main.c", 0);

info = mem_link_shm(key, as, atoi(argv[1]));

#ifndef SINGLE_PROCESS

pthread_t tid;

pthread_create(&tid, 0, do_work, (void *)0);

#endif

//info = mem_init(p, as, 1);

assert(info);

unsigned long p1, p2, p3, p4;

unsigned long s1, s2, s3;

p1 = mem_alloc(info, 524288);

assert(p1);

char *ptr4[4];

// not free

unsigned long h1 = mem_alloc(info, 12);

ptr4[0] = mem_off_2_ptr(info, h1);

strcpy(ptr4[0], "hello,world");

////////////////////////////////////

p2 = mem_alloc(info, 8192);

assert(p2);

// not free

unsigned long h2 = mem_alloc(info, 12);

ptr4[1] = mem_off_2_ptr(info, h2);

strcpy(ptr4[1], "hello,world");

//////////////////////////////////////////

p3 = mem_alloc(info, 32768);

assert(p3);

// not free

unsigned long h3 = mem_alloc(info, 12);

ptr4[2] = mem_off_2_ptr(info, h3);

strcpy(ptr4[2], "hello,world");

/////////////////////////////////////

p4 = mem_alloc(info, 65535);

assert(p4);

// not free

unsigned long h4 = mem_alloc(info, 12);

ptr4[3] = mem_off_2_ptr(info, h4);

strcpy(ptr4[3], "hello,world");

///////////////////////////////////////

void *ppp = mem_off_2_ptr(info, p1);

unsigned long pp1 = mem_ptr_2_off(info, ppp);

assert(pp1 == p1);

mem_free(info, p1);

mem_free(info, p2);

mem_free(info, p3);

mem_free(info, p4);

int count = 0;

time_t cur, last = time(0);

for(;;) {

while(!(s1 = rand() % 524288)) ;

while(!(s2 = rand() % 8192)) ;

p1 = mem_alloc(info, s1);

p2 = mem_alloc(info, s2);

assert(p1);

assert(p2);

if(s1 > 16) {

char *ppp = mem_off_2_ptr(info, p1);

strcpy(ppp, "hello,world");

//printf("%s\n", ppp);

}

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s1, p1);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s2, p2);

mem_free(info, p2);

mem_free(info, p1);

while(!(s1 = rand() % 32)) ;

while(!(s2 = rand() % 65535)) ;

p1 = mem_alloc(info, s1);

p2 = mem_alloc(info, s2);

assert(p1);

assert(p2);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s1, p1);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s2, p2);

mem_free(info, p2);

while(!(s3 = rand() % 4096)) ;

p3 = mem_alloc(info, s3);

assert(p3);

unsigned long pp[100];

for(int i = 0; i < 100; ++i) {

while(!(s3 = rand() % 4096)) ;

//while(!(s3 = rand() % 409)) ;

pp[i] = mem_alloc(info, s3);

assert(pp[i]);

/*if(s3 > 16) {

char *ppp = mem_off_2_ptr(info, pp[i]);

strcpy(ppp, "hello,world");

//printf("%s\n", ppp);

}*/

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s3, pp[i]);

}

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s3, p3);

mem_free(info, p3);

mem_free(info, p1);

//while(!(s1 = rand() % 524288)) ;

while(!(s1 = rand() % 124288)) ;

while(!(s2 = rand() % 64)) ;

while(!(s3 = rand() % 32768)) ;

p1 = mem_alloc(info, s1);

p2 = mem_alloc(info, s2);

p3 = mem_alloc(info, s3);

assert(p1);

assert(p2);

assert(p3);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s1, p1);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s2, p2);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s3, p3);

mem_free(info, p2);

mem_free(info, p3);

for(int i = 99; i >= 0; --i)

mem_free(info, pp[i]);

mem_free(info, p1);

//static int aaaaaaa = 0;

if(++count == 100000) {

cur = time(0);

printf("XXX: %lu\n", cur - last);

for(int i = 0; i < 4; ++i)

printf("%s\n", ptr4[i]);

count = 0;

last = cur;

/*if(++aaaaaaa == 3)

exit(0);*/

}

}

return 0;

}

static void sig_handle(int s)

{

printf("\ntid is %ld\n", syscall(SYS_gettid));

psignal(s, "\ndestroy shared memory");

mem_destroy(info);

exit(0);

}

void *do_work(void *p)

{

int mi = (int)p;

unsigned long as = BUF_SIZE;

//void *p = malloc(as);

key_t key = ftok("./main.c", 0);

info = mem_link_shm(key, as, mi);

//info = mem_init(p, as, 1);

assert(info);

unsigned long p1, p2, p3, p4;

unsigned long s1, s2, s3;

p1 = mem_alloc(info, 524288);

assert(p1);

char *ptr4[4];

// not free

unsigned long h1 = mem_alloc(info, 12);

ptr4[0] = mem_off_2_ptr(info, h1);

strcpy(ptr4[0], "hello,world");

////////////////////////////////////

p2 = mem_alloc(info, 8192);

assert(p2);

// not free

unsigned long h2 = mem_alloc(info, 12);

ptr4[1] = mem_off_2_ptr(info, h2);

strcpy(ptr4[1], "hello,world");

//////////////////////////////////////////

p3 = mem_alloc(info, 32768);

assert(p3);

// not free

unsigned long h3 = mem_alloc(info, 12);

ptr4[2] = mem_off_2_ptr(info, h3);

strcpy(ptr4[2], "hello,world");

/////////////////////////////////////

p4 = mem_alloc(info, 65535);

assert(p4);

// not free

unsigned long h4 = mem_alloc(info, 12);

ptr4[3] = mem_off_2_ptr(info, h4);

strcpy(ptr4[3], "hello,world");

///////////////////////////////////////

void *ppp = mem_off_2_ptr(info, p1);

unsigned long pp1 = mem_ptr_2_off(info, ppp);

assert(pp1 == p1);

mem_free(info, p1);

mem_free(info, p2);

mem_free(info, p3);

mem_free(info, p4);

int count = 0;

time_t cur, last = time(0);

for(;;) {

while(!(s1 = rand() % 524288)) ;

while(!(s2 = rand() % 8192)) ;

p1 = mem_alloc(info, s1);

p2 = mem_alloc(info, s2);

assert(p1);

assert(p2);

if(s1 > 16) {

char *ppp = mem_off_2_ptr(info, p1);

strcpy(ppp, "hello,world");

//printf("%s\n", ppp);

}

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s1, p1);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s2, p2);

mem_free(info, p2);

mem_free(info, p1);

while(!(s1 = rand() % 32)) ;

while(!(s2 = rand() % 65535)) ;

p1 = mem_alloc(info, s1);

p2 = mem_alloc(info, s2);

assert(p1);

assert(p2);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s1, p1);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s2, p2);

mem_free(info, p2);

while(!(s3 = rand() % 4096)) ;

p3 = mem_alloc(info, s3);

assert(p3);

unsigned long pp[100];

for(int i = 0; i < 100; ++i) {

while(!(s3 = rand() % 4096)) ;

//while(!(s3 = rand() % 409)) ;

pp[i] = mem_alloc(info, s3);

assert(pp[i]);

if(s3 > 16) {

char *ppp = mem_off_2_ptr(info, pp[i]);

strcpy(ppp, "hello,world");

//printf("%s\n", ppp);

}

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s3, pp[i]);

}

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s3, p3);

mem_free(info, p3);

mem_free(info, p1);

//while(!(s1 = rand() % 524288)) ;

while(!(s1 = rand() % 124288)) ;

while(!(s2 = rand() % 64)) ;

while(!(s3 = rand() % 32768)) ;

p1 = mem_alloc(info, s1);

p2 = mem_alloc(info, s2);

p3 = mem_alloc(info, s3);

assert(p1);

assert(p2);

assert(p3);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s1, p1);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s2, p2);

// printf("%d XXX: size: %lu, offset: %lu\n", __LINE__, s3, p3);

mem_free(info, p2);

mem_free(info, p3);

for(int i = 99; i >= 0; --i)

mem_free(info, pp[i]);

mem_free(info, p1);

//static int aaaaaaa = 0;

if(++count == 100000) {

cur = time(0);

printf("XXX: %lu\n", cur - last);

for(int i = 0; i < 4; ++i)

printf("%s\n", ptr4[i]);

count = 0;

last = cur;

/*if(++aaaaaaa == 3)

exit(0);*/

}

}

return (void *)0;

}

===========================================================

makefile:

===========================================================

mod=SMALL_SIZE_BOOST

proc=SINGLE_PROCESS

mytest: main.c mem_alloc.c mem_alloc.h mem_lock.h

gcc -std=c99 -O2 -g -W -Wall -Wextra -D_GNU_SOURCE -D$(mod) -o $@ main.c mem_alloc.c -lpthread

.PHONY:clean

clean:

-rm -rf mytest

===========================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: