glibc ptmalloc中的宏操作
来源:互联网 发布:淘宝劵 编辑:程序博客网 时间:2024/05/02 04:37
glibc ptmalloc很有意思的宏操作:
1.MORECORE
__default_morecore是一个函数声明。morecore是一个函数类型定义。
MORECORE是一个对函数类型的宏定义。
例如MORECORE(1000);就等于调用函数__default_morecore(1000);
如果没有定义MORECORE,那么那就是sbrk函数的宏定义。
2. brk & sbrk
3. malloc_chunk结构体
chunk <=> mem的转换
4. 求结构体某成员的偏移量
其实它求得的就是16,因为fd_nextsize变量的偏移量是16.
5. 将请求的内存大小转成chunk对其的内存量
注意,这里只是多申请了一个size_sz,就是chunk size的4个字节。
MALLOC_ALIGN_MASK = 8 - 1 = 7,后面计算时将(req+size_sz) up align to 8的倍数。
6. 最低三位的设置与判断
4个字节的size域,共可以存储最大2^32的chunk size内存量,最低3位可以用来存储下面三个域,于是chunk size总是8的倍数。
所以如果要获取chunk size,只需要将这个4字节的数作如下操作就可以了:
以及获取它前后2个chunk的头指针
下面的宏操作才是获取当前chunk的是否是free状态
由chunk头地址来得到这个chunk来自于哪个分配区:
1.MORECORE
/* Definition for getting more memory from the OS. */#define MORECORE (*__morecore)#define MORECORE_FAILURE 0void * __default_morecore (ptrdiff_t);void *(*__morecore)(ptrdiff_t) = __default_morecore;
__default_morecore是一个函数声明。morecore是一个函数类型定义。
MORECORE是一个对函数类型的宏定义。
例如MORECORE(1000);就等于调用函数__default_morecore(1000);
#ifndef MORECORE#define MORECORE sbrk#endif
如果没有定义MORECORE,那么那就是sbrk函数的宏定义。
2. brk & sbrk
int__brk (void *addr){ void *__unbounded newbrk; INTERNAL_SYSCALL_DECL (err); newbrk = (void *__unbounded) INTERNAL_SYSCALL (brk, err, 1, __ptrvalue (addr)); __curbrk = newbrk; if (newbrk < addr) { __set_errno (ENOMEM); return -1; } return 0;}void *__sbrk (intptr_t increment){ void *oldbrk; /* If this is not part of the dynamic library or the library is used via dynamic loading in a statically linked program update __curbrk from the kernel's brk value. That way two separate instances of __brk and __sbrk can share the heap, returning interleaved pieces of it. */ if (__curbrk == NULL || __libc_multiple_libcs) if (__brk (0) < 0) /* Initialize the break. */ return (void *) -1; if (increment == 0) return __curbrk; oldbrk = __curbrk; if ((increment > 0 ? ((uintptr_t) oldbrk + (uintptr_t) increment < (uintptr_t) oldbrk) : ((uintptr_t) oldbrk < (uintptr_t) -increment)) || __brk (oldbrk + increment) < 0) return (void *) -1; return oldbrk;}
3. malloc_chunk结构体
struct malloc_chunk { INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; /* Only used for large blocks: pointer to next larger size. */ struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */ struct malloc_chunk* bk_nextsize;};
chunk <=> mem的转换
#define chunk2mem(p) ((void*)((char*)(p) + 2*SIZE_SZ))#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
4. 求结构体某成员的偏移量
#define offsetof(Type, Member) ((size_t) &((Type *) NULL)->Member)#define MIN_CHUNK_SIZE (offsetof(struct malloc_chunk, fd_nextsize))
其实它求得的就是16,因为fd_nextsize变量的偏移量是16.
5. 将请求的内存大小转成chunk对其的内存量
#define request2size(req) \ (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \ MINSIZE : \ ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
注意,这里只是多申请了一个size_sz,就是chunk size的4个字节。
MALLOC_ALIGN_MASK = 8 - 1 = 7,后面计算时将(req+size_sz) up align to 8的倍数。
6. 最低三位的设置与判断
4个字节的size域,共可以存储最大2^32的chunk size内存量,最低3位可以用来存储下面三个域,于是chunk size总是8的倍数。
/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */#define PREV_INUSE 0x1/* extract inuse bit of previous chunk */#define prev_inuse(p) ((p)->size & PREV_INUSE)/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */#define IS_MMAPPED 0x2/* check for mmap()'ed chunk */#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained from a non-main arena. This is only set immediately before handing the chunk to the user, if necessary. */#define NON_MAIN_ARENA 0x4/* check for chunk from non-main arena */#define chunk_non_main_arena(p) ((p)->size & NON_MAIN_ARENA)
所以如果要获取chunk size,只需要将这个4字节的数作如下操作就可以了:
#define SIZE_BITS (PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA)/* Get size, ignoring use bits */#define chunksize(p) ((p)->size & ~(SIZE_BITS))
以及获取它前后2个chunk的头指针
/* Ptr to next physical malloc_chunk. */#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~SIZE_BITS) ))/* Ptr to previous physical malloc_chunk */#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
下面的宏操作才是获取当前chunk的是否是free状态
/* extract p's inuse bit */#define inuse(p)\((((mchunkptr)(((char*)(p))+((p)->size & ~SIZE_BITS)))->size) & PREV_INUSE)/* set/clear chunk as being inuse without otherwise disturbing */#define set_inuse(p)\((mchunkptr)(((char*)(p)) + ((p)->size & ~SIZE_BITS)))->size |= PREV_INUSE#define clear_inuse(p)\((mchunkptr)(((char*)(p)) + ((p)->size & ~SIZE_BITS)))->size &= ~(PREV_INUSE)
由chunk头地址来得到这个chunk来自于哪个分配区:
#define heap_for_ptr(ptr) \ ((heap_info *)((unsigned long)(ptr) & ~(HEAP_MAX_SIZE-1)))#define arena_for_chunk(ptr) \ (chunk_non_main_arena(ptr) ? heap_for_ptr(ptr)->ar_ptr : &main_arena)
- glibc ptmalloc中的宏操作
- glibc 内存池管理 ptmalloc
- glibc 内存池管理 ptmalloc(转)
- [转]glibc 内存池管理 ptmalloc
- glibc 内存池管理 ptmalloc(转)
- glibc(ptmalloc)内存暴增问题解决
- glibc内存管理模块ptmalloc架构透析
- glibc内存管理ptmalloc底层实现
- glibc(ptmalloc)内存暴增问题解决 (转)
- ptmalloc
- ptmalloc
- ptmalloc
- ptmalloc
- ptmalloc
- ptmalloc
- ptmalloc
- ptmalloc
- ptmalloc
- hdu 1025 Constructing Roads In JGShining's Kingdom【即求最长上升子序列】
- JSP内置对象
- 【javaWeb】Struts 2导出excel文件
- 为产品赋予人格 - 情感化设计的组成要素及实践案例
- oracle中的connect by prior ... start with 数据库的递归算法
- glibc ptmalloc中的宏操作
- 截断表 TRUNCATE
- “IT程序猿是怎么练成的” ——浅阅读是个技术活:食不厌精,脍不厌细
- JavaScript【日期(今天是:xxxx年xx月xx日)】
- android4.0上ListView出现残影
- cocos2d-x场景动态切换
- MongoDB Sharding配置
- 指尖上的代码[C语言版]-<7>数据结构之单链表
- 线索二叉树