Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
youngwolf
st_asio_wrapper
提交
3ce69fb3
S
st_asio_wrapper
项目概览
youngwolf
/
st_asio_wrapper
通知
10
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
st_asio_wrapper
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
3ce69fb3
编写于
8月 03, 2016
作者:
Y
youngwolf
提交者:
youngowlf
4月 27, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Memory pool optimization.
上级
7d0730d9
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
113 addition
and
74 deletion
+113
-74
asio_client/asio_client.cpp
asio_client/asio_client.cpp
+1
-1
asio_server/asio_server.cpp
asio_server/asio_server.cpp
+5
-1
include/ext/st_asio_wrapper_ext.h
include/ext/st_asio_wrapper_ext.h
+71
-49
include/ext/st_asio_wrapper_packer.h
include/ext/st_asio_wrapper_packer.h
+5
-5
include/ext/st_asio_wrapper_unpacker.h
include/ext/st_asio_wrapper_unpacker.h
+12
-12
include/st_asio_wrapper_base.h
include/st_asio_wrapper_base.h
+1
-0
pingpong_client/client.cpp
pingpong_client/client.cpp
+7
-3
pingpong_server/server.cpp
pingpong_server/server.cpp
+6
-2
test_client/test_client.cpp
test_client/test_client.cpp
+5
-1
未找到文件。
asio_client/asio_client.cpp
浏览文件 @
3ce69fb3
...
...
@@ -5,7 +5,7 @@
#define ST_ASIO_SERVER_PORT 9527
#define ST_ASIO_FORCE_TO_USE_MSG_RECV_BUFFER //force to use the msg recv buffer
#define ST_ASIO_CUSTOM_LOG
#define ST_ASIO_DEFAULT_UNPACKER
buffer_free
_unpacker
#define ST_ASIO_DEFAULT_UNPACKER
non_copy
_unpacker
//#define ST_ASIO_DEFAULT_UNPACKER stream_unpacker
//the following three macros demonstrate how to support huge msg(exceed 65535 - 2).
...
...
asio_server/asio_server.cpp
浏览文件 @
3ce69fb3
...
...
@@ -190,7 +190,7 @@ int main(int argc, const char* argv[])
printf
(
"normal server, link #: "
ST_ASIO_SF
", invalid links: "
ST_ASIO_SF
"
\n
"
,
server_
.
size
(),
server_
.
invalid_object_size
());
printf
(
"echo server, link #: "
ST_ASIO_SF
", invalid links: "
ST_ASIO_SF
"
\n
"
,
echo_server_
.
size
(),
echo_server_
.
invalid_object_size
());
#if 4 == PACKER_UNPACKER_TYPE
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
size
(),
pool
.
buffer_size
());
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
available_size
(),
pool
.
available_
buffer_size
());
#endif
puts
(
""
);
puts
(
echo_server_
.
get_statistic
().
to_string
().
data
());
...
...
@@ -228,6 +228,10 @@ int main(int argc, const char* argv[])
}
}
#if 4 == PACKER_UNPACKER_TYPE
pool
.
stop
();
#endif
return
0
;
}
...
...
include/ext/st_asio_wrapper_ext.h
浏览文件 @
3ce69fb3
...
...
@@ -15,6 +15,7 @@
#include <string>
#include <boost/array.hpp>
#include <boost/container/set.hpp>
#include "../st_asio_wrapper_base.h"
...
...
@@ -29,13 +30,13 @@ public:
virtual
const
char
*
data
()
const
{
return
std
::
string
::
data
();}
};
class
most_primitive
_buffer
class
basic
_buffer
{
public:
most_primitive
_buffer
()
{
do_detach
();}
most_primitive
_buffer
(
size_t
len
)
{
do_detach
();
assign
(
len
);}
most_primitive_buffer
(
most_primitive
_buffer
&&
other
)
{
do_attach
(
other
.
buff
,
other
.
len
,
other
.
buff_len
);
other
.
do_detach
();}
~
most_primitive
_buffer
()
{
free
();}
basic
_buffer
()
{
do_detach
();}
basic
_buffer
(
size_t
len
)
{
do_detach
();
assign
(
len
);}
basic_buffer
(
basic
_buffer
&&
other
)
{
do_attach
(
other
.
buff
,
other
.
len
,
other
.
buff_len
);
other
.
do_detach
();}
~
basic
_buffer
()
{
free
();}
void
assign
(
size_t
len
)
{
free
();
do_attach
(
new
char
[
len
],
len
,
len
);}
void
free
()
{
delete
[]
buff
;
do_detach
();}
...
...
@@ -44,7 +45,7 @@ public:
bool
empty
()
const
{
return
0
==
len
||
nullptr
==
buff
;}
size_t
size
()
const
{
return
len
;}
const
char
*
data
()
const
{
return
buff
;}
void
swap
(
most_primitive
_buffer
&
other
)
{
std
::
swap
(
buff
,
other
.
buff
);
std
::
swap
(
len
,
other
.
len
);}
void
swap
(
basic
_buffer
&
other
)
{
std
::
swap
(
buff
,
other
.
buff
);
std
::
swap
(
len
,
other
.
len
);}
void
clear
()
{
free
();}
//functions needed by packer and unpacker
...
...
@@ -61,64 +62,85 @@ protected:
size_t
len
,
buff_len
;
};
//not thread safe, please pay attention
class
memory_pool
class
pooled_buffer
:
public
basic_buffer
{
public:
typedef
most_primitive_buffer
raw_object_type
;
typedef
const
raw_object_type
raw_object_ctype
;
typedef
boost
::
shared_ptr
<
most_primitive_buffer
>
object_type
;
typedef
const
object_type
object_ctype
;
class
i_memory_pool
{
public:
typedef
pooled_buffer
raw_buffer_type
;
typedef
const
raw_buffer_type
raw_buffer_ctype
;
typedef
boost
::
shared_ptr
<
raw_buffer_type
>
buffer_type
;
typedef
const
buffer_type
buffer_ctype
;
virtual
buffer_type
checkout
(
size_t
block_size
,
bool
best_fit
=
false
)
=
0
;
virtual
void
checkin
(
raw_buffer_type
&
buff
)
=
0
;
};
memory_pool
()
{}
memory_pool
(
size_t
block_count
,
size_t
block_size
)
{
init_pool
(
block_count
,
block_size
);}
//not thread safe
void
init_pool
(
size_t
block_count
,
size_t
block_size
)
{
for
(
size_t
i
=
0
;
i
<
block_count
;
++
i
)
pool
.
push_back
(
boost
::
make_shared
<
most_primitive_buffer
>
(
block_size
));}
public:
pooled_buffer
(
i_memory_pool
&
_pool
)
:
pool
(
_pool
)
{}
pooled_buffer
(
i_memory_pool
&
_pool
,
size_t
len
)
:
basic_buffer
(
len
),
pool
(
_pool
)
{}
pooled_buffer
(
pooled_buffer
&&
other
)
:
basic_buffer
(
std
::
move
(
other
)),
pool
(
other
.
pool
)
{}
~
pooled_buffer
()
{
pool
.
checkin
(
*
this
);}
size_t
size
()
{
boost
::
shared_lock
<
boost
::
shared_mutex
>
lock
(
mutex
);
return
pool
.
size
();}
//memory block amount
uint_fast64_t
buffer_size
()
{
uint_fast64_t
size
=
0
;
do_something_to_all
(
pool
,
mutex
,
[
&
](
object_ctype
&
item
)
{
size
+=
item
->
buffer_size
();});
return
size
;}
protected:
i_memory_pool
&
pool
;
};
object_type
ask_memory
(
size_t
block_size
,
bool
best_fit
=
false
)
class
memory_pool
:
public
pooled_buffer
::
i_memory_pool
{
public:
memory_pool
()
:
stopped_
(
false
)
{}
memory_pool
(
size_t
block_count
,
size_t
block_size
)
:
stopped_
(
false
)
{
init_pool
(
block_count
,
block_size
);}
void
stop
()
{
stopped_
=
true
;}
bool
stopped
()
const
{
return
stopped_
;}
//not thread safe, and can call many times before using this memory pool
void
init_pool
(
size_t
block_count
,
size_t
block_size
)
{
for
(
size_t
i
=
0
;
i
<
block_count
;
++
i
)
pool
.
insert
(
boost
::
make_shared
<
raw_buffer_type
>
(
*
this
,
block_size
));}
size_t
available_size
()
{
boost
::
shared_lock
<
boost
::
shared_mutex
>
lock
(
mutex
);
return
pool
.
size
();}
uint_fast64_t
available_buffer_size
()
{
uint_fast64_t
size
=
0
;
do_something_to_all
(
pool
,
mutex
,
[
&
](
buffer_ctype
&
item
)
{
size
+=
item
->
buffer_size
();});
return
size
;}
public:
virtual
buffer_type
checkout
(
size_t
block_size
,
bool
best_fit
=
false
)
{
if
(
stopped
())
return
buffer_type
();
auto
find_buffer_predicate
=
[
block_size
](
buffer_ctype
&
item
)
->
bool
{
return
item
->
buffer_size
()
>=
block_size
;};
boost
::
unique_lock
<
boost
::
shared_mutex
>
lock
(
mutex
);
auto
iter
=
best_fit
?
std
::
prev
(
std
::
find_if
(
pool
.
rbegin
(),
pool
.
rend
(),
find_buffer_predicate
).
base
())
:
std
::
find_if
(
std
::
begin
(
pool
),
std
::
end
(
pool
),
find_buffer_predicate
);
object_type
re
;
if
(
best_fit
)
{
object_type
candidate
;
size_t
gap
=
-
1
;
for
(
auto
iter
=
std
::
begin
(
pool
);
iter
!=
std
::
end
(
pool
);
++
iter
)
if
(
iter
->
unique
()
&&
(
*
iter
)
->
buffer_size
()
>=
block_size
)
{
auto
this_gap
=
(
*
iter
)
->
buffer_size
()
-
block_size
;
if
(
this_gap
<
gap
)
{
candidate
=
*
iter
;
if
(
0
==
(
gap
=
this_gap
))
break
;
}
}
re
=
candidate
;
}
else
for
(
auto
iter
=
std
::
begin
(
pool
);
!
re
&&
iter
!=
std
::
end
(
pool
);
++
iter
)
if
(
iter
->
unique
()
&&
(
*
iter
)
->
buffer_size
()
>=
block_size
)
re
=
*
iter
;
if
(
re
)
re
->
size
(
block_size
);
else
if
(
iter
!=
std
::
end
(
pool
))
{
re
=
boost
::
make_shared
<
most_primitive_buffer
>
(
block_size
);
pool
.
push_back
(
re
);
auto
buff
(
std
::
move
(
*
iter
));
buff
->
size
(
block_size
);
pool
.
erase
(
iter
);
return
buff
;
}
lock
.
unlock
();
return
re
;
return
boost
::
make_shared
<
raw_buffer_type
>
(
*
this
,
block_size
);
}
virtual
void
checkin
(
raw_buffer_type
&
buff
)
{
if
(
stopped
())
return
;
boost
::
unique_lock
<
boost
::
shared_mutex
>
lock
(
mutex
);
pool
.
insert
(
boost
::
make_shared
<
raw_buffer_type
>
(
std
::
move
(
buff
)));
}
protected:
boost
::
container
::
list
<
object_type
>
pool
;
struct
buffer_compare
{
bool
operator
()(
buffer_ctype
&
left
,
buffer_ctype
&
right
)
const
{
return
left
->
buffer_size
()
>
right
->
buffer_size
();}};
boost
::
container
::
multiset
<
buffer_type
,
buffer_compare
>
pool
;
boost
::
shared_mutex
mutex
;
bool
stopped_
;
};
}}
//namespace
...
...
include/ext/st_asio_wrapper_packer.h
浏览文件 @
3ce69fb3
...
...
@@ -100,7 +100,7 @@ public:
//protocol: length + body
//use memory pool
class
pooled_packer
:
public
i_packer
<
shared_buffer
<
memory_pool
::
raw_
object
_type
>>
class
pooled_packer
:
public
i_packer
<
shared_buffer
<
memory_pool
::
raw_
buffer
_type
>>
{
public:
static
size_t
get_max_msg_size
()
{
return
ST_ASIO_MSG_BUFFER_SIZE
-
ST_ASIO_HEAD_LEN
;}
...
...
@@ -128,12 +128,12 @@ public:
return
msg
;
}
msg
.
raw_buffer
(
pool
->
ask_memory
(
total_len
));
msg
.
raw_buffer
(
pool
->
checkout
(
total_len
));
head_len
=
ST_ASIO_HEAD_H2N
(
head_len
);
memcpy
(
msg
.
raw_buffer
()
->
data
(),
(
const
char
*
)
&
head_len
,
ST_ASIO_HEAD_LEN
);
}
else
msg
.
raw_buffer
(
pool
->
ask_memory
(
total_len
));
msg
.
raw_buffer
(
pool
->
checkout
(
total_len
));
total_len
=
pre_len
;
for
(
size_t
i
=
0
;
i
<
num
;
++
i
)
...
...
@@ -217,7 +217,7 @@ private:
//protocol: stream (non-protocol)
//use memory pool
class
pooled_stream_packer
:
public
i_packer
<
shared_buffer
<
memory_pool
::
raw_
object
_type
>>
class
pooled_stream_packer
:
public
i_packer
<
shared_buffer
<
memory_pool
::
raw_
buffer
_type
>>
{
public:
pooled_stream_packer
()
:
pool
(
nullptr
)
{}
...
...
@@ -233,7 +233,7 @@ public:
return
msg
;
else
if
(
total_len
>
0
)
{
msg
.
raw_buffer
(
pool
->
ask_memory
(
total_len
));
msg
.
raw_buffer
(
pool
->
checkout
(
total_len
));
total_len
=
0
;
for
(
size_t
i
=
0
;
i
<
num
;
++
i
)
...
...
include/ext/st_asio_wrapper_unpacker.h
浏览文件 @
3ce69fb3
...
...
@@ -130,12 +130,12 @@ protected:
//protocol: length + body
//use memory pool
class
pooled_unpacker
:
public
i_unpacker
<
shared_buffer
<
m
ost_primitive_buffer
>>
,
public
unpacker
class
pooled_unpacker
:
public
i_unpacker
<
shared_buffer
<
m
emory_pool
::
raw_buffer_type
>>
,
public
unpacker
{
public:
using
i_unpacker
<
shared_buffer
<
m
ost_primitive_buffer
>>::
msg_type
;
using
i_unpacker
<
shared_buffer
<
m
ost_primitive_buffer
>>::
msg_ctype
;
using
i_unpacker
<
shared_buffer
<
m
ost_primitive_buffer
>>::
container_type
;
using
i_unpacker
<
shared_buffer
<
m
emory_pool
::
raw_buffer_type
>>::
msg_type
;
using
i_unpacker
<
shared_buffer
<
m
emory_pool
::
raw_buffer_type
>>::
msg_ctype
;
using
i_unpacker
<
shared_buffer
<
m
emory_pool
::
raw_buffer_type
>>::
container_type
;
pooled_unpacker
()
:
pool
(
nullptr
)
{}
void
mem_pool
(
memory_pool
&
_pool
)
{
pool
=
&
_pool
;}
...
...
@@ -147,9 +147,9 @@ public:
boost
::
container
::
list
<
std
::
pair
<
const
char
*
,
size_t
>>
msg_pos_can
;
auto
unpack_ok
=
unpacker
::
parse_msg
(
bytes_transferred
,
msg_pos_can
);
do_something_to_all
(
msg_pos_can
,
[
this
,
&
msg_can
](
decltype
(
*
std
::
begin
(
msg_pos_can
))
&
item
)
{
auto
buff
=
pool
->
ask_memory
(
item
.
second
);
auto
buff
=
pool
->
checkout
(
item
.
second
);
memcpy
(
buff
->
data
(),
item
.
first
,
item
.
second
);
msg_can
.
push_back
(
shared_buffer
<
most_primitive_buffer
>
(
buff
));
msg_can
.
push_back
(
msg_type
(
buff
));
});
if
(
unpack_ok
&&
remain_len
>
0
)
...
...
@@ -226,10 +226,10 @@ protected:
//protocol: length + body
//this unpacker demonstrate how to forbid memory copying while parsing msgs (let asio write msg directly).
class
buffer_free_unpacker
:
public
i_unpacker
<
most_primitive
_buffer
>
class
non_copy_unpacker
:
public
i_unpacker
<
basic
_buffer
>
{
public:
buffer_free
_unpacker
()
{
reset_state
();}
non_copy
_unpacker
()
{
reset_state
();}
size_t
current_msg_length
()
const
{
return
raw_buff
.
size
();}
//current msg's total length(not include the head), 0 means not available
public:
...
...
@@ -509,7 +509,7 @@ protected:
//protocol: stream (non-protocol)
//use memory pool
class
pooled_stream_unpacker
:
public
i_unpacker
<
shared_buffer
<
m
ost_primitive_buffer
>>
class
pooled_stream_unpacker
:
public
i_unpacker
<
shared_buffer
<
m
emory_pool
::
raw_buffer_type
>>
{
public:
pooled_stream_unpacker
()
:
pool
(
nullptr
)
{}
...
...
@@ -525,19 +525,19 @@ public:
assert
(
bytes_transferred
<=
ST_ASIO_MSG_BUFFER_SIZE
);
buff
->
size
(
bytes_transferred
);
msg_can
.
push_back
(
shared_buffer
<
most_primitive_buffer
>
(
buff
));
msg_can
.
push_back
(
msg_type
(
buff
));
return
true
;
}
virtual
size_t
completion_condition
(
const
boost
::
system
::
error_code
&
ec
,
size_t
bytes_transferred
)
{
return
ec
||
bytes_transferred
>
0
?
0
:
boost
::
asio
::
detail
::
default_max_transfer_size
;}
virtual
boost
::
asio
::
mutable_buffers_1
prepare_next_recv
()
{
buff
=
pool
->
ask_memory
(
ST_ASIO_MSG_BUFFER_SIZE
);
buff
=
pool
->
checkout
(
ST_ASIO_MSG_BUFFER_SIZE
);
return
boost
::
asio
::
buffer
(
buff
->
data
(),
buff
->
buffer_size
());
}
protected:
msg_type
::
buffer_type
buff
;
//equal to memory_pool::
object
_type
msg_type
::
buffer_type
buff
;
//equal to memory_pool::
buffer
_type
memory_pool
*
pool
;
};
...
...
include/st_asio_wrapper_base.h
浏览文件 @
3ce69fb3
...
...
@@ -64,6 +64,7 @@ namespace st_asio_wrapper
virtual
const
char
*
data
()
const
=
0
;
};
//convert '->' operation to '.' operation
template
<
typename
T
>
class
shared_buffer
{
...
...
pingpong_client/client.cpp
浏览文件 @
3ce69fb3
...
...
@@ -7,11 +7,11 @@
#define ST_ASIO_SERVER_PORT 9527
#define ST_ASIO_REUSE_OBJECT //use objects pool
//#define ST_ASIO_FORCE_TO_USE_MSG_RECV_BUFFER
#define ST_ASIO_WANT_MSG_SEND_NOTIFY
//
#define ST_ASIO_WANT_MSG_SEND_NOTIFY
#define ST_ASIO_MSG_BUFFER_SIZE 65536
//use the following macro to control the type of packer and unpacker
#define PACKER_UNPACKER_TYPE
2
#define PACKER_UNPACKER_TYPE
1
//1-stream unpacker (non-protocol)
//2-pooled_stream_packer and pooled_stream_unpacker (non-protocol)
...
...
@@ -169,7 +169,7 @@ int main(int argc, const char* argv[])
{
printf
(
"link #: "
ST_ASIO_SF
", valid links: "
ST_ASIO_SF
", invalid links: "
ST_ASIO_SF
"
\n
"
,
client
.
size
(),
client
.
valid_size
(),
client
.
invalid_object_size
());
#if 2 == PACKER_UNPACKER_TYPE
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
size
(),
pool
.
buffer_size
());
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
available_size
(),
pool
.
available_
buffer_size
());
#endif
puts
(
""
);
puts
(
client
.
get_statistic
().
to_string
().
data
());
...
...
@@ -208,6 +208,10 @@ int main(int argc, const char* argv[])
}
}
#if 2 == PACKER_UNPACKER_TYPE
pool
.
stop
();
#endif
return
0
;
}
...
...
pingpong_server/server.cpp
浏览文件 @
3ce69fb3
...
...
@@ -8,7 +8,7 @@
#define ST_ASIO_MSG_BUFFER_SIZE 65536
//use the following macro to control the type of packer and unpacker
#define PACKER_UNPACKER_TYPE
2
#define PACKER_UNPACKER_TYPE
1
//1-stream unpacker (non-protocol)
//2-pooled_stream_packer and pooled_stream_unpacker (non-protocol)
...
...
@@ -98,13 +98,17 @@ int main(int argc, const char* argv[])
{
printf
(
"link #: "
ST_ASIO_SF
", invalid links: "
ST_ASIO_SF
"
\n
"
,
echo_server_
.
size
(),
echo_server_
.
invalid_object_size
());
#if 2 == PACKER_UNPACKER_TYPE
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
size
(),
pool
.
buffer_size
());
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
available_size
(),
pool
.
available_
buffer_size
());
#endif
puts
(
""
);
puts
(
echo_server_
.
get_statistic
().
to_string
().
data
());
}
}
#if 2 == PACKER_UNPACKER_TYPE
pool
.
stop
();
#endif
return
0
;
}
...
...
test_client/test_client.cpp
浏览文件 @
3ce69fb3
...
...
@@ -284,7 +284,7 @@ int main(int argc, const char* argv[])
{
printf
(
"link #: "
ST_ASIO_SF
", valid links: "
ST_ASIO_SF
", invalid links: "
ST_ASIO_SF
"
\n
"
,
client
.
size
(),
client
.
valid_size
(),
client
.
invalid_object_size
());
#if 4 == PACKER_UNPACKER_TYPE
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
size
(),
pool
.
buffer_size
());
printf
(
"pool block amount: "
ST_ASIO_SF
", pool total size: %llu
\n
"
,
pool
.
available_size
(),
pool
.
available_
buffer_size
());
#endif
puts
(
""
);
puts
(
client
.
get_statistic
().
to_string
().
data
());
...
...
@@ -447,6 +447,10 @@ int main(int argc, const char* argv[])
}
}
#if 4 == PACKER_UNPACKER_TYPE
pool
.
stop
();
#endif
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录