Pārlūkot izejas kodu

feat: Activity加锁

SongZihuan 3 gadi atpakaļ
vecāks
revīzija
b95601841e
4 mainītis faili ar 71 papildinājumiem un 18 dzēšanām
  1. 2 0
      src/core/__env.h
  2. 53 15
      src/core/env.c
  3. 5 1
      src/core/gc.c
  4. 11 2
      src/core/run.c

+ 2 - 0
src/core/__env.h

@@ -54,6 +54,8 @@ struct af_Activity {  // 活动记录器
         act_guardian,  /* 守护器 */
     } type;
 
+    /* gc锁, 保护belong, run_varlist, func, return_obj, parentheses_call, macro_varlistm func_varlist */
+    pthread_rwlock_t gc_lock;  // gc读时上读锁, 解释器所在进读时不上锁, 写时上写锁
     struct af_Object *belong;  // 属对象 (belong通常为func的belong)
 
     struct af_Message *msg_down;  // 被调用者向调用者传递信息

+ 53 - 15
src/core/env.c

@@ -185,6 +185,7 @@ static af_Activity *makeActivity(af_Message *msg_up, af_VarSpaceListNode *varlis
     activity->count_run_varlist = 0;
     activity->belong = belong;
     activity->line = 1;
+    pthread_rwlock_init(&activity->gc_lock, NULL);
     return activity;
 }
 
@@ -247,6 +248,7 @@ static af_Activity *makeGuardianActivity(af_GuardianList *gl, af_GuardianList **
 }
 
 static af_Activity *freeActivity(af_Activity *activity) {
+    pthread_rwlock_wrlock(&activity->gc_lock);
     af_Activity *prev = activity->prev;
 
     freeAllMessage(activity->msg_down);  // msg转移后需要将对应成员设置为NULL
@@ -271,6 +273,8 @@ static af_Activity *freeActivity(af_Activity *activity) {
         free(activity->import_mark);
     }
 
+    pthread_rwlock_unlock(&activity->gc_lock);
+    pthread_rwlock_destroy(&activity->gc_lock);
     free(activity);
     return prev;
 }
@@ -307,6 +311,7 @@ static void clearFuncActivity(af_Activity *activity) {
     /* acl在runArgList之后就被释放了 */
     /* acl在FuncBody暂时不释放 */
 
+    pthread_rwlock_wrlock(&activity->gc_lock);
     activity->out_varlist = activity->run_varlist;
     activity->count_out_varlist = activity->count_run_varlist;
     activity->count_run_varlist = 0;
@@ -315,6 +320,13 @@ static void clearFuncActivity(af_Activity *activity) {
     activity->count_macro_varlist = 0;
 
     activity->func_varlist = NULL;
+
+    /* mark在setFuncActivityToNormal被清理*/
+    /* 只有FuncBody执行到最后一个(意味着Mark被清理)后才会有尾调用优化 */
+    activity->mark = NULL;
+    activity->func = NULL;
+    pthread_rwlock_unlock(&activity->gc_lock);
+
     setActivityBtTop(NULL, activity);
     setActivityBtStart(NULL, activity);
 
@@ -324,11 +336,6 @@ static void clearFuncActivity(af_Activity *activity) {
 
     /* activity->fi 暂时不清理, 直到setFuncActivityAddVar时才清理 */
     activity->body_next = NULL;
-
-    /* mark在setFuncActivityToNormal被清理*/
-    /* 只有FuncBody执行到最后一个(意味着Mark被清理)后才会有尾调用优化 */
-    activity->mark = NULL;
-    activity->func = NULL;
 }
 
 /*
@@ -375,7 +382,10 @@ static void tailCallActivity(af_Object *func, af_Activity *activity) {
     atb->next = activity->tb;
     clearFuncActivity(activity);
     activity->tb = atb;
+
+    pthread_rwlock_wrlock(&activity->gc_lock);
     activity->func = func;
+    pthread_rwlock_unlock(&activity->gc_lock);
 }
 
 /*
@@ -1175,7 +1185,10 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env) {
     af_Code *next;
     af_Code *func;
     af_Object *parentheses_call = env->activity->parentheses_call;
+
+    pthread_rwlock_wrlock(&env->activity->gc_lock);
     env->activity->parentheses_call = NULL;
+    pthread_rwlock_unlock(&env->activity->gc_lock);
 
     writeTrackLog(aFunCoreLogger, "Run func");
     next = getCodeNext(bt);
@@ -1250,23 +1263,27 @@ bool pushMacroFuncActivity(af_Object *func, af_Environment *env) {
     ActivityCount count = env->activity->count_macro_varlist;
     env->activity->count_macro_varlist = 0;
 
+    pthread_rwlock_wrlock(&env->activity->gc_lock);
+    af_VarSpaceListNode *tmp = env->activity->run_varlist;
+    env->activity->run_varlist = NULL;
+    pthread_rwlock_unlock(&env->activity->gc_lock);
+
     writeTrackLog(aFunCoreLogger, "Run macro");
-    if (!freeVarSpaceListCount(env->activity->count_run_varlist, env->activity->run_varlist)) { // 释放外部变量空间
+    if (!freeVarSpaceListCount(env->activity->count_run_varlist, tmp)) { // 释放外部变量空间
         env->activity->count_run_varlist = 0;
-        env->activity->run_varlist = NULL;
         pushMessageDown(makeERRORMessage(RUN_ERROR, FREE_VARSPACE_INFO, env), env);
         return false;
     }
 
     env->activity->count_run_varlist = 0;
-    env->activity->run_varlist = NULL;
-
     tailCallActivity(func, env->activity);  /* 隐式调用不设置 bt_top */
 
     /* tailCallActivity 会清除 out_varlist 的设定 */
+    pthread_rwlock_wrlock(&env->activity->gc_lock);
     env->activity->out_varlist = macro_varlist;
     env->activity->count_out_varlist = count;
     env->activity->is_macro_call = true;
+    pthread_rwlock_unlock(&env->activity->gc_lock);
     return setFuncActivityToArg(func, env);
 }
 
@@ -1328,15 +1345,19 @@ bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
     af_ObjectAPI *api = getObjectAPI(func);
     obj_funcGetArgCodeList *get_acl = findAPI("obj_funcGetArgCodeList", api);
     obj_funcGetVarList *get_var_list = findAPI("obj_funcGetVarList", api);
+    af_VarSpaceListNode *func_varlist = NULL;
+    af_Object *belong = getBelongObject(func);
 
     if (get_var_list == NULL) {
         pushMessageDown(makeERRORMessage(TYPE_ERROR, API_NOT_FOUND_INFO(obj_funcGetVarList), env), env);
         return false;
     }
 
+    pthread_rwlock_wrlock(&env->activity->gc_lock);
     env->activity->func = func;
-    env->activity->belong = getBelongObject(func);
+    env->activity->belong = belong;
     env->activity->status = act_func_arg;
+    pthread_rwlock_unlock(&env->activity->gc_lock);
 
     /* 遇到错误时 get_acl 和 get_var_list 要自行设定msg */
     if (get_acl != NULL) {
@@ -1378,6 +1399,9 @@ bool setFuncActivityAddVar(af_Environment *env){
         return false;
     }
 
+    af_VarSpaceListNode *tmp = NULL;  // 临时变量, 存放内容见代码注释
+    pthread_rwlock_wrlock(&env->activity->gc_lock);
+
     if (fi->is_macro) {  // 是宏函数则保存变量空间
         env->activity->macro_varlist = env->activity->out_varlist;
         env->activity->count_macro_varlist = env->activity->count_out_varlist;
@@ -1393,21 +1417,34 @@ bool setFuncActivityAddVar(af_Environment *env){
         env->activity->run_varlist = env->activity->func_varlist;
     } else if (fi->scope == pure_scope) {  // 纯函数只有 protect 变量空间
         env->activity->count_run_varlist = 1;
-        env->activity->run_varlist = makeVarSpaceList(env->protect);
+        pthread_rwlock_unlock(&env->activity->gc_lock);
+
+        tmp = makeVarSpaceList(env->protect);  // 该过程不加gc锁, 避免死锁
+
+        pthread_rwlock_wrlock(&env->activity->gc_lock);
+        env->activity->run_varlist = tmp;
     } else if (fi->scope == super_pure_scope) {  // 超纯函数没有变量空间, 因此不得为超内嵌函数(否则var_list就为NULL了)
         env->activity->count_run_varlist = 0;
         env->activity->run_varlist = NULL;
     }
 
     env->activity->func_varlist = NULL;
-    freeVarSpaceListCount(env->activity->count_out_varlist, env->activity->out_varlist);
-    env->activity->count_out_varlist = 0;
+    tmp = env->activity->out_varlist;
     env->activity->out_varlist = NULL;
 
+    pthread_rwlock_unlock(&env->activity->gc_lock);
+
+    freeVarSpaceListCount(env->activity->count_out_varlist, tmp);  // freeVarSpaceListCount 前释放, 避免死锁
+    env->activity->count_out_varlist = 0;
+
     if (fi->embedded != super_embedded) {  // 不是超内嵌函数则引入一层新的变量空间
         /* 新层的变量空间应该属于belong而不是func */
-        env->activity->run_varlist = pushNewVarList(env->activity->belong, env->activity->run_varlist, env);
+        tmp = pushNewVarList(env->activity->belong, env->activity->run_varlist, env);
+
+        pthread_rwlock_wrlock(&env->activity->gc_lock);
+        env->activity->run_varlist = tmp;
         env->activity->count_run_varlist++;
+        pthread_rwlock_unlock(&env->activity->gc_lock);
     }
 
     if (fi->var_this && env->activity->belong != NULL) {
@@ -1429,7 +1466,8 @@ bool setFuncActivityAddVar(af_Environment *env){
     /* 计算参数 */
     if (get_arg_list != NULL) {
         af_ArgList *al;
-        if (!get_arg_list(getObjectID(env->activity->func), env->activity->func, &al, env->activity->acl_start, env->activity->mark, env))
+        if (!get_arg_list(getObjectID(env->activity->func), env->activity->func, &al, env->activity->acl_start,
+                          env->activity->mark, env))
             return false;
         runArgList(al, env->activity->run_varlist, env);
         freeAllArgList(al);

+ 5 - 1
src/core/gc.c

@@ -333,13 +333,16 @@ static pgc_Analyzed iterEnvironment(af_Environment *env, pgc_Analyzed plist) {
 
 static pgc_Analyzed reachable(af_Activity *activity, pgc_Analyzed plist) {
     for (NULL; activity != NULL; activity = activity->prev) {
+        pthread_rwlock_rdlock(&activity->gc_lock);
         if (activity->belong != NULL)
             plist = reachableObject(activity->belong, plist);
 
         plist = reachableVarSpaceList(activity->run_varlist, plist);
 
-        if (activity->type == act_guardian)  // gc不执行接下来的检查
+        if (activity->type == act_guardian) {  // gc不执行接下来的检查
+            pthread_rwlock_unlock(&activity->gc_lock);
             continue;
+        }
 
         if (activity->func != NULL)
             plist = reachableObject(activity->func, plist);
@@ -352,6 +355,7 @@ static pgc_Analyzed reachable(af_Activity *activity, pgc_Analyzed plist) {
 
         plist = reachableVarSpaceList(activity->func_varlist, plist);
         plist = reachableVarSpaceList(activity->macro_varlist, plist);
+        pthread_rwlock_unlock(&activity->gc_lock);
     }
     return plist;
 }

+ 11 - 2
src/core/run.c

@@ -268,7 +268,9 @@ static int checkMsg(af_Message *msg, af_Environment *env) {
     pushMessageDown(msg, env);  // msg不弹出
     if (env->activity->status != act_func_normal || !checkInMsgType(msg->type, env)) {  // 非normal模式, 或normal模式下msg_type不匹配该msg
         env->activity->return_first = false;
+        pthread_rwlock_wrlock(&env->activity->gc_lock);
         env->activity->return_obj = NULL;
+        pthread_rwlock_unlock(&env->activity->gc_lock);
         return 0;
     }
 
@@ -310,7 +312,9 @@ bool checkNormalEnd(af_Message *msg, af_Environment *env) {
     } else if (msg != NULL) {
         if (env->activity->bt_next->type == code_block && env->activity->bt_next->block.type == parentheses &&
             env->activity->bt_next->prefix != getPrefix(B_EXEC, env)) {
+            pthread_rwlock_wrlock(&env->activity->gc_lock);
             env->activity->parentheses_call = *(af_Object **) (msg->msg);  // 类前缀调用
+            pthread_rwlock_unlock(&env->activity->gc_lock);
         }
         gc_delReference(*(af_Object **)(msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
         freeMessage(msg);
@@ -396,6 +400,7 @@ bool iterCode(af_Code *code, int mode, af_Environment *env){
         }
 
         /* 切换执行的 var_list */
+        pthread_rwlock_wrlock(&env->activity->gc_lock);
         if (env->activity->type == act_func && env->activity->status == act_func_arg) {
             if (env->activity->run_in_func && env->activity->func_varlist != NULL)
                 env->activity->run_varlist = env->activity->func_varlist;
@@ -406,6 +411,7 @@ bool iterCode(af_Code *code, int mode, af_Environment *env){
             env->activity->run_varlist = env->activity->out_varlist;
             env->activity->count_run_varlist = 0;
         }
+        pthread_rwlock_unlock(&env->activity->gc_lock);
 
         /* 无代码运行 */
         if (env->activity->bt_next == NULL && env->activity->process_msg_first == 0) {  // 无代码运行, 并且非msg_first
@@ -457,8 +463,11 @@ bool iterCode(af_Code *code, int mode, af_Environment *env){
                 popActivity(false, NULL, env);  // 跳出当前activity
                 continue;  // 下面的代码不再执行
             case 1:  // 正常信号
-                if (env->activity->return_first && env->activity->return_obj == NULL)  // 设置return_first
-                    env->activity->return_obj = *(af_Object **)msg->msg;
+                if (env->activity->return_first && env->activity->return_obj == NULL) { // 设置return_first
+                    pthread_rwlock_wrlock(&env->activity->gc_lock);
+                    env->activity->return_obj = *(af_Object **) msg->msg;
+                    pthread_rwlock_unlock(&env->activity->gc_lock);
+                }
                 break;
             case -1:  // NORMAL模式下, 非正常但可处理 [已经放回]
             default: