zoukankan
html css js c++ java
MemMan 3 beta 2
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEMMAN__
#define
__MEMMAN__
#include
<
malloc.h
>
#pragma pack(push,
1
)
namespace
mem
{
#define
mem_inline __forceinline
#define
mem_page_pad 48
#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;
}
;
template
<
typename ALLOC
>
class
pool
{
public
:
class
node;
class
entry
{
public
:
mem_inline entry()
{
priority
=
ENTRY_PRIORITY;
last_use_time
=
pl.get_current_time();
locked
=
false
;
node_ptr
=
NULL;
}
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
&
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;
node
*
node_ptr;
}
;
class
node
{
public
:
mem_inline node( entry
*
obj, node
*
old, node
*
g_old, node
*
phead, node
*
g_phead )
{
ptr
=
obj;
obj
->
node_ptr
=
this
;
next
=
old;
prev
=
phead;
g_next
=
g_old;
g_prev
=
g_phead;
if
( next )
next
->
prev
=
this
;
if
( g_next )
g_next
->
g_prev
=
this
;
}
mem_inline node()
{
ptr
=
NULL;
next
=
NULL;
prev
=
NULL;
g_next
=
NULL;
g_prev
=
NULL;
}
mem_inline
~
node()
{
void
*
p
=
NULL;
stream_out( p,
0
);
}
mem_inline time_type get_last_use_time()
{
if
( ptr )
return
ptr
->
last_use_time;
else
return
0
;
}
mem_inline
bool
is_locked()
{
if
( ptr )
return
ptr
->
is_locked();
else
return
false
;
}
mem_inline
bool
stream_out(
void
*
&
p, size_type size )
{
if
( ptr )
{
bool
bret
=
ptr
->
stream_out( p, size );
if
( bret )
ptr
->
node_ptr
=
NULL;
return
bret;
}
else
return
false
;
}
mem_inline
void
detach()
{
if
( prev )
prev
->
next
=
next;
if
( next )
next
->
prev
=
prev;
if
( g_prev )
g_prev
->
g_next
=
g_next;
if
( g_next )
g_next
->
g_prev
=
g_prev;
}
public
:
entry
*
ptr;
node
*
next,
*
prev;
node
*
g_next,
*
g_prev;
}
;
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
;
num_nodes
=
0
;
}
mem_inline
~
page()
{
node
*
p
=
head.next;
while
( p )
{
head.next
=
p
->
next;
p
->
detach();
delete p;
p
=
head.next;
}
}
mem_inline
void
recycle( page
*
old )
{
node
*
p
=
head.next;
while
( p )
{
head.next
=
p
->
next;
p
->
detach();
delete p;
p
=
head.next;
}
head.next
=
NULL;
size
=
get_size();
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
num_nodes
=
0
;
}
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 )
{
void
*
ptr
=
(
void
*
)
base
;
base
+=
req_size;
size
-=
req_size;
return
ptr;
}
mem_inline time_type priority()
const
{
time_type last_use_time
=
0
;
node
*
p
=
head.next;
while
( p )
{
last_use_time
+=
p
->
get_last_use_time();
p
=
p
->
next;
}
last_use_time
/=
static_cast
<
time_type
>
( num_nodes );
return
last_use_time;
}
mem_inline
bool
operator
<
(
const
page
&
right )
const
{
return
( priority()
<
right.priority() );
}
public
:
mem_align union
{
struct
{
byte
*
base
;
page
*
next;
page
*
prev;
size_type size;
node head;
size_type num_nodes;
}
;
byte
pad[mem_page_pad];
}
;
}
;
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
*
obj )
{
void
*
ptr
=
NULL;
++
allocated;
obj
->
node_ptr
=
NULL;
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
*
obj )
{
--
allocated;
if
( obj
->
node_ptr )
{
obj
->
node_ptr
->
detach();
delete obj
->
node_ptr;
obj
->
node_ptr
=
NULL;
}
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;
}
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
*
obj )
{
page
*
p
=
pages;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
p
->
alloc( size );
p
->
head.next
=
g_head.next
=
new
node( obj, p
->
head.next, g_head.next,
&
p
->
head,
&
g_head );
++
p
->
num_nodes;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline node
*
node_sort( node
*
p )
{
return
p;
}
mem_inline
bool
search_entry(
void
*
&
ptr, size_type size, entry
*
obj )
{
g_head.g_next
=
node_sort( g_head.g_next );
node
*
p
=
g_head.g_next;
while
( p )
{
if
(
!
p
->
is_locked()
&&
p
->
stream_out( ptr, size ) )
{
p
->
ptr
=
obj;
obj
->
node_ptr
=
p;
return
true
;
}
p
=
p
->
g_next;
}
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;
node g_head;
page
*
pages;
chunk
*
chunks;
}
;
class
man
{
public
:
mem_inline man()
{
m_heap
=
NULL;
}
mem_inline
~
man()
{
if
( m_heap )
delete m_heap;
}
mem_inline
void
begin( size_type heap_size )
{
if
( m_heap )
end();
m_heap
=
new
heap( heap_size );
}
mem_inline
void
end()
{
if
( m_heap )
{
delete m_heap;
m_heap
=
NULL;
}
}
public
:
static
heap
*
m_heap;
public
:
class
allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
m_heap
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
m_heap
->
dealloc( ptr, size );
}
mem_inline size_type available()
{
return
m_heap
->
available();
}
}
;
class
aligned_allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
m_heap
->
aligned_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
m_heap
->
aligned_dealloc( ptr, size );
}
mem_inline size_type available()
{
return
m_heap
->
available();
}
}
;
}
;
typedef pool
<
man::allocator
>
::entry resource;
typedef pool
<
man::aligned_allocator
>
::entry aligned_resource;
}
//
namespace mem
extern
mem::man memman;
#pragma pack(pop)
#endif
//
__MEMMAN__
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEMMAN_DEF__
#define
__MEMMAN_DEF__
#include
"
memman3.h
"
mem::man memman;
mem::heap
*
mem::man::m_heap;
mem::pool
<
mem::man::allocator
>
mem::pool
<
mem::man::allocator
>
::entry::pl;
mem::pool
<
mem::man::aligned_allocator
>
mem::pool
<
mem::man::aligned_allocator
>
::entry::pl;
#endif
//
__MEMMAN_DEF__
查看全文
相关阅读:
APP案例分析
第一次作业
第0次作业
结对编程-四则运算
韩剧TV APP案例分析
四则运算生成器(基于控制台)
大学
JAVA异常机制学习
散列学习
PAT 甲级1025 PAT Ranking的
原文地址:https://www.cnblogs.com/len3d/p/989986.html
最新文章
国内外云服务现状及发展探讨
(二). 细说Kalman滤波:The Kalman Filter
(一):细说贝叶斯滤波:Bayes filters
写一个普适计算(认知计算)课程的博客
HDU1598 并查集+枚举
HDU5792 树状数组
HDU1686 KMP模板
HDU1711-Number Sequence
Postman的基本使用
Monkey的基本使用
热门文章
Fiddler的基本使用
Charles的基本使用
ApacheBench测试Web并发
蓝桥杯-递归常用的几种套路
蓝桥杯-打印十字图
蓝桥杯-学校的第一次练习题
蓝桥杯-练习题(1017-1030)
蓝桥杯-练习题(1008-1016)
蓝桥杯-练习题(1000-1030)
结队项目1
Copyright © 2011-2022 走看看