ソースを参照

feat: 多线程支持

SongZihuan 3 年 前
コミット
0859521a63
7 ファイル変更95 行追加5 行削除
  1. 1 0
      include/core/aFunCore.h
  2. 2 0
      include/core/env.h
  3. 8 0
      include/core/thread.h
  4. 2 2
      src/core/env.c
  5. 69 0
      src/core/thread.c
  6. 3 3
      src/tool/log.c
  7. 10 0
      test/src/run_code.c

+ 1 - 0
include/core/aFunCore.h

@@ -24,5 +24,6 @@
 #include "reader.h"
 #include "token.h"
 #include "global_obj.h"
+#include "thread.h"
 
 #endif //AFUN_AFUNCORE_H

+ 2 - 0
include/core/env.h

@@ -32,6 +32,8 @@ enum GcRunTime {
 /* 运行环境 创建与释放 */
 AFUN_CORE_EXPORT af_Environment *makeEnvironment(enum GcRunTime grt);
 AFUN_CORE_EXPORT bool freeEnvironment(af_Environment *env);
+AFUN_CORE_EXPORT af_Environment *deriveEnvironment(bool derive_tmp, bool derive_guardian, bool derive_lr, bool enable,
+                                                   af_Environment *base);
 
 /* 消息 创建与释放 */
 AFUN_CORE_EXPORT af_Message *makeMessage(char *type, size_t size);

+ 8 - 0
include/core/thread.h

@@ -0,0 +1,8 @@
+#ifndef AFUN_THREAD_H
+#define AFUN_THREAD_H
+
+AFUN_CORE_EXPORT af_Environment *startRunThread(af_Environment *env, af_VarSpace *vs, af_Code *code,
+                                                bool derive_tmp, bool derive_guardian, bool derive_lr, bool enable);
+AFUN_CORE_EXPORT void tartRunThread_(af_Environment *env, af_Code *code);
+
+#endif //AFUN_THREAD_H

+ 2 - 2
src/core/env.c

@@ -1001,10 +1001,10 @@ void enableEnvironment(af_Environment *env) {
 
 bool freeEnvironment(af_Environment *env) {
     bool res = true;
-    if (getEnviromentSonCount(env) != 0)
+    if (!env->is_derive && getEnviromentSonCount(env) != 0)
         return false;
 
-    if (env->status != core_creat)
+    if (!env->is_derive && env->status != core_creat)
         res = iterDestruct(10, env);
 
     freeAllActivity(env->activity);

+ 69 - 0
src/core/thread.c

@@ -0,0 +1,69 @@
+#include "__env.h"
+#include "__run.h"
+#include "core_init.h"
+#include "thread.h"
+
+struct EnvCode {
+    af_Environment *env;
+    af_Code *code;
+};
+
+static void *runThread(void *ec);
+
+/**
+ * 启动一个次线程运行代码
+ * @param env 父线程env
+ * @param vs 压入的变量空间
+ * @param code 执行的代码
+ */
+af_Environment *startRunThread(af_Environment *env, af_VarSpace *vs, af_Code *code,
+                               bool derive_tmp, bool derive_guardian, bool derive_lr, bool enable) {
+    af_Environment *base = env->base;
+    af_Environment *new = deriveEnvironment(derive_tmp, derive_guardian, derive_lr, enable, base);
+
+    if (vs == NULL)
+        vs = makeVarSpace(getGlobal(env), 3, 3, 3, env);
+
+    af_VarSpaceListNode *vsl = makeVarSpaceList(vs);
+    vsl->next = new->activity->run_varlist;
+    new->activity->run_varlist = vsl;
+    new->activity->count_run_varlist++;
+    if (!enable)  // 如果未Enable, 则暂时不启动线程
+        return new;
+
+    struct EnvCode *ec = calloc(1, sizeof(struct EnvCode));
+    ec->env = new;
+    ec->code = code;
+
+    pthread_t id;
+    pthread_create(&id, NULL, runThread, ec);
+    pthread_detach(id);
+    return new;
+}
+
+
+void tartRunThread_(af_Environment *env, af_Code *code) {
+    struct EnvCode *ec = calloc(1, sizeof(struct EnvCode));
+    ec->env = env;
+    ec->code = code;
+
+    pthread_t id;
+    pthread_create(&id, NULL, runThread, ec);
+    pthread_detach(id);
+}
+
+
+static void *runThread(void *ec) {
+    af_Environment *env = ((struct EnvCode *)ec)->env;
+    af_Code *code = ((struct EnvCode *)ec)->code;
+    free(ec);
+
+    writeInfoLog(aFunCoreLogger, "Thread start");
+    iterCode(code, 0, env);
+
+    writeInfoLog(aFunCoreLogger, "Thread free");
+    freeEnvironment(env);
+
+    writeInfoLog(aFunCoreLogger, "Thread end");
+    return NULL;
+}

+ 3 - 3
src/tool/log.c

@@ -266,13 +266,13 @@ static void writeLogToFactory_(LogLevel level, char *id, pid_t tid, char *ti, ti
  * @param info 日志内容
  */
 static void writeLogToConsole_(LogLevel level, char *id, pid_t tid, char *ti, time_t t, char *file, int line, char *func, char *info) {
-#define FORMAT_SHORT "\r* %s(%s:%d) : %s \n"  // 显示到终端, 添加\r回车符确保顶行显示
+#define FORMAT_SHORT "\r* %s[%d](%s:%d) : %s \n"  // 显示到终端, 添加\r回车符确保顶行显示
 #define STD_BUF_SIZE (STR_LEN(info) + 1024)
     if (level < log_warning) {
-        printf_stdout(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], file, line, info);
+        printf_stdout(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], tid, file, line, info);
         fflush(stdout);
     } else {
-        printf_stderr(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], file, line, info);
+        printf_stderr(STD_BUF_SIZE, FORMAT_SHORT, LogLevelNameLong[level], tid, file, line, info);
         fflush(stderr);
     }
 #undef FORMAT_SHORT

+ 10 - 0
test/src/run_code.c

@@ -1228,6 +1228,16 @@ INIT_ERROR:
         printf("popGuardian: %d\n\n", re);
     }
 
+    {
+        printf("TAG V:\n");
+        af_Code *bt1 = makeElementCode("object", 0, 1, "Taga.aun");
+
+        startRunThread(env, NULL, bt1, true, true, true, true);
+        runCodeFromMemory(bt1, 0, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
     /* 错误用例 */
 
     {  // 中缀调用测试