zoukankan
html css js c++ java
MemMan 3 beta
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEM_MAN__
#define
__MEM_MAN__
#include
<
vector
>
#include
<
algorithm
>
#include
<
malloc.h
>
#pragma pack(push,
1
)
namespace
mem
{
#define
mem_inline __forceinline
#define
mem_page_size ( 1 << 18 )
#define
mem_align_size 16
#define
mem_align __declspec( align( mem_align_size ) )
typedef unsigned
int
prior_type;
typedef unsigned
long
time_type;
typedef unsigned
long
size_type;
typedef unsigned
char
byte
;
#define
mem_max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
#define
mem_min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
enum
{
ENTRY_PRIORITY
=
0
,
}
;
class
heap
{
public
:
mem_inline heap( size_type max_size )
{
allocated_size
=
0
;
available_size
=
max_size;
}
mem_inline
~
heap()
{
}
mem_inline
void
*
alloc( size_type size )
{
if
( size
==
0
)
return
NULL;
allocated_size
+=
size;
available_size
-=
size;
return
sys_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
if
( ptr
&&
size
!=
0
)
{
sys_dealloc( ptr );
allocated_size
-=
size;
available_size
+=
size;
}
}
mem_inline
void
*
aligned_alloc( size_type size )
{
if
( size
==
0
)
return
NULL;
allocated_size
+=
size;
available_size
-=
size;
return
sys_aligned_alloc( size );
}
mem_inline
void
aligned_dealloc(
void
*
ptr, size_type size )
{
if
( ptr
&&
size
!=
0
)
{
sys_aligned_dealloc( ptr );
allocated_size
-=
size;
available_size
+=
size;
}
}
mem_inline size_type available()
{
return
available_size;
}
private
:
mem_inline
void
*
sys_alloc( size_type size )
{
return
malloc( size );
}
mem_inline
void
sys_dealloc(
void
*
ptr )
{
free( ptr );
}
mem_inline
void
*
sys_aligned_alloc( size_type size )
{
return
_aligned_malloc( size, mem_align_size );
}
mem_inline
void
sys_aligned_dealloc(
void
*
ptr )
{
_aligned_free( ptr );
}
private
:
size_type allocated_size,
available_size;
}
;
extern
heap
*
g_heap;
class
allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
g_heap
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
g_heap
->
dealloc( ptr, size );
}
mem_inline size_type available()
{
return
g_heap
->
available();
}
}
;
class
aligned_allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
g_heap
->
aligned_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
g_heap
->
aligned_dealloc( ptr, size );
}
mem_inline size_type available()
{
return
g_heap
->
available();
}
}
;
template
<
typename ALLOC
=
allocator
>
class
pool;
template
<
typename ALLOC
=
allocator
>
class
entry
{
public
:
mem_inline entry()
{
priority
=
ENTRY_PRIORITY;
last_use_time
=
pl.get_current_time();
locked
=
false
;
}
mem_inline
virtual
~
entry()
{
}
mem_inline
void
*
alloc( size_type size )
{
return
pl.alloc( size,
this
);
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
pl.dealloc( ptr, size,
this
);
}
mem_inline
void
stream_begin()
{
locked
=
true
;
stream_in();
last_use_time
=
pl.get_current_time();
}
mem_inline
void
stream_end()
{
locked
=
false
;
}
mem_inline
bool
is_locked()
{
return
locked;
}
mem_inline
bool
operator
<
(
const
entry
<
ALLOC
>
&
right )
const
{
if
( priority
==
right.priority )
return
( last_use_time
<
right.last_use_time );
else
return
( priority
<
right.priority );
}
public
:
#ifdef _DEBUG
virtual
void
stream_in()
=
0
;
#endif
virtual
bool
stream_out(
void
*
&
ptr, size_type size )
=
0
;
public
:
static
pool
<
ALLOC
>
pl;
prior_type priority;
time_type last_use_time;
bool
locked;
}
;
template
<
typename ALLOC
>
mem_inline
bool
compare_entry(
const
entry
<
ALLOC
>
*
left,
const
entry
<
ALLOC
>
*
right )
{
return
(
*
left
<
*
right );
}
template
<
typename ALLOC
>
class
pool
{
private
:
class
page
{
public
:
mem_inline page( size_type _size, page
*
old )
{
size
=
_size;
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline
~
page()
{
}
mem_inline
void
recycle( page
*
old )
{
void
*
ptr
=
NULL;
for
( std::vector
<
entry
<
ALLOC
>
*
>
::iterator i
=
ents.begin();
i
!=
ents.end();
++
i )
{
(
*
i)
->
stream_out( ptr,
0
);
}
ents.clear();
size
=
get_size();
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline
byte
*
get_base()
{
return
(
byte
*
)
this
+
sizeof
(page);
}
mem_inline size_type get_size()
{
return
static_cast
<
size_type
>
(
base
-
get_base()
+
size );
}
mem_inline size_type available()
{
return
size;
}
mem_inline
void
*
alloc( size_type req_size, entry
<
ALLOC
>
*
obj )
{
void
*
ptr
=
(
void
*
)
base
;
base
+=
req_size;
size
-=
req_size;
ents.push_back( obj );
return
ptr;
}
mem_inline time_type priority()
const
{
time_type last_use_time
=
0
;
for
( std::vector
<
entry
<
ALLOC
>
*
>
::const_iterator i
=
ents.begin();
i
!=
ents.end();
++
i )
{
last_use_time
+=
(
*
i)
->
last_use_time;
}
last_use_time
/=
static_cast
<
time_type
>
( ents.size() );
return
last_use_time;
}
mem_inline
bool
operator
<
(
const
page
&
right )
const
{
return
( priority()
<
right.priority() );
}
public
:
mem_align
struct
{
byte
*
base
;
page
*
next;
page
*
prev;
size_type size;
std::vector
<
entry
<
ALLOC
>
*
>
ents;
}
;
}
;
class
chunk
{
public
:
mem_inline chunk( size_type _size, chunk
*
old )
{
size
=
_size;
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline size_type available()
{
return
size;
}
public
:
chunk
*
next;
chunk
*
prev;
size_type size;
}
;
public
:
mem_inline pool()
{
current_time
=
0
;
pages
=
NULL;
chunks
=
NULL;
allocated
=
0
;
}
mem_inline
~
pool()
{
destory();
}
mem_inline time_type get_current_time()
{
return
(
++
current_time );
}
mem_inline
void
*
alloc( size_type size, entry
<
ALLOC
>
*
obj )
{
void
*
ptr
=
NULL;
++
allocated;
if
( search_chunk( ptr, size ) )
return
ptr;
else
if
( search_page( ptr, size, obj ) )
return
ptr;
else
if
( (size
+
sizeof
(page))
>
al.available() )
{
if
( search_entry( ptr, size, obj ) )
return
ptr;
else
{
recycle_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
return
NULL;
}
}
else
{
allocate_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
return
NULL;
}
}
mem_inline
void
dealloc(
void
*
ptr, size_type size, entry
<
ALLOC
>
*
obj )
{
--
allocated;
for
( std::vector
<
entry
<
ALLOC
>
*
>
::iterator i
=
g_ents.begin();
i
!=
g_ents.end();
++
i )
{
if
( obj
==
*
i )
{
g_ents.erase( i );
break
;
}
}
if
( size
>=
sizeof
(chunk) )
chunks
=
new
(ptr) chunk( size, chunks );
if
( allocated
==
0
)
destory();
}
private
:
mem_inline
void
destory()
{
page
*
p
=
pages;
while
( p )
{
pages
=
p
->
next;
p
->~
page();
al.dealloc( p, p
->
get_size() );
p
=
pages;
}
chunks
=
NULL;
g_ents.clear();
}
mem_inline
bool
search_chunk(
void
*
&
ptr, size_type size )
{
chunk
*
p
=
chunks;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
(
void
*
) p;
if
( p
->
prev )
p
->
prev
->
next
=
p
->
next;
if
( p
->
next )
p
->
next
->
prev
=
p
->
prev;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline
bool
search_page(
void
*
&
ptr, size_type size, entry
<
ALLOC
>
*
obj )
{
page
*
p
=
pages;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
p
->
alloc( size, obj );
g_ents.push_back( obj );
if
( p
->
prev )
p
->
prev
->
next
=
p
->
next;
if
( p
->
next )
p
->
next
->
prev
=
p
->
prev;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline
bool
search_entry(
void
*
&
ptr, size_type size, entry
<
ALLOC
>
*
obj )
{
std::sort( g_ents.begin(), g_ents.end(), compare_entry
<
ALLOC
>
);
for
( std::vector
<
entry
<
ALLOC
>
*
>
::iterator i
=
g_ents.begin();
i
!=
g_ents.end();
++
i )
{
if
(
!
(
*
i)
->
is_locked()
&&
(
*
i)
->
stream_out( ptr, size ) )
{
*
i
=
obj;
return
true
;
}
}
return
false
;
}
mem_inline
void
recycle_page( size_type size )
{
if
( pages )
{
page
*
p,
*
old;
old
=
pages;
p
=
pages
->
next;
while
( p )
{
if
(
*
p
<
*
old )
old
=
p;
p
=
p
->
next;
}
if
( old
->
prev )
old
->
prev
->
next
=
old
->
next;
if
( old
->
next )
old
->
next
->
prev
=
old
->
prev;
old
->
recycle( pages );
pages
=
old;
}
}
mem_inline
void
allocate_page( size_type size )
{
size_type asize
=
mem_min( mem_max(
sizeof
(page)
+
size, mem_page_size ), al.available() );
pages
=
new
(al.alloc( asize )) page( asize
-
sizeof
(page), pages );
}
private
:
time_type current_time;
time_type allocated;
ALLOC al;
std::vector
<
entry
<
ALLOC
>
*
>
g_ents;
page
*
pages;
chunk
*
chunks;
}
;
}
//
namespace mem
#pragma pack(pop)
#endif
//
__MEM_MAN__
查看全文
相关阅读:
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
牛客网每日一练
原文地址:https://www.cnblogs.com/len3d/p/988562.html
最新文章
php分页
[转]PHP页面间参数传递的四种方式
php操作json小结
JS获取表格行数和列数
ubuntu php访问带apache2基本认证的页面
php导出Excel
ASP导出Excel
如何处理系统异常
跟踪用户的更改/删除历史
BAPI List
热门文章
程序之间的调用
金额转换大写
ALV增加勾选框及修改数据和颜色
Query 操作手册 (新增逻辑数据库)
转:在ABAP中实现进度条的例子
ABAP数据库操作
tabcontrol 中 需要修改后才能传入到内表中
spring成神之路第三十一篇:aop 概念详解
spring成神之路第三十三篇:ProxyFactoryBean 创建 AOP 代理
spring成神之路第三十二篇:AOP 核心源码、原理详解
Copyright © 2011-2022 走看看