Skip to content

Commit 4c73a5a

Browse files
committed
[optimization] #support reference params
1 parent f51602e commit 4c73a5a

File tree

5 files changed

+41
-28
lines changed

5 files changed

+41
-28
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ GPM 多线程协程调度器 for PHP Extension
3838
```php
3939
<?php
4040
Runtime::GOMAXPROCS(10);
41+
$ref = ["ref"];
4142
for($i = 0;$i <100; $i++)
4243
{
43-
go(function()use($i){
44+
//support reference params
45+
go(function()use($i,&$ref){
4446
go(function(){
45-
//echo "go yield \n";
46-
//goyield();
47-
//echo "go end \n";
47+
var_dump($i,$ref);
4848
});
4949
});
5050
}

coroutine/Coroutine.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ long Coroutine::run()
5757
*/
5858
void Coroutine::yield()
5959
{
60-
Debug("yield G: g:%ld",this);
60+
Debug("yield G: g:%x",this);
6161
PHPCoroutine::save_stack(&main_stack);
6262
restore_stack(stack);
6363
{
6464
// unique_lock <mutex> lock(*GO_ZG(_glock));
65-
Debug("_glock:%ld",GO_ZG(_glock));
65+
Debug("_glock:%x",GO_ZG(_glock));
6666
GO_ZG(_g) = nullptr;
6767
//每次切换出去时需要更新tick 和时间
6868
GO_ZG(schedwhen) = chrono::steady_clock::now();
@@ -78,15 +78,15 @@ void Coroutine::yield()
7878
*/
7979
void Coroutine::newproc()
8080
{
81-
Debug("run new G: g:%ld",this);
81+
Debug("run new G: g:%x",this);
8282
callback->is_new = 0;
8383
callback->prepare_functions(this);
8484
PHPCoroutine::save_stack(&main_stack);
8585
{
8686
unique_lock <mutex> lock(*GO_ZG(_glock),defer_lock);
8787
if(!lock.try_lock())
8888
Debug(" not get the lock");
89-
Debug("_glock:%ld",GO_ZG(_glock));
89+
Debug("_glock:%x",GO_ZG(_glock));
9090
GO_ZG(_g) = this;
9191
//每次切入时出去时需要更新tick 和时间
9292
GO_ZG(schedwhen) = chrono::steady_clock::now();
@@ -102,14 +102,14 @@ void Coroutine::newproc()
102102
*/
103103
void Coroutine::resume()
104104
{
105-
Debug("resume G: mark Grunnable g:%ld",this);
105+
Debug("resume G: mark Grunnable g:%x",this);
106106
restore_stack(&main_stack);
107107
PHPCoroutine::save_stack(stack);
108108
{
109109
unique_lock <mutex> lock(*GO_ZG(_glock),defer_lock);
110110
if(!lock.try_lock())
111111
Debug(" not get the lock");
112-
Debug("_glock:%ld",GO_ZG(_glock));
112+
Debug("_glock:%x",GO_ZG(_glock));
113113
GO_ZG(_g) = this;
114114
//每次切入时出去时需要更新tick 和时间
115115
GO_ZG(schedwhen) = chrono::steady_clock::now();
@@ -123,7 +123,7 @@ void Coroutine::resume()
123123
*/
124124
void Coroutine::stackpreempt()
125125
{
126-
Debug("exec stack preempt:%ld gstatus:%d ctx->is_end:%d",this,gstatus,ctx->is_end);
126+
Debug("exec stack preempt:%x gstatus:%d ctx->is_end:%d",this,gstatus,ctx->is_end);
127127
// gstatus = Preempt;
128128
yield();
129129

runtime/Proc.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ void Proc::schedule()
9595
}
9696
}
9797
if(co == nullptr){
98-
Debug("co exception:%ld",co);
98+
Debug("co exception:%x",co);
9999
continue;
100100
}
101-
Debug("get one G: %ld",co);
101+
Debug("get one G: %x",co);
102102
//当前线程分配到一个未初始化的G
103103
if(co->gstatus == Gidle) co->newproc();
104104
//恢复被暂停的G

runtime/Sysmon.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void Sysmon::sighandler(int signo)
1919
lock.lock();
2020
Coroutine *co = GO_ZG(_g);
2121
if(co == nullptr)return;
22-
Debug("receive signal:%d _g:%ld co->status:%d Grunnable:%d",signo,co,co->gstatus,Grunnable);
22+
Debug("receive signal:%d _g:%x co->status:%d Grunnable:%d",signo,co,co->gstatus,Grunnable);
2323
//判断当前G是否状态正常
2424
if(co->gstatus == Grunnable){
2525
//抢占切出
@@ -53,7 +53,7 @@ void Sysmon::preemptPark(M *m)
5353
Coroutine *co = GO_FETCH(m->_m,_g);
5454
//发起抢占前判断G是否正常
5555
if(co == nullptr)return;
56-
Debug("start park preempt: _g:%ld co->gstatus:%d Grunnable:%d",co,co->gstatus,Grunnable);
56+
Debug("start park preempt: _g:%x co->gstatus:%d Grunnable:%d",co,co->gstatus,Grunnable);
5757
if(co->gstatus == Grunnable){
5858
Debug("start send signal:%d",SIGURG);
5959
pthread_kill(m->tid, SIGURG);
@@ -69,7 +69,7 @@ void Sysmon::preemptM(M *m)
6969
{
7070
//检查周期是否一致
7171
if(m->tick != m->G->schedtick){
72-
Debug("period not consistent m:%ld",m->tid);
72+
Debug("period not consistent m:%x",m->tid);
7373
m->tick = m->G->schedtick;
7474
return;
7575
}
@@ -110,7 +110,7 @@ void Sysmon::monitor()
110110
Debug("not get lock");
111111
continue;
112112
}
113-
Debug("mid:%ld G:%ld _g:%d _glock:%ld",m.tid,m.G,m.G->_g,m.G->_glock);
113+
Debug("mid:%x G:%x _g:%d _glock:%x",m.tid,m.G,m.G->_g,m.G->_glock);
114114
if(m.G->_g != nullptr){
115115
preemptM(&m);
116116
}else if(proc->tasks.empty() && m.G->runq->empty()){

runtime/ZendFunction.cpp

+24-11
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
void ZendFunction::freehash(zval *zval_ptr)
88
{
99

10-
// if(Z_TYPE_P(zval_ptr) == IS_NULL){
11-
// cout << "该变量为 null" <<endl;
12-
// return;
13-
// }
10+
Debug("zend_hash_destory: zval:%x type:%d",zval_ptr,Z_TYPE_P(zval_ptr));
11+
if(Z_TYPE_P(zval_ptr) == IS_NULL) {
12+
return;
13+
}
14+
if(Z_TYPE_P(zval_ptr) == IS_REFERENCE) {
15+
int gccount = GC_REFCOUNT(Z_REF_P(zval_ptr));
16+
Debug("reference gc count:%d",gccount);
17+
return;
18+
}
1419
zval_ptr_dtor(zval_ptr);
1520
}
1621
/**
@@ -60,15 +65,15 @@ void ZendFunction::prepare_functions(Coroutine *co) {
6065
void *value = NULL,*prepared = NULL;
6166
//TODO: need handle it,could crash
6267
zend_compiler_globals* cg = ((zend_compiler_globals *) (*((void ***) co->creator))[TSRM_UNSHUFFLE_RSRC_ID(compiler_globals_id)]);
63-
Debug("creator:%ld cgid:%ld cg:%ld null:%d",co->creator,compiler_globals_id,cg,cg== nullptr);
68+
Debug("creator:%x cgid:%ld cg:%x null:%d",co->creator,compiler_globals_id,cg,cg== nullptr);
6469
if(cg == nullptr){
6570
cg = ((zend_compiler_globals *) (*((void ***) co->creator))[TSRM_UNSHUFFLE_RSRC_ID(compiler_globals_id)]);
66-
Error("creator thread local not exist cg:%ld",cg);
71+
Error("creator thread local not exist cg:%x",cg);
6772
return;
6873
}
6974
HashTable *function_table = cg->function_table;
7075
HashTable *local_table = CG(function_table);
71-
Debug("origin:%ld local:%ld",function_table,local_table)
76+
Debug("origin:%x local:%x",function_table,local_table)
7277
ZEND_HASH_FOREACH_STR_KEY_PTR(function_table, key, value)
7378
{
7479
if (((zend_function*)value)->type == ZEND_INTERNAL_FUNCTION ||
@@ -77,7 +82,7 @@ void ZendFunction::prepare_functions(Coroutine *co) {
7782
name = zend_string_new(key);
7883
prepared = copy_function((zend_function*)value);
7984
if (!zend_hash_add_ptr(local_table, name, prepared)) {
80-
Debug("function table add failed: %ld",local_table)
85+
Debug("function table add failed: %x",local_table)
8186
destroy_op_array((zend_op_array*)prepared);
8287
}
8388

@@ -109,6 +114,7 @@ zend_function* ZendFunction::copy_user_function(zend_function *function)
109114
{
110115
zend_function *copy;
111116
zend_op_array *op_array;
117+
zend_op_array *old_op_array;
112118
zend_string **variables, *filename_copy;
113119
zval *literals;
114120
zend_arg_info *arg_info;
@@ -120,6 +126,7 @@ zend_function* ZendFunction::copy_user_function(zend_function *function)
120126
variables = op_array->vars;
121127
literals = op_array->literals;
122128
arg_info = op_array->arg_info;
129+
old_op_array = (zend_op_array*)function;
123130

124131
// op_array->function_name = zend_string_new(op_array->function_name);
125132
op_array->function_name = ZendString::copy_string(op_array->function_name,is_new);
@@ -154,7 +161,9 @@ zend_function* ZendFunction::copy_user_function(zend_function *function)
154161
if (op_array->live_range) op_array->live_range = copy_live(op_array->live_range, op_array->last_live_range);
155162
if (op_array->try_catch_array) op_array->try_catch_array = copy_try(op_array->try_catch_array, op_array->last_try_catch);
156163
if (op_array->vars) op_array->vars = copy_variables(variables, op_array->last_var);
157-
if (op_array->static_variables) op_array->static_variables = copy_statics(op_array->static_variables);
164+
// if (op_array->static_variables) op_array->static_variables = copy_statics(op_array->static_variables);
165+
if (op_array->static_variables) op_array->static_variables = copy_statics(old_op_array->static_variables);
166+
// op_array->static_variables = old_op_array->static_variables;
158167

159168
return copy;
160169
}
@@ -201,8 +210,12 @@ HashTable* ZendFunction::copy_statics(HashTable *old) {
201210
ZEND_HASH_FOREACH_STR_KEY_VAL(old, key, value) {
202211
zend_string *name = zend_string_new(key);
203212
zval *next = value;
204-
while (Z_TYPE_P(next) == IS_REFERENCE)
205-
next = &Z_REF_P(next)->val;
213+
// while (Z_TYPE_P(next) == IS_REFERENCE)
214+
// next = &Z_REF_P(next)->val;
215+
if(Z_TYPE_P(next) == IS_REFERENCE){
216+
zend_hash_add(statics, name, next);
217+
continue;
218+
}
206219

207220
if (Z_REFCOUNTED_P(next)) {
208221
zval copy;

0 commit comments

Comments
 (0)