Skip to content

Commit f142924

Browse files
authored
Optimize code (swoole#4005)
* add slow master tests * optimize code * optimize code [2] * fix * add core-test
1 parent 004d08a commit f142924

File tree

12 files changed

+193
-57
lines changed

12 files changed

+193
-57
lines changed

core-tests/src/coroutine/base.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,10 @@ TEST(coroutine_base, get_elapsed) {
171171
&elapsed_time);
172172
ASSERT_GE(elapsed_time, 2);
173173
}
174+
175+
TEST(coroutine_base, run) {
176+
long cid = coroutine::run([](void *ptr){
177+
178+
});
179+
ASSERT_GE(cid, 1);
180+
}

ext-src/php_swoole_coroutine.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ class PHPCoroutine {
127127

128128
static const uint8_t MAX_EXEC_MSEC = 10;
129129
static void init();
130-
static void deactivate(void *ptr);
131130
static void shutdown();
132131
static long create(zend_fcall_info_cache *fci_cache, uint32_t argc, zval *argv);
133132
static void defer(zend::Function *fci);
@@ -144,7 +143,7 @@ class PHPCoroutine {
144143
static void resume_m(FutureTask *task, zval *retval);
145144

146145
static inline long get_cid() {
147-
return sw_likely(active) ? Coroutine::get_current_cid() : -1;
146+
return sw_likely(activated) ? Coroutine::get_current_cid() : -1;
148147
}
149148

150149
static inline long get_pcid(long cid = 0) {
@@ -153,7 +152,7 @@ class PHPCoroutine {
153152
}
154153

155154
static inline long get_elapsed(long cid = 0) {
156-
return sw_likely(active) ? Coroutine::get_elapsed(cid) : -1;
155+
return sw_likely(activated) ? Coroutine::get_elapsed(cid) : -1;
157156
}
158157

159158
static inline PHPContext *get_context() {
@@ -215,18 +214,19 @@ class PHPCoroutine {
215214
}
216215

217216
static inline bool is_activated() {
218-
return active;
217+
return activated;
219218
}
220219

221220
protected:
222-
static bool active;
221+
static bool activated;
223222
static PHPContext main_task;
224223
static Config config;
225224

226225
static bool interrupt_thread_running;
227226
static std::thread interrupt_thread;
228227

229228
static void activate();
229+
static void deactivate(void *ptr);
230230

231231
static inline void vm_stack_init(void);
232232
static inline void vm_stack_destroy(void);

ext-src/swoole_coroutine.cc

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ using swoole::coroutine::System;
4242

4343
enum sw_exit_flags { SW_EXIT_IN_COROUTINE = 1 << 1, SW_EXIT_IN_SERVER = 1 << 2 };
4444

45-
bool PHPCoroutine::active = false;
45+
bool PHPCoroutine::activated = false;
4646
zend_array *PHPCoroutine::options = nullptr;
4747

4848
PHPCoroutine::Config PHPCoroutine::config {
@@ -290,27 +290,8 @@ void PHPCoroutine::init() {
290290
Coroutine::set_on_close(on_close);
291291
}
292292

293-
void PHPCoroutine::deactivate(void *ptr) {
294-
interrupt_thread_stop();
295-
/**
296-
* reset runtime hook
297-
*/
298-
disable_hook();
299-
300-
zend_interrupt_function = orig_interrupt_function;
301-
zend_error_cb = orig_error_function;
302-
303-
if (config.enable_deadlock_check) {
304-
deadlock_check();
305-
}
306-
307-
enable_unsafe_function();
308-
309-
active = false;
310-
}
311-
312293
void PHPCoroutine::activate() {
313-
if (sw_unlikely(active)) {
294+
if (sw_unlikely(activated)) {
314295
return;
315296
}
316297

@@ -336,7 +317,7 @@ void PHPCoroutine::activate() {
336317
orig_error_function = zend_error_cb;
337318
zend_error_cb = [](int type, const char *error_filename, const uint32_t error_lineno, ZEND_ERROR_CB_LAST_ARG_D) {
338319
if (sw_unlikely(type & E_FATAL_ERRORS)) {
339-
if (active) {
320+
if (activated) {
340321
/* update the last coroutine's info */
341322
save_task(get_context());
342323
}
@@ -365,7 +346,27 @@ void PHPCoroutine::activate() {
365346
* deactivate when reactor free.
366347
*/
367348
SwooleTG.reactor->add_destroy_callback(deactivate, nullptr);
368-
active = true;
349+
Coroutine::activate();
350+
activated = true;
351+
}
352+
353+
void PHPCoroutine::deactivate(void *ptr) {
354+
interrupt_thread_stop();
355+
/**
356+
* reset runtime hook
357+
*/
358+
disable_hook();
359+
360+
zend_interrupt_function = orig_interrupt_function;
361+
zend_error_cb = orig_error_function;
362+
363+
if (config.enable_deadlock_check) {
364+
deadlock_check();
365+
}
366+
367+
enable_unsafe_function();
368+
Coroutine::deactivate();
369+
activated = false;
369370
}
370371

371372
void PHPCoroutine::shutdown() {
@@ -803,7 +804,7 @@ long PHPCoroutine::create(zend_fcall_info_cache *fci_cache, uint32_t argc, zval
803804
return Coroutine::ERR_INVALID;
804805
}
805806

806-
if (sw_unlikely(!active)) {
807+
if (sw_unlikely(!activated)) {
807808
activate();
808809
}
809810

include/swoole_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ SW_API swoole::TimerNode *swoole_timer_get(long timer_id);
3636
SW_API bool swoole_timer_clear(long timer_id);
3737
SW_API void swoole_timer_free();
3838
SW_API int swoole_timer_select();
39+
SW_API bool swoole_timer_is_available();
3940

4041
SW_API int swoole_event_init(int flags);
4142
SW_API int swoole_event_add(swoole::network::Socket *socket, int events);

include/swoole_coroutine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ class Coroutine {
105105
return (new Coroutine(fn, args))->run();
106106
}
107107

108+
static void activate();
109+
static void deactivate();
110+
108111
static inline Coroutine *get_current() {
109112
return current;
110113
}
@@ -170,6 +173,7 @@ class Coroutine {
170173
static SwapCallback on_resume; /* before resume */
171174
static SwapCallback on_close; /* before close */
172175
static BailoutCallback on_bailout; /* when bailout */
176+
static bool activated;
173177

174178
enum State state = STATE_INIT;
175179
long cid;

include/swoole_coroutine_context.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ class Context {
5858
inline bool is_end() {
5959
return end_;
6060
}
61-
static void context_func(void *arg);
62-
6361
protected:
6462
coroutine_func_t fn_;
6563
#ifdef SW_USE_THREAD_CONTEXT
@@ -77,6 +75,8 @@ class Context {
7775
#endif
7876
void *private_data_;
7977
bool end_;
78+
79+
static void context_func(void *arg);
8080
};
8181

8282
} // namespace coroutine

src/coroutine/base.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,35 @@ Coroutine *Coroutine::current = nullptr;
2323
long Coroutine::last_cid = 0;
2424
std::unordered_map<long, Coroutine *> Coroutine::coroutines;
2525
uint64_t Coroutine::peak_num = 0;
26+
bool Coroutine::activated = false;
2627

2728
size_t Coroutine::stack_size = SW_DEFAULT_C_STACK_SIZE;
2829
Coroutine::SwapCallback Coroutine::on_yield = nullptr;
2930
Coroutine::SwapCallback Coroutine::on_resume = nullptr;
3031
Coroutine::SwapCallback Coroutine::on_close = nullptr;
3132
Coroutine::BailoutCallback Coroutine::on_bailout = nullptr;
3233

34+
#ifdef SW_USE_THREAD_CONTEXT
35+
namespace coroutine {
36+
void thread_context_init();
37+
void thread_context_clean();
38+
}
39+
#endif
40+
41+
void Coroutine::activate() {
42+
#ifdef SW_USE_THREAD_CONTEXT
43+
coroutine::thread_context_init();
44+
#endif
45+
activated = true;
46+
}
47+
48+
void Coroutine::deactivate() {
49+
#ifdef SW_USE_THREAD_CONTEXT
50+
coroutine::thread_context_clean();
51+
#endif
52+
activated = false;
53+
}
54+
3355
void Coroutine::yield() {
3456
SW_ASSERT(current == this || on_bailout != nullptr);
3557
state = STATE_WAITING;
@@ -154,8 +176,10 @@ bool run(const coroutine_func_t &fn, void *arg) {
154176
if (swoole_event_init(SW_EVENTLOOP_WAIT_EXIT) < 0) {
155177
return false;
156178
}
179+
Coroutine::activate();
157180
long cid = Coroutine::create(fn, arg);
158181
swoole_event_wait();
182+
Coroutine::deactivate();
159183
return cid > 0;
160184
}
161185
} // namespace coroutine

src/coroutine/thread_context.cc

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,34 @@ static String *g_buffer = nullptr;
3030
static AsyncThreads *g_async_threads = nullptr;
3131
static std::mutex *current_lock = nullptr;
3232

33+
void thread_context_init() {
34+
if (!swoole_timer_is_available()) {
35+
swoole_timer_add(1, false, [](Timer *timer, TimerNode *tnode) {
36+
// do nothing
37+
}, nullptr);
38+
}
39+
if (SwooleTG.async_threads == nullptr) {
40+
SwooleTG.async_threads = new AsyncThreads();
41+
}
42+
g_reactor = SwooleTG.reactor;
43+
g_buffer = SwooleTG.buffer_stack;
44+
g_timer = SwooleTG.timer;
45+
g_async_threads = SwooleTG.async_threads;
46+
current_lock = &g_lock;
47+
g_lock.lock();
48+
}
49+
50+
void thread_context_clean() {
51+
g_reactor = nullptr;
52+
g_buffer = nullptr;
53+
g_timer = nullptr;
54+
g_async_threads = nullptr;
55+
current_lock = nullptr;
56+
g_lock.unlock();
57+
}
58+
3359
Context::Context(size_t stack_size, const coroutine_func_t &fn, void *private_data)
3460
: fn_(fn), private_data_(private_data) {
35-
if (sw_unlikely(current_lock == nullptr)) {
36-
current_lock = &g_lock;
37-
if (SwooleTG.timer == nullptr) {
38-
swoole_timer_add(1, false, [](Timer *timer, TimerNode *tnode) {
39-
// do nothing
40-
}, nullptr);
41-
}
42-
if (SwooleTG.async_threads == nullptr) {
43-
SwooleTG.async_threads = new AsyncThreads();
44-
}
45-
g_reactor = SwooleTG.reactor;
46-
g_buffer = SwooleTG.buffer_stack;
47-
g_timer = SwooleTG.timer;
48-
g_async_threads = SwooleTG.async_threads;
49-
g_lock.lock();
50-
}
5161
end_ = false;
5262
lock_.lock();
5363
swap_lock_ = nullptr;

src/server/reactor_thread.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ static int ReactorThread_init(Server *serv, Reactor *reactor, uint16_t reactor_i
822822
reactor->close = Server::close_connection;
823823

824824
reactor->set_exit_condition(Reactor::EXIT_CONDITION_DEFAULT, [thread](Reactor *reactor, int &event_num) -> bool {
825-
return reactor->event_num == thread->pipe_num;
825+
return event_num == (int) thread->pipe_num;
826826
});
827827

828828
reactor->default_error_handler = ReactorThread_onClose;

src/wrapper/timer.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ Timer *sw_timer() {
2525
}
2626
#endif
2727

28+
bool swoole_timer_is_available() {
29+
return SwooleTG.timer != nullptr;
30+
}
31+
2832
TimerNode *swoole_timer_add(long ms, bool persistent, const TimerCallback &callback, void *private_data) {
29-
if (sw_unlikely(SwooleTG.timer == nullptr)) {
33+
if (sw_unlikely(!swoole_timer_is_available())) {
3034
SwooleTG.timer = new Timer();
3135
if (sw_unlikely(!SwooleTG.timer->init())) {
3236
delete SwooleTG.timer;
@@ -72,8 +76,8 @@ long swoole_timer_tick(long ms, const TimerCallback &callback, void *private_dat
7276
}
7377

7478
bool swoole_timer_exists(long timer_id) {
75-
if (!SwooleTG.timer) {
76-
swWarn("no timer");
79+
if (!swoole_timer_is_available()) {
80+
swWarn("timer[%ld] is not exists", timer_id);
7781
return false;
7882
}
7983
TimerNode *tnode = SwooleTG.timer->get(timer_id);
@@ -85,15 +89,15 @@ bool swoole_timer_clear(long timer_id) {
8589
}
8690

8791
TimerNode *swoole_timer_get(long timer_id) {
88-
if (!SwooleTG.timer) {
89-
swWarn("no timer");
92+
if (!swoole_timer_is_available()) {
93+
swWarn("timer[%ld] is not exists", timer_id);
9094
return nullptr;
9195
}
9296
return SwooleTG.timer->get(timer_id);
9397
}
9498

9599
void swoole_timer_free() {
96-
if (!SwooleTG.timer) {
100+
if (!swoole_timer_is_available()) {
97101
return;
98102
}
99103
delete SwooleTG.timer;
@@ -102,7 +106,7 @@ void swoole_timer_free() {
102106
}
103107

104108
int swoole_timer_select() {
105-
if (!SwooleTG.timer) {
109+
if (!swoole_timer_is_available()) {
106110
return SW_ERR;
107111
}
108112
return SwooleTG.timer->select();

tests/init

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function read_sql_file(string $file)
3737

3838
require __DIR__ . '/include/config.php';
3939

40-
go(function () {
40+
Swoole\Coroutine\run(function () {
4141
echo "[DB-init] initialization MySQL database...\n";
4242
$mysql = new Swoole\Coroutine\MySQL();
4343
$connected = $mysql->connect([
@@ -59,4 +59,4 @@ go(function () {
5959
}
6060
}
6161
echo "[DB-init] Done!\n";
62-
});
62+
});

0 commit comments

Comments
 (0)