浏览代码

feat: 新增gc_Factory模块

新增gc_Factory管理gc对象
并使用互斥锁保护
SongZihuan 3 年之前
父节点
当前提交
54a820ca10
共有 4 个文件被更改,包括 124 次插入46 次删除
  1. 1 4
      src/core/__env.h
  2. 16 1
      src/core/__gc.h
  3. 2 0
      src/core/env.c
  4. 105 41
      src/core/gc.c

+ 1 - 4
src/core/__env.h

@@ -223,10 +223,7 @@ struct af_Environment {  // 运行环境
     /* 字面量基本信息 */
     af_LiteralRegex *lr;
 
-    struct af_ObjectData *gc_ObjectData;
-    struct af_Object *gc_Object;
-    struct af_Var *gc_Var;
-    struct af_VarSpace *gc_VarSpace;
+    struct gc_Factory *gc_factory;  // 记录gc信息
 
     struct af_EnvVarSpace *esv;
     struct af_TopMsgProcess *process;

+ 16 - 1
src/core/__gc.h

@@ -1,6 +1,7 @@
 #ifndef AFUN_GC_H_
 #define AFUN_GC_H_
 #include "tool.h"
+#include "pthread.h"
 
 typedef struct GC_Var GC_Var;
 typedef struct GC_VarSpace GC_VarSpace;
@@ -8,10 +9,11 @@ typedef struct GC_Object GC_Object;
 typedef struct GC_ObjectData GC_ObjectData;
 typedef struct af_GcList af_GcList;
 typedef struct gc_Analyzed gc_Analyzed, **pgc_Analyzed;
+typedef struct gc_Factory gc_Factory;
 
 #define GC_FREE_EXCHANGE(obj, Type, Env) do { \
 {if ((obj)->gc.prev != NULL) {(obj)->gc.prev->gc.next = (obj)->gc.next;} \
- else {(Env)->gc_##Type = (obj)->gc.next;}} \
+ else {(Env)->gc_factory->gc_##Type = (obj)->gc.next;}} \
 {if ((obj)->gc.next != NULL) {(obj)->gc.next->gc.prev = (obj)->gc.prev;}}} while(0)
 
 #define GC_CHAIN(type) struct type *next, *prev
@@ -69,6 +71,14 @@ struct gc_Analyzed {
     struct gc_Analyzed *next;
 };
 
+struct gc_Factory {
+    pthread_mutex_t mutex;  // 互斥锁, 保护下面字段
+    struct af_ObjectData *gc_ObjectData;
+    struct af_Object *gc_Object;
+    struct af_Var *gc_Var;
+    struct af_VarSpace *gc_VarSpace;
+};
+
 /* 重新定义包括af_ObjectData的 gc Reference 函数 */
 #ifdef core_shared_t_EXPORTS
 #undef gc_addReference
@@ -92,6 +102,11 @@ struct gc_Analyzed {
                                af_Var *: gc_getVarReference, \
                                af_VarSpace *: gc_getVarSpaceReference))(obj))
 #endif
+
+/* gc_Factory 创建与释放 */
+AFUN_CORE_NO_EXPORT gc_Factory *makegGcFactory(void);
+AFUN_CORE_NO_EXPORT void freeGcFactory(gc_Factory *factory);
+
 /* gc 对象新增函数 */
 AFUN_CORE_NO_EXPORT void gc_addObject(af_Object *obj, af_Environment *env);
 AFUN_CORE_NO_EXPORT void gc_addVar(af_Var *obj, af_Environment *env);

+ 2 - 0
src/core/env.c

@@ -826,6 +826,7 @@ af_Environment *makeEnvironment(enum GcRunTime grt) {
     pthread_mutex_init(&env->in_run, &attr);  // 检测锁
     pthread_mutexattr_destroy(&attr);
 
+    env->gc_factory = makegGcFactory();
     env->esv = makeEnvVarSpace();
 
     /* 设置默认prefix */
@@ -895,6 +896,7 @@ void freeEnvironment(af_Environment *env) {
     gc_freeAllValueData(env);  // 先释放ObjectData的void *data
     printGCByCore(env);
     gc_freeAllValue(env);  // 再完全释放Object
+    freeGcFactory(env->gc_factory);
 
     if (!res)
         writeErrorLog(aFunCoreLogger, "Run iterDestruct error.");

+ 105 - 41
src/core/gc.c

@@ -6,14 +6,15 @@
 #include "pthread.h"
 
 /* gc 操控函数 */
-
 void gc_addObjectData(af_ObjectData *obj, af_Environment *env){
     obj->gc.prev = ((void *) 0);
-    if (env->gc_ObjectData != ((void *) 0))
-        env->gc_ObjectData->gc.prev = obj;
-    obj->gc.next = env->gc_ObjectData;
-    env->gc_ObjectData = obj;
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    if (env->gc_factory->gc_ObjectData != ((void *) 0))
+        env->gc_factory->gc_ObjectData->gc.prev = obj;
+    obj->gc.next = env->gc_factory->gc_ObjectData;
+    env->gc_factory->gc_ObjectData = obj;
     GcCountAdd1(env);
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
 void gc_addObjectDataReference(af_ObjectData *obj){
@@ -30,11 +31,13 @@ GcCount gc_getObjectDataReference(af_ObjectData *obj){
 
 void gc_addObject(af_Object *obj, af_Environment *env){
     obj->gc.prev = ((void *) 0);
-    if (env->gc_Object != ((void *) 0))
-        env->gc_Object->gc.prev = obj;
-    obj->gc.next = env->gc_Object;
-    env->gc_Object = obj;
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    if (env->gc_factory->gc_Object != ((void *) 0))
+        env->gc_factory->gc_Object->gc.prev = obj;
+    obj->gc.next = env->gc_factory->gc_Object;
+    env->gc_factory->gc_Object = obj;
     GcCountAdd1(env);
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
 void gc_addObjectReference(af_Object *obj){
@@ -51,11 +54,13 @@ GcCount gc_getObjectReference(af_Object *obj){
 
 void gc_addVar(af_Var *obj, af_Environment *env) {
     obj->gc.prev = ((void *) 0);
-    if (env->gc_Var != ((void *) 0))
-        env->gc_Var->gc.prev = obj;
-    obj->gc.next = env->gc_Var;
-    env->gc_Var = obj;
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    if (env->gc_factory->gc_Var != ((void *) 0))
+        env->gc_factory->gc_Var->gc.prev = obj;
+    obj->gc.next = env->gc_factory->gc_Var;
+    env->gc_factory->gc_Var = obj;
     GcCountAdd1(env);
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
 void gc_addVarReference(af_Var *obj) {
@@ -72,10 +77,12 @@ GcCount gc_getVarReference(af_Var *obj) {
 
 void gc_addVarSpace(af_VarSpace *obj, af_Environment *env){
     obj->gc.prev = ((void *) 0);
-    if (env->gc_VarSpace != ((void *) 0)) { env->gc_VarSpace->gc.prev = obj; }
-    obj->gc.next = env->gc_VarSpace;
-    env->gc_VarSpace = obj;
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    if (env->gc_factory->gc_VarSpace != ((void *) 0)) { env->gc_factory->gc_VarSpace->gc.prev = obj; }
+    obj->gc.next = env->gc_factory->gc_VarSpace;
+    env->gc_factory->gc_VarSpace = obj;
     GcCountAdd1(env);
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
 void gc_addVarSpaceReference(af_VarSpace *obj) {
@@ -90,6 +97,24 @@ GcCount gc_getVarSpaceReference(af_VarSpace *obj) {
     return obj->gc.info.reference;
 }
 
+/* gc_Factory 函数 */
+gc_Factory *makegGcFactory(void) {
+    gc_Factory *factory = calloc(1, sizeof(gc_Factory));
+
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&factory->mutex, &attr);
+    pthread_mutexattr_destroy(&attr);
+
+    return factory;
+}
+
+void freeGcFactory(struct gc_Factory *factory) {
+    pthread_mutex_destroy(&factory->mutex);
+    free(factory);
+}
+
 /* gcList 函数 */
 /* gcList 创建与释放 */
 static af_GcList *freeGcList(af_GcList *gl);
@@ -156,8 +181,8 @@ static pgc_Analyzed reachableObject(struct af_Object *od, pgc_Analyzed plist);
 /* gc运行函数 */
 static void freeValue(af_Environment *env);
 static pgc_Analyzed reachable(af_Activity *activity, pgc_Analyzed plist);
-static pgc_Analyzed iterLinker(af_Environment *core, pgc_Analyzed plist);
-static pgc_Analyzed checkDestruct(af_Environment *env, paf_GuardianList *pdl, pgc_Analyzed plist);
+static pgc_Analyzed iterLinker(af_Environment *env, pgc_Analyzed plist);
+static pgc_Analyzed checkDestruct(af_Environment *env, paf_GuardianList *pgl, pgc_Analyzed plist);
 static pgc_Analyzed checkAnalyzed(gc_Analyzed *analyzed, pgc_Analyzed plist);
 
 // 使用 gc_Analyzed 目的是令可达性分析程序不需要使用递归
@@ -262,25 +287,27 @@ static pgc_Analyzed iterLinker(af_Environment *env, pgc_Analyzed plist) {
     if (env->global != NULL)
         plist = reachableObject(env->global, plist);
 
-    for (af_ObjectData *od = env->gc_ObjectData; od != NULL; od = od->gc.next) {
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData; od != NULL; od = od->gc.next) {
         if (!od->gc.info.reachable && (od->gc.info.reference > 0 || od->gc.info.not_clear))
             plist = reachableObjectData(od, plist);
     }
 
-    for (af_Object *obj = env->gc_Object; obj != NULL; obj = obj->gc.next) {
+    for (af_Object *obj = env->gc_factory->gc_Object; obj != NULL; obj = obj->gc.next) {
         if (!obj->gc.info.reachable && (obj->gc.info.reference > 0 || obj->gc.info.not_clear))
             plist = reachableObject(obj, plist);
     }
 
-    for (af_VarSpace *vs = env->gc_VarSpace; vs != NULL; vs = vs->gc.next) {
+    for (af_VarSpace *vs = env->gc_factory->gc_VarSpace; vs != NULL; vs = vs->gc.next) {
         if (!vs->gc.info.reachable && (vs->gc.info.reference > 0 || vs->gc.info.not_clear))
             plist = reachableVarSpace(vs, plist);
     }
 
-    for (af_Var *var = env->gc_Var; var != NULL; var = var->gc.next) {
+    for (af_Var *var = env->gc_factory->gc_Var; var != NULL; var = var->gc.next) {
         if (!var->gc.info.reachable && (var->gc.info.reference > 0 || var->gc.info.not_clear))
             plist = reachableVar(var, plist);
     }
+    pthread_mutex_unlock(&env->gc_factory->mutex);
     return plist;
 }
 
@@ -316,25 +343,28 @@ static pgc_Analyzed checkAnalyzed(gc_Analyzed *analyzed, pgc_Analyzed plist) {
 }
 
 void resetGC(af_Environment *env) {
-    for (af_ObjectData *od = env->gc_ObjectData; od != NULL; od = od->gc.next)
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData; od != NULL; od = od->gc.next)
         od->gc.info.reachable = false;
 
-    for (af_Object *obj = env->gc_Object; obj != NULL; obj = obj->gc.next)
+    for (af_Object *obj = env->gc_factory->gc_Object; obj != NULL; obj = obj->gc.next)
         obj->gc.info.reachable = false;
 
-    for (af_VarSpace *vs = env->gc_VarSpace; vs != NULL; vs = vs->gc.next)
+    for (af_VarSpace *vs = env->gc_factory->gc_VarSpace; vs != NULL; vs = vs->gc.next)
         vs->gc.info.reachable = false;
 
-    for (af_Var *var = env->gc_Var; var != NULL; var = var->gc.next)
+    for (af_Var *var = env->gc_factory->gc_Var; var != NULL; var = var->gc.next)
         var->gc.info.reachable = false;
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
 /**
  * 清理对象, 清除不可达的对象
+ * 内部函数, 不上锁
  * @param env
  */
 static void freeValue(af_Environment *env) {
-    for (af_ObjectData *od = env->gc_ObjectData, *next; od != NULL; od = next) {
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData, *next; od != NULL; od = next) {
         next = od->gc.next;
         if (!od->gc.info.reachable) {
             writeTrackLog(aFunCoreLogger, "ObjectData: %p", od);
@@ -342,7 +372,7 @@ static void freeValue(af_Environment *env) {
         }
     }
 
-    for (af_Object *obj = env->gc_Object, *next; obj != NULL; obj = next) {
+    for (af_Object *obj = env->gc_factory->gc_Object, *next; obj != NULL; obj = next) {
         next = obj->gc.next;
         if (!obj->gc.info.reachable) {
             writeTrackLog(aFunCoreLogger, "Object: %p", obj);
@@ -350,7 +380,7 @@ static void freeValue(af_Environment *env) {
         }
     }
 
-    for (af_VarSpace *vs = env->gc_VarSpace, *next; vs != NULL; vs = next) {
+    for (af_VarSpace *vs = env->gc_factory->gc_VarSpace, *next; vs != NULL; vs = next) {
         next = vs->gc.next;
         if (!vs->gc.info.reachable) {
             writeTrackLog(aFunCoreLogger, "VarSpace: %p", vs);
@@ -358,7 +388,7 @@ static void freeValue(af_Environment *env) {
         }
     }
 
-    for (af_Var *var = env->gc_Var, *next; var != NULL; var = next) {
+    for (af_Var *var = env->gc_factory->gc_Var, *next; var != NULL; var = next) {
         next = var->gc.next;
         if (!var->gc.info.reachable) {
             writeTrackLog(aFunCoreLogger, "Var: %p", var);
@@ -367,8 +397,16 @@ static void freeValue(af_Environment *env) {
     }
 }
 
+/**
+ * 检查对象是否有析构函数
+ * 内部函数, 不上锁
+ * @param env
+ * @param pgl
+ * @param plist
+ * @return
+ */
 static pgc_Analyzed checkDestruct(af_Environment *env, paf_GuardianList *pgl, pgc_Analyzed plist) {
-    for (af_ObjectData *od = env->gc_ObjectData; od != NULL; od = od->gc.next) {
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData; od != NULL; od = od->gc.next) {
         if (!od->gc.info.reachable && !od->gc.done_destruct) {
             af_Object *func = findObjectAttributesByObjectData(mg_gc_destruct, NULL, od);
             if (func == NULL)
@@ -400,8 +438,16 @@ af_GuardianList *gc_RunGC(af_Environment *env) {
     return gl;
 }
 
+/**
+ * 检查所有ObjectData的析构函数
+ * 非内部函数, 会上锁
+ * @param env
+ * @param pgl
+ * @return
+ */
 paf_GuardianList checkAllDestruct(af_Environment *env, paf_GuardianList pgl) {
-    for (af_ObjectData *od = env->gc_ObjectData; od != NULL; od = od->gc.next) {
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData; od != NULL; od = od->gc.next) {
         if (!od->gc.done_destruct) {
             af_Object *func = findObjectAttributesByObjectData(mg_gc_destruct, NULL, od);
             if (func == NULL)
@@ -410,40 +456,58 @@ paf_GuardianList checkAllDestruct(af_Environment *env, paf_GuardianList pgl) {
             pgl = pushGuardianList(od->base, func, pgl);
         }
     }
+    pthread_mutex_unlock(&env->gc_factory->mutex);
     return pgl;
 }
 
+/**
+ * 释放所有ObjectData的 void *Data
+ * @param env
+ */
 void gc_freeAllValueData(af_Environment *env) {
-    for (af_ObjectData *od = env->gc_ObjectData; od != NULL; od = od->gc.next) {
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData; od != NULL; od = od->gc.next) {
         freeObjectDataData(od, env);
     }
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
+/**
+ * 释放所有的Value
+ * @param env
+ */
 void gc_freeAllValue(af_Environment *env) {
-    for (af_ObjectData *od = env->gc_ObjectData, *next; od != NULL; od = next) {
+    pthread_mutex_lock(&env->gc_factory->mutex);
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData, *next; od != NULL; od = next) {
         next = od->gc.next;
         freeObjectData(od, env);
     }
 
-    for (af_Object *obj = env->gc_Object, *next; obj != NULL; obj = next) {
+    for (af_Object *obj = env->gc_factory->gc_Object, *next; obj != NULL; obj = next) {
         next = obj->gc.next;
         freeObject(obj, env);
     }
 
-    for (af_VarSpace *vs = env->gc_VarSpace, *next; vs != NULL; vs = next) {
+    for (af_VarSpace *vs = env->gc_factory->gc_VarSpace, *next; vs != NULL; vs = next) {
         next = vs->gc.next;
         freeVarSpace(vs, env);
     }
 
-    for (af_Var *var = env->gc_Var, *next; var != NULL; var = next) {
+    for (af_Var *var = env->gc_factory->gc_Var, *next; var != NULL; var = next) {
         next = var->gc.next;
         freeVar(var, env);
     }
+    pthread_mutex_unlock(&env->gc_factory->mutex);
 }
 
+/**
+ * Debug用的函数
+ * 不上锁
+ * @param env
+ */
 void printGCByCore(af_Environment *env) {
     bool success = true;
-    for (af_ObjectData *od = env->gc_ObjectData; od != NULL; od = od->gc.next) {
+    for (af_ObjectData *od = env->gc_factory->gc_ObjectData; od != NULL; od = od->gc.next) {
         if (od->gc.info.reference != 0) {
             writeWarningLog(aFunCoreLogger, "af_ObjectData(%p) Reference: %d", od, od->gc.info.reference);
             success = false;
@@ -451,7 +515,7 @@ void printGCByCore(af_Environment *env) {
             writeTrackLog(aFunCoreLogger, "af_ObjectData(%p) Reference: %d", od, od->gc.info.reference);
     }
 
-    for (af_Object *obj = env->gc_Object; obj != NULL; obj = obj->gc.next) {
+    for (af_Object *obj = env->gc_factory->gc_Object; obj != NULL; obj = obj->gc.next) {
         if (obj->gc.info.reference != 0) {
             writeWarningLog(aFunCoreLogger, "af_Object(%p->%p) Reference: %d", obj, obj->data, obj->gc.info.reference);
             success = false;
@@ -459,7 +523,7 @@ void printGCByCore(af_Environment *env) {
             writeTrackLog(aFunCoreLogger, "af_Object(%p->%p) Reference: %d", obj, obj->data, obj->gc.info.reference);
     }
 
-    for (af_VarSpace *vs = env->gc_VarSpace; vs != NULL; vs = vs->gc.next) {
+    for (af_VarSpace *vs = env->gc_factory->gc_VarSpace; vs != NULL; vs = vs->gc.next) {
         if (vs->gc.info.reference != 0) {
             writeWarningLog(aFunCoreLogger, "af_VarSpace(%p) Reference: %d", vs, vs->gc.info.reference);
             success = false;
@@ -467,7 +531,7 @@ void printGCByCore(af_Environment *env) {
             writeTrackLog(aFunCoreLogger, "af_VarSpace(%p) Reference: %d", vs, vs->gc.info.reference);
     }
 
-    for (af_Var *var = env->gc_Var; var != NULL; var = var->gc.next) {
+    for (af_Var *var = env->gc_factory->gc_Var; var != NULL; var = var->gc.next) {
         if (var->gc.info.reference != 0) {
             writeWarningLog(aFunCoreLogger, "af_Var(%p) Reference: %d", var, var->gc.info.reference);
             success = false;