Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix lambda function copy captured variable many times #272

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions libgo/common/syntax_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,19 @@ struct __go
opt_.lineno_ = lineno;
}

template <typename Function>
ALWAYS_INLINE void operator-(Function const& f)
template <typename F, typename = decltype(std::declval<F>()())>
ALWAYS_INLINE void operator-(F &&f)
{
if (!scheduler_) scheduler_ = Processer::GetCurrentScheduler();
if (!scheduler_) scheduler_ = &Scheduler::getInstance();
scheduler_->CreateTask(f, opt_);
scheduler_->CreateTask(std::forward<F>(f), opt_);
}

ALWAYS_INLINE void operator-(TaskF &f)
{
if (!scheduler_) scheduler_ = Processer::GetCurrentScheduler();
if (!scheduler_) scheduler_ = &Scheduler::getInstance();
scheduler_->CreateTask(std::forward<TaskF>(f), opt_);
}

ALWAYS_INLINE __go& operator-(__go_option<opt_scheduler> const& opt)
Expand Down
12 changes: 6 additions & 6 deletions libgo/netio/unix/hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,8 @@ struct hostent* gethostbyname(const char* name)
int & host_errno = CLS(int);

int ret = -1;
while (ret = gethostbyname_r(name, host, &buf[0],
buf.size(), &result, &host_errno) == ERANGE &&
while ((ret = gethostbyname_r(name, host, &buf[0],
buf.size(), &result, &host_errno)) == ERANGE &&
host_errno == NETDB_INTERNAL )
{
if (buf.size() < 1024)
Expand Down Expand Up @@ -568,8 +568,8 @@ struct hostent* gethostbyname2(const char* name, int af)
int & host_errno = CLS(int);

int ret = -1;
while (ret = gethostbyname2_r(name, af, host, &buf[0],
buf.size(), &result, &host_errno) == ERANGE &&
while ((ret = gethostbyname2_r(name, af, host, &buf[0],
buf.size(), &result, &host_errno)) == ERANGE &&
host_errno == NETDB_INTERNAL )
{
if (buf.size() < 1024)
Expand Down Expand Up @@ -618,8 +618,8 @@ struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type)
int & host_errno = CLS(int);

int ret = -1;
while (ret = gethostbyaddr_r(addr, len, type,
host, &buf[0], buf.size(), &result, &host_errno) == ERANGE &&
while ((ret = gethostbyaddr_r(addr, len, type,
host, &buf[0], buf.size(), &result, &host_errno)) == ERANGE &&
host_errno == NETDB_INTERNAL )
{
if (buf.size() < 1024)
Expand Down
1 change: 1 addition & 0 deletions libgo/routine_sync/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ class ChannelImpl : public ChannelImplWithSignal<T>
std::size_t cap_;
};

using std::nullptr_t;
// 仅计数
template <
typename QueueT
Expand Down
4 changes: 2 additions & 2 deletions libgo/scheduler/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ Scheduler::~Scheduler()
Stop();
}

void Scheduler::CreateTask(TaskF const& fn, TaskOpt const& opt)
void Scheduler::CreateTask(TaskF &&fn, TaskOpt const& opt)
{
Task* tk = new Task(fn, opt.stack_size_ ? opt.stack_size_ : CoroutineOptions::getInstance().stack_size);
Task* tk = new Task(std::forward<TaskF>(fn), opt.stack_size_ ? opt.stack_size_ : CoroutineOptions::getInstance().stack_size);
// printf("new tk = %p impl = %p\n", tk, tk->impl_);
tk->SetDeleter(Deleter(&Scheduler::DeleteTask, this));
tk->id_ = ++GetTaskIdFactory();
Expand Down
2 changes: 1 addition & 1 deletion libgo/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Scheduler
static Scheduler* Create();

// 创建一个协程
void CreateTask(TaskF const& fn, TaskOpt const& opt);
void CreateTask(TaskF &&fn, TaskOpt const& opt);

// 当前是否处于协程中
bool IsCoroutine();
Expand Down
6 changes: 2 additions & 4 deletions libgo/task/task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ void FCONTEXT_CALL Task::StaticRun(intptr_t vp)
tk->Run();
}

Task::Task(TaskF const& fn, std::size_t stack_size)
: ctx_(&Task::StaticRun, (intptr_t)this, stack_size), fn_(fn)
Task::Task(TaskF fn, std::size_t stack_size)
: ctx_(&Task::StaticRun, (intptr_t)this, stack_size), fn_(std::move(fn))
{
// DebugPrint(dbg_task, "task(%s) construct. this=%p", DebugInfo(), this);
#if USE_ROUTINE_SYNC
Expand All @@ -106,8 +106,6 @@ Task::~Task()

const char* Task::DebugInfo()
{
if (reinterpret_cast<void*>(this) == nullptr) return "nil";

return TaskDebugInfo(this);
}

Expand Down
2 changes: 1 addition & 1 deletion libgo/task/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct Task

atomic_t<uint64_t> suspendId_ {0};

Task(TaskF const& fn, std::size_t stack_size);
Task(TaskF fn, std::size_t stack_size);
~Task();

ALWAYS_INLINE void SwapIn()
Expand Down
67 changes: 67 additions & 0 deletions test/bench/capture.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

#include "coroutine.h"
#include <benchmark/benchmark.h>
#include <stdio.h>
#include <thread>

struct C {
C() { std::cout << __PRETTY_FUNCTION__ << '\n'; }

C(const C &) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
C(const C &&) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
C &operator=(const C &) {
std::cout << __PRETTY_FUNCTION__ << '\n';
return *this;
}
C &operator=(const C &&) {
std::cout << __PRETTY_FUNCTION__ << '\n';
return *this;
}
~C() { std::cout << __PRETTY_FUNCTION__ << '\n'; }
int i = 100;
};

static void BenchCreateEmpty(benchmark::State &state) {
for (auto _ : state) {
std::vector<char> vi(state.range(0));
go[]{

};
benchmark::DoNotOptimize(vi.size());
}
}

BENCHMARK(BenchCreateEmpty)->Range(1, 8192);

static void BenchCreateCopy(benchmark::State &state) {
for (auto _ : state) {
std::vector<char> vi(state.range(0));
go[vi](){

};
}
}

BENCHMARK(BenchCreateCopy)->Range(1, 8192);
static void BenchCreateMove(benchmark::State &state) {
for (auto _ : state) {
std::vector<char> vi(state.range(0));
go[vi = std::move(vi)](){

};
}
}

BENCHMARK(BenchCreateMove)->Range(1, 8192);

int main(int argc, char **argv) {
C c;
go [c = std::move(c)] {};
std::thread t([] { co_sched.Start(); });
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
benchmark::Shutdown();
co_sched.Stop();
t.join();
return 0;
}