Skip to content

Commit 738b625

Browse files
author
test
committed
v2.2 Merge branch 'dev': 优化多线程模型的性能
2 parents 0cea895 + 1ae65f2 commit 738b625

File tree

24 files changed

+594
-137
lines changed

24 files changed

+594
-137
lines changed

.travis.yml

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,34 @@
1+
sudo: required
2+
dist: trusty
13
language: cpp
24

35
compiler:
46
- gcc
57

68
before_install:
7-
- sudo add-apt-repository -y ppa:andykimpe/cmake
8-
- sudo add-apt-repository -y ppa:boost-latest/ppa
9-
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
10-
- sudo apt-get -qq update
9+
- sudo add-apt-repository -y ppa:kojoley/boost
10+
- sudo apt-get update -y
11+
- lsb_release -a
1112

1213
install:
13-
- sudo apt-get install cmake
14-
- sudo apt-get install -qq boost1.55
15-
- .travis_scripts/gcc.sh
14+
- git clone https://github.com/yyzybb537/Boost-dev-bin.git /tmp/boost-dev-bin && sudo dpkg -i /tmp/boost-dev-bin/libboost1.59-all-dev.deb
15+
- ls /usr/local/lib/libboost*
16+
- sudo ldconfig
17+
#- sudo apt-get install -y -qq libboost1.58-dev
18+
#- sudo apt-get install -y -qq libboost-thread1.58-dev
19+
#- sudo apt-get install -y -qq libboost-coroutine1.58-dev
20+
#- sudo apt-get install -y -qq libboost-context1.58-dev
21+
#- sudo apt-get install -y -qq libboost-system1.58-dev
22+
#- sudo apt-get install -y -qq libboost-date-time1.58-dev
23+
#- sudo apt-get install -y -qq libboost-chrono1.58-dev
24+
#- sudo apt-get install -y -qq libboost-regex1.58-dev
25+
- sudo apt-get install -y -qq cmake
1626

1727
script:
1828
- mkdir build; pushd build;
19-
- cmake ..
20-
- make -j4
21-
- sudo make install
22-
- make test_small
23-
- make samples
24-
- make run_test
25-
# - sudo rm * -rf
26-
# - cmake .. -DENABLE_BOOST_COROUTINE=ON
27-
# - make -j4
28-
# - sudo make install
29-
# - make test_small
30-
# - make run_test
31-
# - sudo rm * -rf
32-
# - cmake .. -DENABLE_SHARED_STACK=ON
33-
# - make -j4
34-
# - sudo make install
35-
# - make test_small
36-
# - make run_test
29+
- cmake .. && make -j4 && sudo make install && make test_small && make samples && make run_test
30+
- sudo rm * -rf && cmake .. -DENABLE_BOOST_COROUTINE=ON && make -j4 && sudo make install && make test_small && make samples && make run_test
31+
- sudo rm * -rf && cmake .. -DENABLE_SHARED_STACK=ON && make -j4 && sudo make install && make test_small && make samples && make run_test
3732
- popd;
3833

3934
after_success:

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ endif()
113113

114114
if (UNIX)
115115
set(CMAKE_CXX_FLAGS "-std=c++11 -fPIC -Wall ${CXX_FLAGS_POSTFIX}")
116-
set(CMAKE_CXX_FLAGS_DEBUG "-g ${CMAKE_CXX_FLAGS} -Werror")
116+
set(CMAKE_CXX_FLAGS_DEBUG "-g -pg ${CMAKE_CXX_FLAGS} -Werror")
117117
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS} -Werror")
118118
else ()
119119
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")

src/block_object.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,19 @@ void BlockObject::CoBlockWait()
4141
Task* tk = g_Scheduler.GetLocalInfo().current_task;
4242
tk->block_ = this;
4343
tk->state_ = TaskState::sys_block;
44-
tk->block_timeout_ = std::chrono::nanoseconds::zero();
44+
tk->block_timeout_ = MininumTimeDurationType::zero();
4545
tk->is_block_timeout_ = false;
4646
++ tk->block_sequence_;
4747
DebugPrint(dbg_syncblock, "wait to switch. task(%s)", tk->DebugInfo());
4848
g_Scheduler.CoYield();
4949
}
5050

51-
bool BlockObject::CoBlockWaitTimed(std::chrono::nanoseconds timeo)
51+
bool BlockObject::CoBlockWaitTimed(MininumTimeDurationType timeo)
5252
{
5353
auto begin = std::chrono::high_resolution_clock::now();
5454
if (!g_Scheduler.IsCoroutine()) {
5555
while (!TryBlockWait() &&
56-
std::chrono::duration_cast<std::chrono::nanoseconds>
56+
std::chrono::duration_cast<MininumTimeDurationType>
5757
(std::chrono::high_resolution_clock::now() - begin) < timeo)
5858
usleep(10 * 1000);
5959
return false;
@@ -104,10 +104,11 @@ bool BlockObject::Wakeup()
104104
DebugPrint(dbg_syncblock, "wakeup to %lu.", (long unsigned)wakeup_);
105105
return true;
106106
}
107+
lock.unlock();
107108

108109
tk->block_ = nullptr;
109-
g_Scheduler.AddTaskRunnable(tk);
110110
DebugPrint(dbg_syncblock, "wakeup task(%s).", tk->DebugInfo());
111+
g_Scheduler.AddTaskRunnable(tk);
111112
return true;
112113
}
113114
void BlockObject::CancelWait(Task* tk, uint32_t block_sequence)
@@ -128,11 +129,12 @@ void BlockObject::CancelWait(Task* tk, uint32_t block_sequence)
128129
DebugPrint(dbg_syncblock, "cancelwait task(%s) erase failed.", tk->DebugInfo());
129130
return;
130131
}
132+
lock.unlock();
131133

132134
tk->block_ = nullptr;
133135
tk->is_block_timeout_ = true;
134-
g_Scheduler.AddTaskRunnable(tk);
135136
DebugPrint(dbg_syncblock, "cancelwait task(%s).", tk->DebugInfo());
137+
g_Scheduler.AddTaskRunnable(tk);
136138
}
137139

138140
bool BlockObject::IsWakeup()
@@ -152,7 +154,7 @@ bool BlockObject::AddWaitTask(Task* tk)
152154
wait_queue_.push(tk);
153155

154156
// 带超时的, 增加定时器
155-
if (std::chrono::nanoseconds::zero() != tk->block_timeout_) {
157+
if (MininumTimeDurationType::zero() != tk->block_timeout_) {
156158
uint32_t seq = tk->block_sequence_;
157159
tk->IncrementRef();
158160
lock.unlock(); // sequence记录完成, task引用计数增加, 可以解锁了

src/block_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class BlockObject
2525

2626
// 带超时的阻塞式等待信号
2727
// @returns: 是否成功等到信号
28-
bool CoBlockWaitTimed(std::chrono::nanoseconds timeo);
28+
bool CoBlockWaitTimed(MininumTimeDurationType timeo);
2929

3030
bool TryBlockWait();
3131

src/channel.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class Channel
141141
template <typename U, typename Duration>
142142
bool TimedPush(U && t, Duration const& dur)
143143
{
144-
if (!write_block_.CoBlockWaitTimed(std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
144+
if (!write_block_.CoBlockWaitTimed(std::chrono::duration_cast<MininumTimeDurationType>(dur)))
145145
return false;
146146

147147
{
@@ -158,7 +158,7 @@ class Channel
158158
bool TimedPop(U & t, Duration const& dur)
159159
{
160160
write_block_.Wakeup();
161-
if (!read_block_.CoBlockWaitTimed(std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
161+
if (!read_block_.CoBlockWaitTimed(std::chrono::duration_cast<MininumTimeDurationType>(dur)))
162162
{
163163
if (write_block_.TryBlockWait())
164164
return false;
@@ -183,7 +183,7 @@ class Channel
183183
bool TimedPop(nullptr_t ignore, Duration const& dur)
184184
{
185185
write_block_.Wakeup();
186-
if (!read_block_.CoBlockWaitTimed(std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
186+
if (!read_block_.CoBlockWaitTimed(std::chrono::duration_cast<MininumTimeDurationType>(dur)))
187187
{
188188
if (write_block_.TryBlockWait())
189189
return false;
@@ -344,7 +344,7 @@ class Channel<void>
344344
template <typename Duration>
345345
bool TimedPush(nullptr_t ignore, Duration const& dur)
346346
{
347-
if (!write_block_.CoBlockWaitTimed(std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
347+
if (!write_block_.CoBlockWaitTimed(std::chrono::duration_cast<MininumTimeDurationType>(dur)))
348348
return false;
349349

350350
read_block_.Wakeup();
@@ -356,7 +356,7 @@ class Channel<void>
356356
bool TimedPop(nullptr_t ignore, Duration const& dur)
357357
{
358358
write_block_.Wakeup();
359-
if (!read_block_.CoBlockWaitTimed(std::chrono::duration_cast<std::chrono::nanoseconds>(dur)))
359+
if (!read_block_.CoBlockWaitTimed(std::chrono::duration_cast<MininumTimeDurationType>(dur)))
360360
{
361361
if (write_block_.TryBlockWait())
362362
return false;

src/config.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
#include <chrono>
3+
4+
// VS2013²»Ö§³Öthread_local
5+
#if defined(_MSC_VER) && _MSC_VER < 1900
6+
#define co_thread_local __declspec(thread)
7+
#else
8+
#define co_thread_local thread_local
9+
#endif
10+
11+
namespace co
12+
{
13+
14+
#ifdef _WIN32
15+
typedef std::chrono::microseconds MininumTimeDurationType;
16+
#else
17+
typedef std::chrono::nanoseconds MininumTimeDurationType;
18+
#endif
19+
20+
} //namespace co

src/context.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <functional>
44
#include <memory>
5+
#include "error.h"
56

67
namespace co
78
{
@@ -16,9 +17,9 @@ namespace co
1617
class impl_t;
1718

1819
public:
19-
explicit Context(std::size_t stack_size);
20+
explicit Context(std::size_t stack_size, std::function<void()> const& fn);
2021

21-
bool Init(std::function<void()> const& fn, char* shared_stack, uint32_t shared_stack_cap);
22+
bool Init(char* shared_stack, uint32_t shared_stack_cap);
2223

2324
bool SwapIn();
2425

src/ctx_boost_coroutine/context.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,48 @@ namespace co
4545
uint32_t stack_capacity_ = 0;
4646
char* shared_stack_;
4747
uint32_t shared_stack_cap_;
48+
std::function<void()> fn_;
4849
};
4950

50-
Context::Context(std::size_t stack_size)
51+
Context::Context(std::size_t stack_size, std::function<void()> const& fn)
5152
: impl_(new Context::impl_t), stack_size_(stack_size)
52-
{ }
53+
{
54+
impl_->fn_ = fn;
55+
56+
#if !defined(ENABLE_SHARED_STACK)
57+
decltype(impl_->ctx_) c(
58+
[=](::boost::coroutines::symmetric_coroutine<void>::yield_type& yield){
59+
impl_->yield_ = &yield;
60+
fn();
61+
}
62+
, boost::coroutines::attributes(std::max<std::size_t>(stack_size_, boost::coroutines::stack_traits::minimum_size()))
63+
);
5364

54-
bool Context::Init(std::function<void()> const& fn, char* shared_stack, uint32_t shared_stack_cap)
65+
if (!c) {
66+
ThrowError(eCoErrorCode::ec_makecontext_failed);
67+
return ;
68+
}
69+
70+
impl_->ctx_.swap(c);
71+
#endif
72+
}
73+
74+
bool Context::Init(char* shared_stack, uint32_t shared_stack_cap)
5575
{
5676
#if defined(ENABLE_SHARED_STACK)
5777
impl_->shared_stack_ = shared_stack;
5878
impl_->shared_stack_cap_ = shared_stack_cap;
59-
#endif
60-
6179
decltype(impl_->ctx_) c(
6280
[=](::boost::coroutines::symmetric_coroutine<void>::yield_type& yield){
6381
impl_->yield_ = &yield;
6482
fn();
6583
}
66-
#if defined(ENABLE_SHARED_STACK)
6784
, boost::coroutines::attributes(shared_stack_cap), shared_stack_allocator(shared_stack, shared_stack_cap)
68-
#else
69-
, boost::coroutines::attributes(std::max<std::size_t>(stack_size_, boost::coroutines::stack_traits::minimum_size()))
70-
#endif
7185
);
86+
7287
if (!c) return false;
7388
impl_->ctx_.swap(c);
7489

75-
#if defined(ENABLE_SHARED_STACK)
7690
static const int default_base_size = 32;
7791
// save coroutine stack first 16 bytes.
7892
assert(!impl_->stack_);
@@ -81,7 +95,6 @@ namespace co
8195
impl_->stack_ = (char*)malloc(impl_->stack_capacity_);
8296
memcpy(impl_->stack_, shared_stack + shared_stack_cap - impl_->stack_size_, impl_->stack_size_);
8397
#endif
84-
8598
return true;
8699
}
87100

src/ctx_ucontext/context.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,33 @@ namespace co
4141
(*pfn)();
4242
}
4343

44-
Context::Context(std::size_t stack_size)
44+
Context::Context(std::size_t stack_size, std::function<void()> const& fn)
4545
: impl_(new Context::impl_t), stack_size_(stack_size)
46-
{}
46+
{
47+
impl_->fn_ = fn;
48+
49+
#if !defined(ENABLE_SHARED_STACK)
50+
if (-1 == getcontext(&impl_->ctx_)) {
51+
ThrowError(eCoErrorCode::ec_makecontext_failed);
52+
return ;
53+
}
54+
55+
impl_->stack_size_ = this->stack_size_;
56+
impl_->stack_ = (char*)valloc(impl_->stack_size_);
4757

48-
bool Context::Init(std::function<void()> const& fn, char* shared_stack, uint32_t shared_stack_cap)
58+
impl_->ctx_.uc_stack.ss_sp = impl_->stack_;
59+
impl_->ctx_.uc_stack.ss_size = impl_->stack_size_;
60+
impl_->ctx_.uc_link = NULL;
61+
makecontext(&impl_->ctx_, (void(*)(void))&ucontext_func, 1, &impl_->fn_);
62+
#endif
63+
}
64+
65+
bool Context::Init(char* shared_stack, uint32_t shared_stack_cap)
4966
{
67+
#if defined(ENABLE_SHARED_STACK)
5068
if (-1 == getcontext(&impl_->ctx_))
5169
return false;
5270

53-
impl_->fn_ = fn;
54-
55-
#if defined(ENABLE_SHARED_STACK)
5671
impl_->shared_stack_ = shared_stack;
5772
impl_->shared_stack_cap_ = shared_stack_cap;
5873

@@ -67,14 +82,6 @@ namespace co
6782
impl_->stack_capacity_ = std::max<uint32_t>(16, g_Scheduler.GetOptions().init_commit_stack_size);
6883
impl_->stack_ = (char*)malloc(impl_->stack_capacity_);
6984
memcpy(impl_->stack_, shared_stack + shared_stack_cap - impl_->stack_size_, impl_->stack_size_);
70-
#else
71-
impl_->stack_size_ = this->stack_size_;
72-
impl_->stack_ = (char*)valloc(impl_->stack_size_);
73-
74-
impl_->ctx_.uc_stack.ss_sp = impl_->stack_;
75-
impl_->ctx_.uc_stack.ss_size = impl_->stack_size_;
76-
impl_->ctx_.uc_link = NULL;
77-
makecontext(&impl_->ctx_, (void(*)(void))&ucontext_func, 1, &impl_->fn_);
7885
#endif
7986

8087
return true;

src/ctx_win_fiber/context.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,23 @@ namespace co
4242
(*fn)();
4343
};
4444

45-
Context::Context(std::size_t stack_size)
45+
Context::Context(std::size_t stack_size, std::function<void()> const& fn)
4646
: impl_(new Context::impl_t), stack_size_(stack_size)
47-
{}
48-
49-
bool Context::Init(std::function<void()> const& fn, char* shared_stack, uint32_t shared_stack_cap)
5047
{
5148
impl_->fn_ = fn;
5249
SIZE_T commit_size = g_Scheduler.GetOptions().init_commit_stack_size;
5350
impl_->native_ = CreateFiberEx(commit_size,
5451
(std::max)(stack_size_, commit_size), FIBER_FLAG_FLOAT_SWITCH,
5552
(LPFIBER_START_ROUTINE)FiberFunc, &impl_->fn_);
56-
return !!impl_->native_;
53+
if (!impl_->native_) {
54+
ThrowError(eCoErrorCode::ec_makecontext_failed);
55+
return ;
56+
}
57+
}
58+
59+
bool Context::Init(char* shared_stack, uint32_t shared_stack_cap)
60+
{
61+
return true;
5762
}
5863

5964
bool Context::SwapIn()

0 commit comments

Comments
 (0)