Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
8142b5eb
提交
8142b5eb
authored
9月 04, 2015
作者:
Anthony Minessale
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
formatting
上级
293ceabb
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
1033 行增加
和
1034 行删除
+1033
-1034
mpool.c
libs/libks/src/mpool.c
+1033
-1034
没有找到文件。
libs/libks/src/mpool.c
浏览文件 @
8142b5eb
...
...
@@ -66,24 +66,24 @@ static char *rcs_id = "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $";
#endif
/* version */
static
char
*
version
=
"mpool library version 2.1.0"
;
static
char
*
version
=
"mpool library version 2.1.0"
;
/* local variables */
static
int
enabled_b
=
0
;
/* lib initialized? */
static
unsigned
int
min_bit_free_next
=
0
;
/* min size of next pnt */
static
unsigned
int
min_bit_free_size
=
0
;
/* min size of next + size */
static
unsigned
long
bit_array
[
MAX_BITS
+
1
];
/* size -> bit */
static
int
enabled_b
=
0
;
/* lib initialized? */
static
unsigned
int
min_bit_free_next
=
0
;
/* min size of next pnt */
static
unsigned
int
min_bit_free_size
=
0
;
/* min size of next + size */
static
unsigned
long
bit_array
[
MAX_BITS
+
1
];
/* size -> bit */
#ifdef _MSC_VER
#include <Windows.h>
long
getpagesize
(
void
)
{
static
long
g_pagesize
=
0
;
if
(
!
g_pagesize
)
{
SYSTEM_INFO
system_info
;
GetSystemInfo
(
&
system_info
);
g_pagesize
=
system_info
.
dwPageSize
;
}
return
g_pagesize
;
static
long
g_pagesize
=
0
;
if
(
!
g_pagesize
)
{
SYSTEM_INFO
system_info
;
GetSystemInfo
(
&
system_info
);
g_pagesize
=
system_info
.
dwPageSize
;
}
return
g_pagesize
;
}
#endif
/****************************** local utilities ******************************/
...
...
@@ -103,38 +103,38 @@ long getpagesize(void) {
*
* None.
*/
static
void
startup
(
void
)
static
void
startup
(
void
)
{
int
bit_c
;
unsigned
long
size
=
1
;
int
bit_c
;
unsigned
long
size
=
1
;
if
(
enabled_b
)
{
return
;
}
if
(
enabled_b
)
{
return
;
}
/* allocate our free bit array list */
for
(
bit_c
=
0
;
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
bit_array
[
bit_c
]
=
size
;
/* allocate our free bit array list */
for
(
bit_c
=
0
;
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
bit_array
[
bit_c
]
=
size
;
/*
* Note our minimum number of bits that can store a pointer. This
* is smallest address that we can have a linked list for.
*/
if
(
min_bit_free_next
==
0
&&
size
>=
sizeof
(
void
*
))
{
min_bit_free_next
=
bit_c
;
}
/*
* Note our minimum number of bits that can store a pointer and
* the size of the block.
*/
if
(
min_bit_free_size
==
0
&&
size
>=
sizeof
(
mpool_free_t
))
{
min_bit_free_size
=
bit_c
;
}
/*
* Note our minimum number of bits that can store a pointer. This
* is smallest address that we can have a linked list for.
*/
if
(
min_bit_free_next
==
0
&&
size
>=
sizeof
(
void
*
))
{
min_bit_free_next
=
bit_c
;
}
/*
* Note our minimum number of bits that can store a pointer and
* the size of the block.
*/
if
(
min_bit_free_size
==
0
&&
size
>=
sizeof
(
mpool_free_t
))
{
min_bit_free_size
=
bit_c
;
}
size
*=
2
;
}
size
*=
2
;
}
enabled_b
=
1
;
enabled_b
=
1
;
}
/*
...
...
@@ -152,17 +152,17 @@ static void startup(void)
*
* size -> Size of memory of which to calculate the number of bits.
*/
static
int
size_to_bits
(
const
unsigned
long
size
)
static
int
size_to_bits
(
const
unsigned
long
size
)
{
int
bit_c
=
0
;
int
bit_c
=
0
;
for
(
bit_c
=
0
;
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
if
(
size
<=
bit_array
[
bit_c
])
{
break
;
}
}
for
(
bit_c
=
0
;
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
if
(
size
<=
bit_array
[
bit_c
])
{
break
;
}
}
return
bit_c
;
return
bit_c
;
}
/*
...
...
@@ -180,21 +180,21 @@ static int size_to_bits(const unsigned long size)
*
* size -> Size of memory of which to calculate the number of bits.
*/
static
int
size_to_free_bits
(
const
unsigned
long
size
)
static
int
size_to_free_bits
(
const
unsigned
long
size
)
{
int
bit_c
=
0
;
int
bit_c
=
0
;
if
(
size
==
0
)
{
return
0
;
}
if
(
size
==
0
)
{
return
0
;
}
for
(
bit_c
=
0
;
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
if
(
size
<
bit_array
[
bit_c
])
{
break
;
}
}
for
(
bit_c
=
0
;
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
if
(
size
<
bit_array
[
bit_c
])
{
break
;
}
}
return
bit_c
-
1
;
return
bit_c
-
1
;
}
/*
...
...
@@ -212,14 +212,14 @@ static int size_to_free_bits(const unsigned long size)
*
* bit_n -> Number of bits
*/
static
unsigned
long
bits_to_size
(
const
int
bit_n
)
static
unsigned
long
bits_to_size
(
const
int
bit_n
)
{
if
(
bit_n
>
MAX_BITS
)
{
return
bit_array
[
MAX_BITS
];
}
else
{
return
bit_array
[
bit_n
];
}
if
(
bit_n
>
MAX_BITS
)
{
return
bit_array
[
MAX_BITS
];
}
else
{
return
bit_array
[
bit_n
];
}
}
/*
...
...
@@ -244,56 +244,55 @@ static unsigned long bits_to_size(const int bit_n)
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
static
void
*
alloc_pages
(
mpool_t
*
mp_p
,
const
unsigned
int
page_n
,
int
*
error_p
)
static
void
*
alloc_pages
(
mpool_t
*
mp_p
,
const
unsigned
int
page_n
,
int
*
error_p
)
{
void
*
mem
;
unsigned
long
size
;
int
state
;
void
*
mem
;
unsigned
long
size
;
int
state
;
/* are we over our max-pages? */
if
(
mp_p
->
mp_max_pages
>
0
&&
mp_p
->
mp_page_c
>=
mp_p
->
mp_max_pages
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NO_PAGES
);
return
NULL
;
}
/* are we over our max-pages? */
if
(
mp_p
->
mp_max_pages
>
0
&&
mp_p
->
mp_page_c
>=
mp_p
->
mp_max_pages
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NO_PAGES
);
return
NULL
;
}
size
=
SIZE_OF_PAGES
(
mp_p
,
page_n
);
size
=
SIZE_OF_PAGES
(
mp_p
,
page_n
);
#ifdef DEBUG
(
void
)
printf
(
"allocating %u pages or %lu bytes
\n
"
,
page_n
,
size
);
(
void
)
printf
(
"allocating %u pages or %lu bytes
\n
"
,
page_n
,
size
);
#endif
state
=
MAP_PRIVATE
;
#if
def MAP_FILE
state
|=
MAP_FILE
;
state
=
MAP_PRIVATE
;
#if
defined(MAP_FILE)
state
|=
MAP_FILE
;
#endif
#if
def MAP_VARIABLE
state
|=
MAP_VARIABLE
;
#if
defined(MAP_VARIABLE)
state
|=
MAP_VARIABLE
;
#endif
/* mmap from /dev/zero */
mem
=
mmap
(
mp_p
->
mp_addr
,
size
,
mp_p
->
mp_mmflags
,
state
,
mp_p
->
mp_fd
,
mp_p
->
mp_top
);
if
(
mem
==
(
void
*
)
MAP_FAILED
)
{
if
(
errno
==
ENOMEM
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NO_MEM
);
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_MMAP
);
}
return
NULL
;
}
mp_p
->
mp_top
+=
size
;
if
(
mp_p
->
mp_addr
!=
NULL
)
{
mp_p
->
mp_addr
=
(
char
*
)
mp_p
->
mp_addr
+
size
;
}
/* mmap from /dev/zero */
mem
=
mmap
(
mp_p
->
mp_addr
,
size
,
mp_p
->
mp_mmflags
,
state
,
mp_p
->
mp_fd
,
mp_p
->
mp_top
);
if
(
mem
==
(
void
*
)
MAP_FAILED
)
{
if
(
errno
==
ENOMEM
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NO_MEM
);
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_MMAP
);
}
return
NULL
;
}
mp_p
->
mp_top
+=
size
;
if
(
mp_p
->
mp_addr
!=
NULL
)
{
mp_p
->
mp_addr
=
(
char
*
)
mp_p
->
mp_addr
+
size
;
}
mp_p
->
mp_page_c
+=
page_n
;
mp_p
->
mp_page_c
+=
page_n
;
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
mem
;
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
mem
;
}
/*
...
...
@@ -317,11 +316,11 @@ static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n,
*
* sbrk_b -> Set to one if the pages were allocated with sbrk else mmap.
*/
static
int
free_pages
(
void
*
pages
,
const
unsigned
long
size
)
static
int
free_pages
(
void
*
pages
,
const
unsigned
long
size
)
{
(
void
)
munmap
(
pages
,
size
);
return
MPOOL_ERROR_NONE
;
(
void
)
munmap
(
pages
,
size
);
return
MPOOL_ERROR_NONE
;
}
/*
...
...
@@ -343,19 +342,19 @@ static int free_pages(void *pages, const unsigned long size)
*
* size -> Size of the block.
*/
static
int
check_magic
(
const
void
*
addr
,
const
unsigned
long
size
)
static
int
check_magic
(
const
void
*
addr
,
const
unsigned
long
size
)
{
const
unsigned
char
*
mem_p
;
const
unsigned
char
*
mem_p
;
/* set our starting point */
mem_p
=
(
unsigned
char
*
)
addr
+
size
;
/* set our starting point */
mem_p
=
(
unsigned
char
*
)
addr
+
size
;
if
(
*
mem_p
==
FENCE_MAGIC0
&&
*
(
mem_p
+
1
)
==
FENCE_MAGIC1
)
{
return
MPOOL_ERROR_NONE
;
}
else
{
return
MPOOL_ERROR_PNT_OVER
;
}
if
(
*
mem_p
==
FENCE_MAGIC0
&&
*
(
mem_p
+
1
)
==
FENCE_MAGIC1
)
{
return
MPOOL_ERROR_NONE
;
}
else
{
return
MPOOL_ERROR_PNT_OVER
;
}
}
/*
...
...
@@ -373,10 +372,10 @@ static int check_magic(const void *addr, const unsigned long size)
*
* addr -> Address where to write the magic.
*/
static
void
write_magic
(
const
void
*
addr
)
static
void
write_magic
(
const
void
*
addr
)
{
*
(
unsigned
char
*
)
addr
=
FENCE_MAGIC0
;
*
((
unsigned
char
*
)
addr
+
1
)
=
FENCE_MAGIC1
;
*
(
unsigned
char
*
)
addr
=
FENCE_MAGIC0
;
*
((
unsigned
char
*
)
addr
+
1
)
=
FENCE_MAGIC1
;
}
/*
...
...
@@ -401,76 +400,76 @@ static void write_magic(const void *addr)
*
* size -> Size of the address space.
*/
static
int
free_pointer
(
mpool_t
*
mp_p
,
void
*
addr
,
const
unsigned
long
size
)
static
int
free_pointer
(
mpool_t
*
mp_p
,
void
*
addr
,
const
unsigned
long
size
)
{
unsigned
int
bit_n
;
unsigned
long
real_size
;
mpool_free_t
free_pnt
;
unsigned
int
bit_n
;
unsigned
long
real_size
;
mpool_free_t
free_pnt
;
#ifdef DEBUG
(
void
)
printf
(
"freeing a block at %lx of %lu bytes
\n
"
,
(
long
)
addr
,
size
);
(
void
)
printf
(
"freeing a block at %lx of %lu bytes
\n
"
,
(
long
)
addr
,
size
);
#endif
if
(
size
==
0
)
{
return
MPOOL_ERROR_NONE
;
}
/*
* if the user size is larger then can fit in an entire block then
* we change the size
*/
if
(
size
>
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
real_size
=
SIZE_OF_PAGES
(
mp_p
,
PAGES_IN_SIZE
(
mp_p
,
size
))
-
sizeof
(
mpool_block_t
);
}
else
{
real_size
=
size
;
}
/*
* We use a specific free bits calculation here because if we are
* freeing 10 bytes then we will be putting it into the 8-byte free
* list and not the 16 byte list. size_to_bits(10) will return 4
* instead of 3.
*/
bit_n
=
size_to_free_bits
(
real_size
);
/*
* Minimal error checking. We could go all the way through the
* list however this might be prohibitive.
*/
if
(
mp_p
->
mp_free
[
bit_n
]
==
addr
)
{
return
MPOOL_ERROR_IS_FREE
;
}
/* add the freed pointer to the free list */
if
(
bit_n
<
min_bit_free_next
)
{
/*
* Yes we know this will lose 99% of the allocations but what else
* can we do? No space for a next pointer.
*/
if
(
mp_p
->
mp_free
[
bit_n
]
==
NULL
)
{
mp_p
->
mp_free
[
bit_n
]
=
addr
;
}
}
else
if
(
bit_n
<
min_bit_free_size
)
{
/* we copy, not assign, to maintain the free list */
memcpy
(
addr
,
mp_p
->
mp_free
+
bit_n
,
sizeof
(
void
*
));
mp_p
->
mp_free
[
bit_n
]
=
addr
;
}
else
{
if
(
size
==
0
)
{
return
MPOOL_ERROR_NONE
;
}
/*
* if the user size is larger then can fit in an entire block then
* we change the size
*/
if
(
size
>
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
real_size
=
SIZE_OF_PAGES
(
mp_p
,
PAGES_IN_SIZE
(
mp_p
,
size
))
-
sizeof
(
mpool_block_t
);
}
else
{
real_size
=
size
;
}
/*
* We use a specific free bits calculation here because if we are
* freeing 10 bytes then we will be putting it into the 8-byte free
* list and not the 16 byte list. size_to_bits(10) will return 4
* instead of 3.
*/
bit_n
=
size_to_free_bits
(
real_size
);
/*
* Minimal error checking. We could go all the way through the
* list however this might be prohibitive.
*/
if
(
mp_p
->
mp_free
[
bit_n
]
==
addr
)
{
return
MPOOL_ERROR_IS_FREE
;
}
/* add the freed pointer to the free list */
if
(
bit_n
<
min_bit_free_next
)
{
/*
* Yes we know this will lose 99% of the allocations but what else
* can we do? No space for a next pointer.
*/
if
(
mp_p
->
mp_free
[
bit_n
]
==
NULL
)
{
mp_p
->
mp_free
[
bit_n
]
=
addr
;
}
}
else
if
(
bit_n
<
min_bit_free_size
)
{
/* we copy, not assign, to maintain the free list */
memcpy
(
addr
,
mp_p
->
mp_free
+
bit_n
,
sizeof
(
void
*
));
mp_p
->
mp_free
[
bit_n
]
=
addr
;
}
else
{
/* setup our free list structure */
free_pnt
.
mf_next_p
=
mp_p
->
mp_free
[
bit_n
];
free_pnt
.
mf_size
=
real_size
;
/* setup our free list structure */
free_pnt
.
mf_next_p
=
mp_p
->
mp_free
[
bit_n
];
free_pnt
.
mf_size
=
real_size
;
/* we copy the structure in since we don't know about alignment */
memcpy
(
addr
,
&
free_pnt
,
sizeof
(
free_pnt
));
mp_p
->
mp_free
[
bit_n
]
=
addr
;
}
/* we copy the structure in since we don't know about alignment */
memcpy
(
addr
,
&
free_pnt
,
sizeof
(
free_pnt
));
mp_p
->
mp_free
[
bit_n
]
=
addr
;
}
return
MPOOL_ERROR_NONE
;
return
MPOOL_ERROR_NONE
;
}
/*
...
...
@@ -495,60 +494,60 @@ static int free_pointer(mpool_t *mp_p, void *addr,
*
* size -> Size of the space that we are taking from address.
*/
static
int
split_block
(
mpool_t
*
mp_p
,
void
*
free_addr
,
const
unsigned
long
size
)
static
int
split_block
(
mpool_t
*
mp_p
,
void
*
free_addr
,
const
unsigned
long
size
)
{
mpool_block_t
*
block_p
,
*
new_block_p
;
int
ret
,
page_n
;
void
*
end_p
;
/*
* 1st we find the block pointer from our free addr. At this point
* the pointer must be the 1st one in the block if it is spans
* multiple blocks.
*/
block_p
=
(
mpool_block_t
*
)((
char
*
)
free_addr
-
sizeof
(
mpool_block_t
));
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
page_n
=
PAGES_IN_SIZE
(
mp_p
,
size
);
/* we are creating a new block structure for the 2nd ... */
new_block_p
=
(
mpool_block_t
*
)((
char
*
)
block_p
+
SIZE_OF_PAGES
(
mp_p
,
page_n
));
new_block_p
->
mb_magic
=
BLOCK_MAGIC
;
/* New bounds is 1st block bounds. The 1st block's is reset below. */
new_block_p
->
mb_bounds_p
=
block_p
->
mb_bounds_p
;
/* Continue the linked list. The 1st block will point to us below. */
new_block_p
->
mb_next_p
=
block_p
->
mb_next_p
;
new_block_p
->
mb_magic2
=
BLOCK_MAGIC
;
/* bounds for the 1st block are reset to the 1st page only */
block_p
->
mb_bounds_p
=
(
char
*
)
new_block_p
;
/* the next block pointer for the 1st block is now the new one */
block_p
->
mb_next_p
=
new_block_p
;
/* only free the space in the 1st block if it is only 1 block in size */
if
(
page_n
==
1
)
{
/* now free the rest of the 1st block block */
end_p
=
(
char
*
)
free_addr
+
size
;
ret
=
free_pointer
(
mp_p
,
end_p
,
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
end_p
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
}
/* now free the rest of the block */
ret
=
free_pointer
(
mp_p
,
FIRST_ADDR_IN_BLOCK
(
new_block_p
),
MEMORY_IN_BLOCK
(
new_block_p
));
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
return
MPOOL_ERROR_NONE
;
mpool_block_t
*
block_p
,
*
new_block_p
;
int
ret
,
page_n
;
void
*
end_p
;
/*
* 1st we find the block pointer from our free addr. At this point
* the pointer must be the 1st one in the block if it is spans
* multiple blocks.
*/
block_p
=
(
mpool_block_t
*
)((
char
*
)
free_addr
-
sizeof
(
mpool_block_t
));
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
page_n
=
PAGES_IN_SIZE
(
mp_p
,
size
);
/* we are creating a new block structure for the 2nd ... */
new_block_p
=
(
mpool_block_t
*
)((
char
*
)
block_p
+
SIZE_OF_PAGES
(
mp_p
,
page_n
));
new_block_p
->
mb_magic
=
BLOCK_MAGIC
;
/* New bounds is 1st block bounds. The 1st block's is reset below. */
new_block_p
->
mb_bounds_p
=
block_p
->
mb_bounds_p
;
/* Continue the linked list. The 1st block will point to us below. */
new_block_p
->
mb_next_p
=
block_p
->
mb_next_p
;
new_block_p
->
mb_magic2
=
BLOCK_MAGIC
;
/* bounds for the 1st block are reset to the 1st page only */
block_p
->
mb_bounds_p
=
(
char
*
)
new_block_p
;
/* the next block pointer for the 1st block is now the new one */
block_p
->
mb_next_p
=
new_block_p
;
/* only free the space in the 1st block if it is only 1 block in size */
if
(
page_n
==
1
)
{
/* now free the rest of the 1st block block */
end_p
=
(
char
*
)
free_addr
+
size
;
ret
=
free_pointer
(
mp_p
,
end_p
,
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
end_p
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
}
/* now free the rest of the block */
ret
=
free_pointer
(
mp_p
,
FIRST_ADDR_IN_BLOCK
(
new_block_p
),
MEMORY_IN_BLOCK
(
new_block_p
));
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
return
MPOOL_ERROR_NONE
;
}
/*
...
...
@@ -573,146 +572,146 @@ static int split_block(mpool_t *mp_p, void *free_addr,
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
static
void
*
get_space
(
mpool_t
*
mp_p
,
const
unsigned
long
byte_size
,
int
*
error_p
)
static
void
*
get_space
(
mpool_t
*
mp_p
,
const
unsigned
long
byte_size
,
int
*
error_p
)
{
mpool_block_t
*
block_p
;
mpool_free_t
free_pnt
;
int
ret
;
unsigned
long
size
;
unsigned
int
bit_c
,
page_n
,
left
;
void
*
free_addr
=
NULL
,
*
free_end
;
size
=
byte_size
;
while
((
size
&
(
sizeof
(
void
*
)
-
1
))
>
0
)
{
size
++
;
}
/*
* First we check the free lists looking for something with enough
* pages. Maybe we should only look X bits higher in the list.
*
* XXX: this is where we'd do the best fit. We'd look for the
* closest match. We then could put the rest of the allocation that
* we did not use in a lower free list. Have a define which states
* how deep in the free list to go to find the closest match.
*/
for
(
bit_c
=
size_to_bits
(
size
);
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
if
(
mp_p
->
mp_free
[
bit_c
]
!=
NULL
)
{
free_addr
=
mp_p
->
mp_free
[
bit_c
];
break
;
}
}
/*
* If we haven't allocated any blocks or if the last block doesn't
* have enough memory then we need a new block.
*/
if
(
bit_c
>
MAX_BITS
)
{
mpool_block_t
*
block_p
;
mpool_free_t
free_pnt
;
int
ret
;
unsigned
long
size
;
unsigned
int
bit_c
,
page_n
,
left
;
void
*
free_addr
=
NULL
,
*
free_end
;
size
=
byte_size
;
while
((
size
&
(
sizeof
(
void
*
)
-
1
))
>
0
)
{
size
++
;
}
/*
* First we check the free lists looking for something with enough
* pages. Maybe we should only look X bits higher in the list.
*
* XXX: this is where we'd do the best fit. We'd look for the
* closest match. We then could put the rest of the allocation that
* we did not use in a lower free list. Have a define which states
* how deep in the free list to go to find the closest match.
*/
for
(
bit_c
=
size_to_bits
(
size
);
bit_c
<=
MAX_BITS
;
bit_c
++
)
{
if
(
mp_p
->
mp_free
[
bit_c
]
!=
NULL
)
{
free_addr
=
mp_p
->
mp_free
[
bit_c
];
break
;
}
}
/*
* If we haven't allocated any blocks or if the last block doesn't
* have enough memory then we need a new block.
*/
if
(
bit_c
>
MAX_BITS
)
{
/* we need to allocate more space */
/* we need to allocate more space */
page_n
=
PAGES_IN_SIZE
(
mp_p
,
size
);
page_n
=
PAGES_IN_SIZE
(
mp_p
,
size
);
/* now we try and get the pages we need/want */
block_p
=
alloc_pages
(
mp_p
,
page_n
,
error_p
);
if
(
block_p
==
NULL
)
{
/* error_p set in alloc_pages */
return
NULL
;
}
/* now we try and get the pages we need/want */
block_p
=
alloc_pages
(
mp_p
,
page_n
,
error_p
);
if
(
block_p
==
NULL
)
{
/* error_p set in alloc_pages */
return
NULL
;
}
/* init the block header */
block_p
->
mb_magic
=
BLOCK_MAGIC
;
block_p
->
mb_bounds_p
=
(
char
*
)
block_p
+
SIZE_OF_PAGES
(
mp_p
,
page_n
);
block_p
->
mb_next_p
=
mp_p
->
mp_first_p
;
block_p
->
mb_magic2
=
BLOCK_MAGIC
;
/* init the block header */
block_p
->
mb_magic
=
BLOCK_MAGIC
;
block_p
->
mb_bounds_p
=
(
char
*
)
block_p
+
SIZE_OF_PAGES
(
mp_p
,
page_n
);
block_p
->
mb_next_p
=
mp_p
->
mp_first_p
;
block_p
->
mb_magic2
=
BLOCK_MAGIC
;
/*
* We insert it into the front of the queue. We could add it to
* the end but there is not much use.
*/
mp_p
->
mp_first_p
=
block_p
;
if
(
mp_p
->
mp_last_p
==
NULL
)
{
mp_p
->
mp_last_p
=
block_p
;
}
/*
* We insert it into the front of the queue. We could add it to
* the end but there is not much use.
*/
mp_p
->
mp_first_p
=
block_p
;
if
(
mp_p
->
mp_last_p
==
NULL
)
{
mp_p
->
mp_last_p
=
block_p
;
}
free_addr
=
FIRST_ADDR_IN_BLOCK
(
block_p
);
free_addr
=
FIRST_ADDR_IN_BLOCK
(
block_p
);
#ifdef DEBUG
(
void
)
printf
(
"had to allocate space for %lx of %lu bytes
\n
"
,
(
long
)
free_addr
,
size
);
(
void
)
printf
(
"had to allocate space for %lx of %lu bytes
\n
"
,
(
long
)
free_addr
,
size
);
#endif
free_end
=
(
char
*
)
free_addr
+
size
;
left
=
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
free_end
;
}
else
{
free_end
=
(
char
*
)
free_addr
+
size
;
left
=
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
free_end
;
}
else
{
if
(
bit_c
<
min_bit_free_next
)
{
mp_p
->
mp_free
[
bit_c
]
=
NULL
;
/* calculate the number of left over bytes */
left
=
bits_to_size
(
bit_c
)
-
size
;
}
else
if
(
bit_c
<
min_bit_free_next
)
{
/* grab the next pointer from the freed address into our list */
memcpy
(
mp_p
->
mp_free
+
bit_c
,
free_addr
,
sizeof
(
void
*
));
/* calculate the number of left over bytes */
left
=
bits_to_size
(
bit_c
)
-
size
;
}
else
{
/* grab the free structure from the address */
memcpy
(
&
free_pnt
,
free_addr
,
sizeof
(
free_pnt
));
mp_p
->
mp_free
[
bit_c
]
=
free_pnt
.
mf_next_p
;
if
(
bit_c
<
min_bit_free_next
)
{
mp_p
->
mp_free
[
bit_c
]
=
NULL
;
/* calculate the number of left over bytes */
left
=
bits_to_size
(
bit_c
)
-
size
;
}
else
if
(
bit_c
<
min_bit_free_next
)
{
/* grab the next pointer from the freed address into our list */
memcpy
(
mp_p
->
mp_free
+
bit_c
,
free_addr
,
sizeof
(
void
*
));
/* calculate the number of left over bytes */
left
=
bits_to_size
(
bit_c
)
-
size
;
}
else
{
/* grab the free structure from the address */
memcpy
(
&
free_pnt
,
free_addr
,
sizeof
(
free_pnt
));
mp_p
->
mp_free
[
bit_c
]
=
free_pnt
.
mf_next_p
;
/* are we are splitting up a multiblock chunk into fewer blocks? */
if
(
PAGES_IN_SIZE
(
mp_p
,
free_pnt
.
mf_size
)
>
PAGES_IN_SIZE
(
mp_p
,
size
))
{
ret
=
split_block
(
mp_p
,
free_addr
,
size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
/* left over memory was taken care of in split_block */
left
=
0
;
}
else
{
/* calculate the number of left over bytes */
left
=
free_pnt
.
mf_size
-
size
;
}
}
/* are we are splitting up a multiblock chunk into fewer blocks? */
if
(
PAGES_IN_SIZE
(
mp_p
,
free_pnt
.
mf_size
)
>
PAGES_IN_SIZE
(
mp_p
,
size
))
{
ret
=
split_block
(
mp_p
,
free_addr
,
size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
/* left over memory was taken care of in split_block */
left
=
0
;
}
else
{
/* calculate the number of left over bytes */
left
=
free_pnt
.
mf_size
-
size
;
}
}
#ifdef DEBUG
(
void
)
printf
(
"found a free block at %lx of %lu bytes
\n
"
,
(
long
)
free_addr
,
left
+
size
);
(
void
)
printf
(
"found a free block at %lx of %lu bytes
\n
"
,
(
long
)
free_addr
,
left
+
size
);
#endif
free_end
=
(
char
*
)
free_addr
+
size
;
}
/*
* If we have memory left over then we free it so someone else can
* use it. We do not free the space if we just allocated a
* multi-block chunk because we need to have every allocation easily
* find the start of the block. Every user address % page-size
* should take us to the start of the block.
*/
if
(
left
>
0
&&
size
<=
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
/* free the rest of the block */
ret
=
free_pointer
(
mp_p
,
free_end
,
left
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
}
/* update our bounds */
if
(
free_addr
>
mp_p
->
mp_bounds_p
)
{
mp_p
->
mp_bounds_p
=
free_addr
;
}
else
if
(
free_addr
<
mp_p
->
mp_min_p
)
{
mp_p
->
mp_min_p
=
free_addr
;
}
return
free_addr
;
free_end
=
(
char
*
)
free_addr
+
size
;
}
/*
* If we have memory left over then we free it so someone else can
* use it. We do not free the space if we just allocated a
* multi-block chunk because we need to have every allocation easily
* find the start of the block. Every user address % page-size
* should take us to the start of the block.
*/
if
(
left
>
0
&&
size
<=
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
/* free the rest of the block */
ret
=
free_pointer
(
mp_p
,
free_end
,
left
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
}
/* update our bounds */
if
(
free_addr
>
mp_p
->
mp_bounds_p
)
{
mp_p
->
mp_bounds_p
=
free_addr
;
}
else
if
(
free_addr
<
mp_p
->
mp_min_p
)
{
mp_p
->
mp_min_p
=
free_addr
;
}
return
free_addr
;
}
/*
...
...
@@ -738,47 +737,47 @@ static void *get_space(mpool_t *mp_p, const unsigned long byte_size,
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
static
void
*
alloc_mem
(
mpool_t
*
mp_p
,
const
unsigned
long
byte_size
,
int
*
error_p
)
static
void
*
alloc_mem
(
mpool_t
*
mp_p
,
const
unsigned
long
byte_size
,
int
*
error_p
)
{
unsigned
long
size
,
fence
;
void
*
addr
;
/* make sure we have enough bytes */
if
(
byte_size
<
MIN_ALLOCATION
)
{
size
=
MIN_ALLOCATION
;
}
else
{
size
=
byte_size
;
}
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
fence
=
0
;
}
else
{
fence
=
FENCE_SIZE
;
}
/* get our free space + the space for the fence post */
addr
=
get_space
(
mp_p
,
size
+
fence
,
error_p
);
if
(
addr
==
NULL
)
{
/* error_p set in get_space */
return
NULL
;
}
if
(
!
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
write_magic
((
char
*
)
addr
+
size
);
}
/* maintain our stats */
mp_p
->
mp_alloc_c
++
;
mp_p
->
mp_user_alloc
+=
size
;
if
(
mp_p
->
mp_user_alloc
>
mp_p
->
mp_max_alloc
)
{
mp_p
->
mp_max_alloc
=
mp_p
->
mp_user_alloc
;
}
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
addr
;
unsigned
long
size
,
fence
;
void
*
addr
;
/* make sure we have enough bytes */
if
(
byte_size
<
MIN_ALLOCATION
)
{
size
=
MIN_ALLOCATION
;
}
else
{
size
=
byte_size
;
}
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
fence
=
0
;
}
else
{
fence
=
FENCE_SIZE
;
}
/* get our free space + the space for the fence post */
addr
=
get_space
(
mp_p
,
size
+
fence
,
error_p
);
if
(
addr
==
NULL
)
{
/* error_p set in get_space */
return
NULL
;
}
if
(
!
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
write_magic
((
char
*
)
addr
+
size
);
}
/* maintain our stats */
mp_p
->
mp_alloc_c
++
;
mp_p
->
mp_user_alloc
+=
size
;
if
(
mp_p
->
mp_user_alloc
>
mp_p
->
mp_max_alloc
)
{
mp_p
->
mp_max_alloc
=
mp_p
->
mp_user_alloc
;
}
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
addr
;
}
/*
...
...
@@ -803,56 +802,56 @@ static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size,
*
* size -> Size of the address being freed.
*/
static
int
free_mem
(
mpool_t
*
mp_p
,
void
*
addr
,
const
unsigned
long
size
)
static
int
free_mem
(
mpool_t
*
mp_p
,
void
*
addr
,
const
unsigned
long
size
)
{
unsigned
long
old_size
,
fence
;
int
ret
;
mpool_block_t
*
block_p
;
/*
* If the size is larger than a block then the allocation must be at
* the front of the block.
*/
if
(
size
>
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
block_p
=
(
mpool_block_t
*
)((
char
*
)
addr
-
sizeof
(
mpool_block_t
));
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
}
/* make sure we have enough bytes */
if
(
size
<
MIN_ALLOCATION
)
{
old_size
=
MIN_ALLOCATION
;
}
else
{
old_size
=
size
;
}
/* if we are packing the pool smaller */
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
fence
=
0
;
}
else
{
/* find the user's magic numbers if they were written */
ret
=
check_magic
(
addr
,
old_size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
fence
=
FENCE_SIZE
;
}
/* now we free the pointer */
ret
=
free_pointer
(
mp_p
,
addr
,
old_size
+
fence
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
mp_p
->
mp_user_alloc
-=
old_size
;
/* adjust our stats */
mp_p
->
mp_alloc_c
--
;
return
MPOOL_ERROR_NONE
;
unsigned
long
old_size
,
fence
;
int
ret
;
mpool_block_t
*
block_p
;
/*
* If the size is larger than a block then the allocation must be at
* the front of the block.
*/
if
(
size
>
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
block_p
=
(
mpool_block_t
*
)((
char
*
)
addr
-
sizeof
(
mpool_block_t
));
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
}
/* make sure we have enough bytes */
if
(
size
<
MIN_ALLOCATION
)
{
old_size
=
MIN_ALLOCATION
;
}
else
{
old_size
=
size
;
}
/* if we are packing the pool smaller */
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
fence
=
0
;
}
else
{
/* find the user's magic numbers if they were written */
ret
=
check_magic
(
addr
,
old_size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
fence
=
FENCE_SIZE
;
}
/* now we free the pointer */
ret
=
free_pointer
(
mp_p
,
addr
,
old_size
+
fence
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
return
ret
;
}
mp_p
->
mp_user_alloc
-=
old_size
;
/* adjust our stats */
mp_p
->
mp_alloc_c
--
;
return
MPOOL_ERROR_NONE
;
}
/***************************** exported routines *****************************/
...
...
@@ -884,149 +883,149 @@ static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size)
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
mpool_t
*
mpool_open
(
const
unsigned
int
flags
,
const
unsigned
int
page_size
,
void
*
start_addr
,
int
*
error_p
)
mpool_t
*
mpool_open
(
const
unsigned
int
flags
,
const
unsigned
int
page_size
,
void
*
start_addr
,
int
*
error_p
)
{
mpool_block_t
*
block_p
;
int
page_n
,
ret
;
mpool_t
mp
,
*
mp_p
;
void
*
free_addr
;
if
(
!
enabled_b
)
{
startup
();
}
/* zero our temp struct */
memset
(
&
mp
,
0
,
sizeof
(
mp
));
mp
.
mp_magic
=
MPOOL_MAGIC
;
mp
.
mp_flags
=
flags
;
mp
.
mp_alloc_c
=
0
;
mp
.
mp_user_alloc
=
0
;
mp
.
mp_max_alloc
=
0
;
mp
.
mp_page_c
=
0
;
/* mp.mp_page_size set below */
/* mp.mp_blocks_bit_n set below */
/* mp.mp_fd set below */
/* mp.mp_top set below */
/* mp.mp_addr set below */
mp
.
mp_log_func
=
NULL
;
mp
.
mp_min_p
=
NULL
;
mp
.
mp_bounds_p
=
NULL
;
mp
.
mp_first_p
=
NULL
;
mp
.
mp_last_p
=
NULL
;
mp
.
mp_magic2
=
MPOOL_MAGIC
;
/* get and sanity check our page size */
if
(
page_size
>
0
)
{
mp
.
mp_page_size
=
page_size
;
if
(
mp
.
mp_page_size
%
getpagesize
()
!=
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
}
else
{
mp
.
mp_page_size
=
getpagesize
()
*
DEFAULT_PAGE_MULT
;
if
(
mp
.
mp_page_size
%
1024
!=
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PAGE_SIZE
);
return
NULL
;
}
}
mp
.
mp_mmflags
=
PROT_READ
|
PROT_WRITE
;
mpool_block_t
*
block_p
;
int
page_n
,
ret
;
mpool_t
mp
,
*
mp_p
;
void
*
free_addr
;
if
(
!
enabled_b
)
{
startup
();
}
/* zero our temp struct */
memset
(
&
mp
,
0
,
sizeof
(
mp
));
mp
.
mp_magic
=
MPOOL_MAGIC
;
mp
.
mp_flags
=
flags
;
mp
.
mp_alloc_c
=
0
;
mp
.
mp_user_alloc
=
0
;
mp
.
mp_max_alloc
=
0
;
mp
.
mp_page_c
=
0
;
/* mp.mp_page_size set below */
/* mp.mp_blocks_bit_n set below */
/* mp.mp_fd set below */
/* mp.mp_top set below */
/* mp.mp_addr set below */
mp
.
mp_log_func
=
NULL
;
mp
.
mp_min_p
=
NULL
;
mp
.
mp_bounds_p
=
NULL
;
mp
.
mp_first_p
=
NULL
;
mp
.
mp_last_p
=
NULL
;
mp
.
mp_magic2
=
MPOOL_MAGIC
;
/* get and sanity check our page size */
if
(
page_size
>
0
)
{
mp
.
mp_page_size
=
page_size
;
if
(
mp
.
mp_page_size
%
getpagesize
()
!=
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
}
else
{
mp
.
mp_page_size
=
getpagesize
()
*
DEFAULT_PAGE_MULT
;
if
(
mp
.
mp_page_size
%
1024
!=
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PAGE_SIZE
);
return
NULL
;
}
}
mp
.
mp_mmflags
=
PROT_READ
|
PROT_WRITE
;
if
(
BIT_IS_SET
(
flags
,
MPOOL_FLAG_ANONYMOUS
))
{
mp
.
mp_fd
=
-
1
;
mp
.
mp_mmflags
|=
MAP_ANON
;
}
else
{
/* open dev-zero for our mmaping */
mp
.
mp_fd
=
open
(
"/dev/zero"
,
O_RDWR
,
0
);
if
(
mp
.
mp_fd
<
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_OPEN_ZERO
);
return
NULL
;
}
}
mp
.
mp_addr
=
start_addr
;
/* we start at the front of the file */
mp
.
mp_top
=
0
;
if
(
BIT_IS_SET
(
flags
,
MPOOL_FLAG_ANONYMOUS
))
{
mp
.
mp_fd
=
-
1
;
mp
.
mp_mmflags
|=
MAP_ANON
;
}
else
{
/* open dev-zero for our mmaping */
mp
.
mp_fd
=
open
(
"/dev/zero"
,
O_RDWR
,
0
);
if
(
mp
.
mp_fd
<
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_OPEN_ZERO
);
return
NULL
;
}
}
mp
.
mp_addr
=
start_addr
;
/* we start at the front of the file */
mp
.
mp_top
=
0
;
/*
* Find out how many pages we need for our mpool structure.
*
* NOTE: this adds possibly unneeded space for mpool_block_t which
* may not be in this block.
*/
page_n
=
PAGES_IN_SIZE
(
&
mp
,
sizeof
(
mpool_t
));
/* now allocate us space for the actual struct */
mp_p
=
alloc_pages
(
&
mp
,
page_n
,
error_p
);
if
(
mp_p
==
NULL
)
{
if
(
mp
.
mp_fd
>=
0
)
{
(
void
)
close
(
mp
.
mp_fd
);
mp
.
mp_fd
=
-
1
;
}
return
NULL
;
}
/*
* NOTE: we do not normally free the rest of the block here because
* we want to lesson the chance of an allocation overwriting the
* main structure.
*/
if
(
BIT_IS_SET
(
flags
,
MPOOL_FLAG_HEAVY_PACKING
))
{
/*
* Find out how many pages we need for our mpool structure.
*
* NOTE: this adds possibly unneeded space for mpool_block_t which
* may not be in this block.
*/
page_n
=
PAGES_IN_SIZE
(
&
mp
,
sizeof
(
mpool_t
));
/* now allocate us space for the actual struct */
mp_p
=
alloc_pages
(
&
mp
,
page_n
,
error_p
);
if
(
mp_p
==
NULL
)
{
if
(
mp
.
mp_fd
>=
0
)
{
(
void
)
close
(
mp
.
mp_fd
);
mp
.
mp_fd
=
-
1
;
}
return
NULL
;
}
/*
* NOTE: we do not normally free the rest of the block here because
* we want to lesson the chance of an allocation overwriting the
* main structure.
*/
if
(
BIT_IS_SET
(
flags
,
MPOOL_FLAG_HEAVY_PACKING
))
{
/* we add a block header to the front of the block */
block_p
=
(
mpool_block_t
*
)
mp_p
;
/* we add a block header to the front of the block */
block_p
=
(
mpool_block_t
*
)
mp_p
;
/* init the block header */
block_p
->
mb_magic
=
BLOCK_MAGIC
;
block_p
->
mb_bounds_p
=
(
char
*
)
block_p
+
SIZE_OF_PAGES
(
&
mp
,
page_n
);
block_p
->
mb_next_p
=
NULL
;
block_p
->
mb_magic2
=
BLOCK_MAGIC
;
/* init the block header */
block_p
->
mb_magic
=
BLOCK_MAGIC
;
block_p
->
mb_bounds_p
=
(
char
*
)
block_p
+
SIZE_OF_PAGES
(
&
mp
,
page_n
);
block_p
->
mb_next_p
=
NULL
;
block_p
->
mb_magic2
=
BLOCK_MAGIC
;
/* the mpool pointer is then the 2nd thing in the block */
mp_p
=
FIRST_ADDR_IN_BLOCK
(
block_p
);
free_addr
=
(
char
*
)
mp_p
+
sizeof
(
mpool_t
);
/* the mpool pointer is then the 2nd thing in the block */
mp_p
=
FIRST_ADDR_IN_BLOCK
(
block_p
);
free_addr
=
(
char
*
)
mp_p
+
sizeof
(
mpool_t
);
/* free the rest of the block */
ret
=
free_pointer
(
&
mp
,
free_addr
,
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
free_addr
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
if
(
mp
.
mp_fd
>=
0
)
{
(
void
)
close
(
mp
.
mp_fd
);
mp
.
mp_fd
=
-
1
;
}
/* NOTE: after this line mp_p will be invalid */
(
void
)
free_pages
(
block_p
,
SIZE_OF_PAGES
(
&
mp
,
page_n
));
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
/* free the rest of the block */
ret
=
free_pointer
(
&
mp
,
free_addr
,
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
free_addr
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
if
(
mp
.
mp_fd
>=
0
)
{
(
void
)
close
(
mp
.
mp_fd
);
mp
.
mp_fd
=
-
1
;
}
/* NOTE: after this line mp_p will be invalid */
(
void
)
free_pages
(
block_p
,
SIZE_OF_PAGES
(
&
mp
,
page_n
));
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
/*
* NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
* header is not on the block linked list.
*/
/*
* NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
* header is not on the block linked list.
*/
/* now copy our tmp structure into our new memory area */
memcpy
(
mp_p
,
&
mp
,
sizeof
(
mpool_t
));
/* now copy our tmp structure into our new memory area */
memcpy
(
mp_p
,
&
mp
,
sizeof
(
mpool_t
));
/* we setup min/max to our current address which is as good as any */
mp_p
->
mp_min_p
=
block_p
;
mp_p
->
mp_bounds_p
=
block_p
->
mb_bounds_p
;
}
else
{
/* now copy our tmp structure into our new memory area */
memcpy
(
mp_p
,
&
mp
,
sizeof
(
mpool_t
));
/* we setup min/max to our current address which is as good as any */
mp_p
->
mp_min_p
=
block_p
;
mp_p
->
mp_bounds_p
=
block_p
->
mb_bounds_p
;
}
else
{
/* now copy our tmp structure into our new memory area */
memcpy
(
mp_p
,
&
mp
,
sizeof
(
mpool_t
));
/* we setup min/max to our current address which is as good as any */
mp_p
->
mp_min_p
=
mp_p
;
mp_p
->
mp_bounds_p
=
(
char
*
)
mp_p
+
SIZE_OF_PAGES
(
mp_p
,
page_n
);
}
/* we setup min/max to our current address which is as good as any */
mp_p
->
mp_min_p
=
mp_p
;
mp_p
->
mp_bounds_p
=
(
char
*
)
mp_p
+
SIZE_OF_PAGES
(
mp_p
,
page_n
);
}
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
mp_p
;
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
mp_p
;
}
/*
...
...
@@ -1047,74 +1046,74 @@ mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size,
*
* mp_p <-> Pointer to our memory pool.
*/
int
mpool_close
(
mpool_t
*
mp_p
)
int
mpool_close
(
mpool_t
*
mp_p
)
{
mpool_block_t
*
block_p
,
*
next_p
;
void
*
addr
;
unsigned
long
size
;
int
ret
,
final
=
MPOOL_ERROR_NONE
;
/* special case, just return no-error */
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_CLOSE
,
0
,
0
,
NULL
,
NULL
,
0
);
}
/*
* NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
* header is not on the linked list.
*/
/* free/invalidate the blocks */
for
(
block_p
=
mp_p
->
mp_first_p
;
block_p
!=
NULL
;
block_p
=
next_p
)
{
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
final
=
MPOOL_ERROR_POOL_OVER
;
break
;
}
block_p
->
mb_magic
=
0
;
block_p
->
mb_magic2
=
0
;
/* record the next pointer because it might be invalidated below */
next_p
=
block_p
->
mb_next_p
;
ret
=
free_pages
(
block_p
,
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
block_p
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
final
=
ret
;
}
}
/* close /dev/zero if necessary */
if
(
mp_p
->
mp_fd
>=
0
)
{
(
void
)
close
(
mp_p
->
mp_fd
);
mp_p
->
mp_fd
=
-
1
;
}
/* invalidate the mpool before we ditch it */
mp_p
->
mp_magic
=
0
;
mp_p
->
mp_magic2
=
0
;
/* if we are heavy packing then we need to free the 1st block later */
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_HEAVY_PACKING
))
{
addr
=
(
char
*
)
mp_p
-
sizeof
(
mpool_block_t
);
}
else
{
addr
=
mp_p
;
}
size
=
SIZE_OF_PAGES
(
mp_p
,
PAGES_IN_SIZE
(
mp_p
,
sizeof
(
mpool_t
)));
mpool_block_t
*
block_p
,
*
next_p
;
void
*
addr
;
unsigned
long
size
;
int
ret
,
final
=
MPOOL_ERROR_NONE
;
/* special case, just return no-error */
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_CLOSE
,
0
,
0
,
NULL
,
NULL
,
0
);
}
/*
* NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
* header is not on the linked list.
*/
/* free/invalidate the blocks */
for
(
block_p
=
mp_p
->
mp_first_p
;
block_p
!=
NULL
;
block_p
=
next_p
)
{
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
final
=
MPOOL_ERROR_POOL_OVER
;
break
;
}
block_p
->
mb_magic
=
0
;
block_p
->
mb_magic2
=
0
;
/* record the next pointer because it might be invalidated below */
next_p
=
block_p
->
mb_next_p
;
ret
=
free_pages
(
block_p
,
(
char
*
)
block_p
->
mb_bounds_p
-
(
char
*
)
block_p
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
final
=
ret
;
}
}
/* close /dev/zero if necessary */
if
(
mp_p
->
mp_fd
>=
0
)
{
(
void
)
close
(
mp_p
->
mp_fd
);
mp_p
->
mp_fd
=
-
1
;
}
/* invalidate the mpool before we ditch it */
mp_p
->
mp_magic
=
0
;
mp_p
->
mp_magic2
=
0
;
/* if we are heavy packing then we need to free the 1st block later */
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_HEAVY_PACKING
))
{
addr
=
(
char
*
)
mp_p
-
sizeof
(
mpool_block_t
);
}
else
{
addr
=
mp_p
;
}
size
=
SIZE_OF_PAGES
(
mp_p
,
PAGES_IN_SIZE
(
mp_p
,
sizeof
(
mpool_t
)));
printf
(
"WTF
\n
"
);
(
void
)
munmap
(
addr
,
size
);
(
void
)
munmap
(
addr
,
size
);
return
final
;
return
final
;
}
/*
...
...
@@ -1134,52 +1133,52 @@ int mpool_close(mpool_t *mp_p)
*
* mp_p <-> Pointer to our memory pool.
*/
int
mpool_clear
(
mpool_t
*
mp_p
)
int
mpool_clear
(
mpool_t
*
mp_p
)
{
mpool_block_t
*
block_p
;
int
final
=
MPOOL_ERROR_NONE
,
bit_n
,
ret
;
void
*
first_p
;
/* special case, just return no-error */
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_CLEAR
,
0
,
0
,
NULL
,
NULL
,
0
);
}
/* reset all of our free lists */
for
(
bit_n
=
0
;
bit_n
<=
MAX_BITS
;
bit_n
++
)
{
mp_p
->
mp_free
[
bit_n
]
=
NULL
;
}
/* free the blocks */
for
(
block_p
=
mp_p
->
mp_first_p
;
block_p
!=
NULL
;
block_p
=
block_p
->
mb_next_p
)
{
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
final
=
MPOOL_ERROR_POOL_OVER
;
break
;
}
mpool_block_t
*
block_p
;
int
final
=
MPOOL_ERROR_NONE
,
bit_n
,
ret
;
void
*
first_p
;
/* special case, just return no-error */
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_CLEAR
,
0
,
0
,
NULL
,
NULL
,
0
);
}
/* reset all of our free lists */
for
(
bit_n
=
0
;
bit_n
<=
MAX_BITS
;
bit_n
++
)
{
mp_p
->
mp_free
[
bit_n
]
=
NULL
;
}
/* free the blocks */
for
(
block_p
=
mp_p
->
mp_first_p
;
block_p
!=
NULL
;
block_p
=
block_p
->
mb_next_p
)
{
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
final
=
MPOOL_ERROR_POOL_OVER
;
break
;
}
first_p
=
FIRST_ADDR_IN_BLOCK
(
block_p
);
first_p
=
FIRST_ADDR_IN_BLOCK
(
block_p
);
/* free the memory */
ret
=
free_pointer
(
mp_p
,
first_p
,
MEMORY_IN_BLOCK
(
block_p
));
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
final
=
ret
;
}
}
return
final
;
/* free the memory */
ret
=
free_pointer
(
mp_p
,
first_p
,
MEMORY_IN_BLOCK
(
block_p
));
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
final
=
ret
;
}
}
return
final
;
}
/*
...
...
@@ -1205,45 +1204,45 @@ int mpool_clear(mpool_t *mp_p)
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
void
*
mpool_alloc
(
mpool_t
*
mp_p
,
const
unsigned
long
byte_size
,
int
*
error_p
)
void
*
mpool_alloc
(
mpool_t
*
mp_p
,
const
unsigned
long
byte_size
,
int
*
error_p
)
{
void
*
addr
;
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal malloc */
addr
=
(
void
*
)
malloc
(
byte_size
);
if
(
addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ALLOC
);
return
NULL
;
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
addr
;
}
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PNT
);
return
NULL
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
if
(
byte_size
==
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
addr
=
alloc_mem
(
mp_p
,
byte_size
,
error_p
);
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_ALLOC
,
byte_size
,
0
,
addr
,
NULL
,
0
);
}
return
addr
;
void
*
addr
;
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal malloc */
addr
=
(
void
*
)
malloc
(
byte_size
);
if
(
addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ALLOC
);
return
NULL
;
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
addr
;
}
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PNT
);
return
NULL
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
if
(
byte_size
==
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
addr
=
alloc_mem
(
mp_p
,
byte_size
,
error_p
);
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_ALLOC
,
byte_size
,
0
,
addr
,
NULL
,
0
);
}
return
addr
;
}
/*
...
...
@@ -1272,51 +1271,51 @@ void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size,
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
void
*
mpool_calloc
(
mpool_t
*
mp_p
,
const
unsigned
long
ele_n
,
const
unsigned
long
ele_size
,
int
*
error_p
)
void
*
mpool_calloc
(
mpool_t
*
mp_p
,
const
unsigned
long
ele_n
,
const
unsigned
long
ele_size
,
int
*
error_p
)
{
void
*
addr
;
unsigned
long
byte_size
;
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal calloc */
addr
=
(
void
*
)
calloc
(
ele_n
,
ele_size
);
if
(
addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ALLOC
);
return
NULL
;
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
addr
;
}
void
*
addr
;
unsigned
long
byte_size
;
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal calloc */
addr
=
(
void
*
)
calloc
(
ele_n
,
ele_size
);
if
(
addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ALLOC
);
return
NULL
;
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
addr
;
}
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PNT
);
return
NULL
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
if
(
ele_n
==
0
||
ele_size
==
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
byte_size
=
ele_n
*
ele_size
;
addr
=
alloc_mem
(
mp_p
,
byte_size
,
error_p
);
if
(
addr
!=
NULL
)
{
memset
(
addr
,
0
,
byte_size
);
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_CALLOC
,
ele_size
,
ele_n
,
addr
,
NULL
,
0
);
}
/* NOTE: error_p set above */
return
addr
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PNT
);
return
NULL
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
if
(
ele_n
==
0
||
ele_size
==
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
byte_size
=
ele_n
*
ele_size
;
addr
=
alloc_mem
(
mp_p
,
byte_size
,
error_p
);
if
(
addr
!=
NULL
)
{
memset
(
addr
,
0
,
byte_size
);
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_CALLOC
,
ele_size
,
ele_n
,
addr
,
NULL
,
0
);
}
/* NOTE: error_p set above */
return
addr
;
}
/*
...
...
@@ -1341,32 +1340,32 @@ void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n,
*
* size -> Size of the address being freed.
*/
int
mpool_free
(
mpool_t
*
mp_p
,
void
*
addr
,
const
unsigned
long
size
)
int
mpool_free
(
mpool_t
*
mp_p
,
void
*
addr
,
const
unsigned
long
size
)
{
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal free */
free
(
addr
);
return
MPOOL_ERROR_NONE
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_FREE
,
size
,
0
,
NULL
,
addr
,
0
);
}
if
(
addr
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
size
==
0
)
{
return
MPOOL_ERROR_ARG_INVALID
;
}
return
free_mem
(
mp_p
,
addr
,
size
);
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal free */
free
(
addr
);
return
MPOOL_ERROR_NONE
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_FREE
,
size
,
0
,
NULL
,
addr
,
0
);
}
if
(
addr
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
size
==
0
)
{
return
MPOOL_ERROR_ARG_INVALID
;
}
return
free_mem
(
mp_p
,
addr
,
size
);
}
/*
...
...
@@ -1400,127 +1399,127 @@ int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size)
* error_p <- Pointer to integer which, if not NULL, will be set with
* a mpool error code.
*/
void
*
mpool_resize
(
mpool_t
*
mp_p
,
void
*
old_addr
,
const
unsigned
long
old_byte_size
,
const
unsigned
long
new_byte_size
,
int
*
error_p
)
void
*
mpool_resize
(
mpool_t
*
mp_p
,
void
*
old_addr
,
const
unsigned
long
old_byte_size
,
const
unsigned
long
new_byte_size
,
int
*
error_p
)
{
unsigned
long
copy_size
,
new_size
,
old_size
,
fence
;
void
*
new_addr
;
mpool_block_t
*
block_p
;
int
ret
;
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal realloc */
new_addr
=
(
void
*
)
realloc
(
old_addr
,
new_byte_size
);
if
(
new_addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ALLOC
);
return
NULL
;
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
new_addr
;
}
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PNT
);
return
NULL
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
if
(
old_addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_NULL
);
return
NULL
;
}
if
(
old_byte_size
==
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
/*
* If the size is larger than a block then the allocation must be at
* the front of the block.
*/
if
(
old_byte_size
>
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
block_p
=
(
mpool_block_t
*
)((
char
*
)
old_addr
-
sizeof
(
mpool_block_t
));
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
}
/* make sure we have enough bytes */
if
(
old_byte_size
<
MIN_ALLOCATION
)
{
old_size
=
MIN_ALLOCATION
;
}
else
{
old_size
=
old_byte_size
;
}
/* verify that the size matches exactly if we can */
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
fence
=
0
;
}
else
if
(
old_size
>
0
)
{
ret
=
check_magic
(
old_addr
,
old_size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
fence
=
FENCE_SIZE
;
}
/* make sure we have enough bytes */
if
(
new_byte_size
<
MIN_ALLOCATION
)
{
new_size
=
MIN_ALLOCATION
;
}
else
{
new_size
=
new_byte_size
;
}
/*
* NOTE: we could here see if the size is the same or less and then
* use the current memory and free the space above. This is harder
* than it sounds if we are changing the block size of the
* allocation.
*/
/* we need to get another address */
new_addr
=
alloc_mem
(
mp_p
,
new_byte_size
,
error_p
);
if
(
new_addr
==
NULL
)
{
/* error_p set in mpool_alloc */
return
NULL
;
}
if
(
new_byte_size
>
old_byte_size
)
{
copy_size
=
old_byte_size
;
}
else
{
copy_size
=
new_byte_size
;
}
memcpy
(
new_addr
,
old_addr
,
copy_size
);
/* free the old address */
ret
=
free_mem
(
mp_p
,
old_addr
,
old_byte_size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
/* if the old free failed, try and free the new address */
(
void
)
free_mem
(
mp_p
,
new_addr
,
new_byte_size
);
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_RESIZE
,
new_byte_size
,
0
,
new_addr
,
old_addr
,
old_byte_size
);
}
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
new_addr
;
unsigned
long
copy_size
,
new_size
,
old_size
,
fence
;
void
*
new_addr
;
mpool_block_t
*
block_p
;
int
ret
;
if
(
mp_p
==
NULL
)
{
/* special case -- do a normal realloc */
new_addr
=
(
void
*
)
realloc
(
old_addr
,
new_byte_size
);
if
(
new_addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ALLOC
);
return
NULL
;
}
else
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
new_addr
;
}
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_PNT
);
return
NULL
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
if
(
old_addr
==
NULL
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_NULL
);
return
NULL
;
}
if
(
old_byte_size
==
0
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_ARG_INVALID
);
return
NULL
;
}
/*
* If the size is larger than a block then the allocation must be at
* the front of the block.
*/
if
(
old_byte_size
>
MAX_BLOCK_USER_MEMORY
(
mp_p
))
{
block_p
=
(
mpool_block_t
*
)((
char
*
)
old_addr
-
sizeof
(
mpool_block_t
));
if
(
block_p
->
mb_magic
!=
BLOCK_MAGIC
||
block_p
->
mb_magic2
!=
BLOCK_MAGIC
)
{
SET_POINTER
(
error_p
,
MPOOL_ERROR_POOL_OVER
);
return
NULL
;
}
}
/* make sure we have enough bytes */
if
(
old_byte_size
<
MIN_ALLOCATION
)
{
old_size
=
MIN_ALLOCATION
;
}
else
{
old_size
=
old_byte_size
;
}
/* verify that the size matches exactly if we can */
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_NO_FREE
))
{
fence
=
0
;
}
else
if
(
old_size
>
0
)
{
ret
=
check_magic
(
old_addr
,
old_size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
fence
=
FENCE_SIZE
;
}
/* make sure we have enough bytes */
if
(
new_byte_size
<
MIN_ALLOCATION
)
{
new_size
=
MIN_ALLOCATION
;
}
else
{
new_size
=
new_byte_size
;
}
/*
* NOTE: we could here see if the size is the same or less and then
* use the current memory and free the space above. This is harder
* than it sounds if we are changing the block size of the
* allocation.
*/
/* we need to get another address */
new_addr
=
alloc_mem
(
mp_p
,
new_byte_size
,
error_p
);
if
(
new_addr
==
NULL
)
{
/* error_p set in mpool_alloc */
return
NULL
;
}
if
(
new_byte_size
>
old_byte_size
)
{
copy_size
=
old_byte_size
;
}
else
{
copy_size
=
new_byte_size
;
}
memcpy
(
new_addr
,
old_addr
,
copy_size
);
/* free the old address */
ret
=
free_mem
(
mp_p
,
old_addr
,
old_byte_size
);
if
(
ret
!=
MPOOL_ERROR_NONE
)
{
/* if the old free failed, try and free the new address */
(
void
)
free_mem
(
mp_p
,
new_addr
,
new_byte_size
);
SET_POINTER
(
error_p
,
ret
);
return
NULL
;
}
if
(
mp_p
->
mp_log_func
!=
NULL
)
{
mp_p
->
mp_log_func
(
mp_p
,
MPOOL_FUNC_RESIZE
,
new_byte_size
,
0
,
new_addr
,
old_addr
,
old_byte_size
);
}
SET_POINTER
(
error_p
,
MPOOL_ERROR_NONE
);
return
new_addr
;
}
/*
...
...
@@ -1557,29 +1556,29 @@ void *mpool_resize(mpool_t *mp_p, void *old_addr,
* will be set to the total amount of space (including administrative
* overhead) used by the pool.
*/
int
mpool_stats
(
const
mpool_t
*
mp_p
,
unsigned
int
*
page_size_p
,
unsigned
long
*
num_alloced_p
,
unsigned
long
*
user_alloced_p
,
unsigned
long
*
max_alloced_p
,
unsigned
long
*
tot_alloced_p
)
int
mpool_stats
(
const
mpool_t
*
mp_p
,
unsigned
int
*
page_size_p
,
unsigned
long
*
num_alloced_p
,
unsigned
long
*
user_alloced_p
,
unsigned
long
*
max_alloced_p
,
unsigned
long
*
tot_alloced_p
)
{
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
SET_POINTER
(
page_size_p
,
mp_p
->
mp_page_size
);
SET_POINTER
(
num_alloced_p
,
mp_p
->
mp_alloc_c
);
SET_POINTER
(
user_alloced_p
,
mp_p
->
mp_user_alloc
);
SET_POINTER
(
max_alloced_p
,
mp_p
->
mp_max_alloc
);
SET_POINTER
(
tot_alloced_p
,
SIZE_OF_PAGES
(
mp_p
,
mp_p
->
mp_page_c
));
return
MPOOL_ERROR_NONE
;
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
SET_POINTER
(
page_size_p
,
mp_p
->
mp_page_size
);
SET_POINTER
(
num_alloced_p
,
mp_p
->
mp_alloc_c
);
SET_POINTER
(
user_alloced_p
,
mp_p
->
mp_user_alloc
);
SET_POINTER
(
max_alloced_p
,
mp_p
->
mp_max_alloc
);
SET_POINTER
(
tot_alloced_p
,
SIZE_OF_PAGES
(
mp_p
,
mp_p
->
mp_page_c
));
return
MPOOL_ERROR_NONE
;
}
/*
...
...
@@ -1603,21 +1602,21 @@ int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p,
* log_func -> Log function (defined in mpool.h) which will be called
* with each mpool transaction.
*/
int
mpool_set_log_func
(
mpool_t
*
mp_p
,
mpool_log_func_t
log_func
)
int
mpool_set_log_func
(
mpool_t
*
mp_p
,
mpool_log_func_t
log_func
)
{
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
mp_p
->
mp_log_func
=
log_func
;
return
MPOOL_ERROR_NONE
;
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
mp_p
->
mp_log_func
=
log_func
;
return
MPOOL_ERROR_NONE
;
}
/*
...
...
@@ -1645,30 +1644,30 @@ int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func)
*
* max_pages -> Maximum number of pages used by the library.
*/
int
mpool_set_max_pages
(
mpool_t
*
mp_p
,
const
unsigned
int
max_pages
)
int
mpool_set_max_pages
(
mpool_t
*
mp_p
,
const
unsigned
int
max_pages
)
{
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_HEAVY_PACKING
))
{
mp_p
->
mp_max_pages
=
max_pages
;
}
else
{
/*
* If we are not heavy-packing the pool then we don't count the
* 1st page allocated which holds the mpool header structure.
*/
mp_p
->
mp_max_pages
=
max_pages
+
1
;
}
return
MPOOL_ERROR_NONE
;
if
(
mp_p
==
NULL
)
{
return
MPOOL_ERROR_ARG_NULL
;
}
if
(
mp_p
->
mp_magic
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_PNT
;
}
if
(
mp_p
->
mp_magic2
!=
MPOOL_MAGIC
)
{
return
MPOOL_ERROR_POOL_OVER
;
}
if
(
BIT_IS_SET
(
mp_p
->
mp_flags
,
MPOOL_FLAG_HEAVY_PACKING
))
{
mp_p
->
mp_max_pages
=
max_pages
;
}
else
{
/*
* If we are not heavy-packing the pool then we don't count the
* 1st page allocated which holds the mpool header structure.
*/
mp_p
->
mp_max_pages
=
max_pages
+
1
;
}
return
MPOOL_ERROR_NONE
;
}
/*
...
...
@@ -1688,74 +1687,74 @@ int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages)
*
* error -> Error number that we are converting.
*/
const
char
*
mpool_strerror
(
const
int
error
)
const
char
*
mpool_strerror
(
const
int
error
)
{
switch
(
error
)
{
case
MPOOL_ERROR_NONE
:
return
"no error"
;
break
;
case
MPOOL_ERROR_ARG_NULL
:
return
"function argument is null"
;
break
;
case
MPOOL_ERROR_ARG_INVALID
:
return
"function argument is invalid"
;
break
;
case
MPOOL_ERROR_PNT
:
return
"invalid mpool pointer"
;
break
;
case
MPOOL_ERROR_POOL_OVER
:
return
"mpool structure was overwritten"
;
break
;
case
MPOOL_ERROR_PAGE_SIZE
:
return
"could not get system page-size"
;
break
;
case
MPOOL_ERROR_OPEN_ZERO
:
return
"could not open /dev/zero"
;
break
;
case
MPOOL_ERROR_NO_MEM
:
return
"no memory available"
;
break
;
case
MPOOL_ERROR_MMAP
:
return
"problems with mmap"
;
break
;
case
MPOOL_ERROR_SIZE
:
return
"error processing requested size"
;
break
;
case
MPOOL_ERROR_TOO_BIG
:
return
"allocation exceeds pool max size"
;
break
;
case
MPOOL_ERROR_MEM
:
return
"invalid memory address"
;
break
;
case
MPOOL_ERROR_MEM_OVER
:
return
"memory lower bounds overwritten"
;
break
;
case
MPOOL_ERROR_NOT_FOUND
:
return
"memory block not found in pool"
;
break
;
case
MPOOL_ERROR_IS_FREE
:
return
"memory address has already been freed"
;
break
;
case
MPOOL_ERROR_BLOCK_STAT
:
return
"invalid internal block status"
;
break
;
case
MPOOL_ERROR_FREE_ADDR
:
return
"invalid internal free address"
;
break
;
case
MPOOL_ERROR_NO_PAGES
:
return
"no available pages left in pool"
;
break
;
case
MPOOL_ERROR_ALLOC
:
return
"system alloc function failed"
;
break
;
case
MPOOL_ERROR_PNT_OVER
:
return
"user pointer admin space overwritten"
;
break
;
default:
break
;
}
return
"invalid error code"
;
switch
(
error
)
{
case
MPOOL_ERROR_NONE
:
return
"no error"
;
break
;
case
MPOOL_ERROR_ARG_NULL
:
return
"function argument is null"
;
break
;
case
MPOOL_ERROR_ARG_INVALID
:
return
"function argument is invalid"
;
break
;
case
MPOOL_ERROR_PNT
:
return
"invalid mpool pointer"
;
break
;
case
MPOOL_ERROR_POOL_OVER
:
return
"mpool structure was overwritten"
;
break
;
case
MPOOL_ERROR_PAGE_SIZE
:
return
"could not get system page-size"
;
break
;
case
MPOOL_ERROR_OPEN_ZERO
:
return
"could not open /dev/zero"
;
break
;
case
MPOOL_ERROR_NO_MEM
:
return
"no memory available"
;
break
;
case
MPOOL_ERROR_MMAP
:
return
"problems with mmap"
;
break
;
case
MPOOL_ERROR_SIZE
:
return
"error processing requested size"
;
break
;
case
MPOOL_ERROR_TOO_BIG
:
return
"allocation exceeds pool max size"
;
break
;
case
MPOOL_ERROR_MEM
:
return
"invalid memory address"
;
break
;
case
MPOOL_ERROR_MEM_OVER
:
return
"memory lower bounds overwritten"
;
break
;
case
MPOOL_ERROR_NOT_FOUND
:
return
"memory block not found in pool"
;
break
;
case
MPOOL_ERROR_IS_FREE
:
return
"memory address has already been freed"
;
break
;
case
MPOOL_ERROR_BLOCK_STAT
:
return
"invalid internal block status"
;
break
;
case
MPOOL_ERROR_FREE_ADDR
:
return
"invalid internal free address"
;
break
;
case
MPOOL_ERROR_NO_PAGES
:
return
"no available pages left in pool"
;
break
;
case
MPOOL_ERROR_ALLOC
:
return
"system alloc function failed"
;
break
;
case
MPOOL_ERROR_PNT_OVER
:
return
"user pointer admin space overwritten"
;
break
;
default:
break
;
}
return
"invalid error code"
;
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论