summaryrefslogtreecommitdiffstatsabout
path: root/SylixOS
diff options
context:
space:
mode:
authorHanhui <hanhui@acoinfo.com>2020-12-28 09:01:42 (GMT)
committer Hanhui <hanhui@acoinfo.com>2020-12-28 09:01:42 (GMT)
commit1b2107a60452b50ee6c96ec98d6a3aa74f8523c4 (patch)
treed89ee0c1cb1fd61c6cf858c44d1e3ece92505346 /SylixOS
parent8a571ac98ee9e71a43f3fed665eacf366c9b60dc (diff)
downloadlibsylixos-1b2107a60452b50ee6c96ec98d6a3aa74f8523c4.zip
libsylixos-1b2107a60452b50ee6c96ec98d6a3aa74f8523c4.tar.gz
libsylixos-1b2107a60452b50ee6c96ec98d6a3aa74f8523c4.tar.bz2
Add vutex and fixed thread once waiting initialize function error.
Diffstat (limited to 'SylixOS')
-rw-r--r--SylixOS/CHANGELOG3
-rw-r--r--SylixOS/api/Lw_Api_Kernel.h10
-rw-r--r--SylixOS/debug/dtrace/dtrace.c3
-rw-r--r--SylixOS/fs/tsync/tsync.c4
-rw-r--r--SylixOS/kernel/core/_ThreadInit.c26
-rw-r--r--SylixOS/kernel/core/_TimeTick.c5
-rw-r--r--SylixOS/kernel/include/k_class.h31
-rw-r--r--SylixOS/kernel/include/k_internal.h14
-rw-r--r--SylixOS/kernel/include/k_kernel.h3
-rw-r--r--SylixOS/kernel/include/k_option.h7
-rw-r--r--SylixOS/kernel/include/k_ptype.h2
-rw-r--r--SylixOS/kernel/include/k_typemacro.h4
-rw-r--r--SylixOS/kernel/interface/ThreadDelete.c4
-rw-r--r--SylixOS/kernel/interface/ThreadRestart.c4
-rw-r--r--SylixOS/kernel/interface/ThreadWakeup.c5
-rw-r--r--SylixOS/kernel/show/ThreadShow.c6
-rw-r--r--SylixOS/kernel/threadext/ThreadOnce.c209
-rw-r--r--SylixOS/kernel/threadext/threadext.h4
-rw-r--r--SylixOS/kernel/vutex/vutex.c202
-rw-r--r--SylixOS/kernel/vutex/vutex.h39
-rw-r--r--SylixOS/kernel/vutex/vutexLib.c170
-rw-r--r--SylixOS/kernel/vutex/vutexLib.h35
-rw-r--r--SylixOS/posix/include/px_pthread.h4
-rw-r--r--SylixOS/posix/pthread/pthread_key.c4
-rw-r--r--SylixOS/system/ptimer/ptimer.c4
-rw-r--r--SylixOS/system/signal/signalLib.c5
26 files changed, 738 insertions, 69 deletions
diff --git a/SylixOS/CHANGELOG b/SylixOS/CHANGELOG
index 15804b7..3ef942f 100644
--- a/SylixOS/CHANGELOG
+++ b/SylixOS/CHANGELOG
@@ -4,6 +4,9 @@ HISTORY
++ New features:
+ 2020-12-26: han.hui
+ 加入 Vutex 支持, 类似 Linux Futex.
+
2020-12-23: han.hui
加入 RFC6528 安全标准支持.
diff --git a/SylixOS/api/Lw_Api_Kernel.h b/SylixOS/api/Lw_Api_Kernel.h
index 71d8522..c0e0a4d 100644
--- a/SylixOS/api/Lw_Api_Kernel.h
+++ b/SylixOS/api/Lw_Api_Kernel.h
@@ -417,6 +417,16 @@
#define Lw_Event_GetName API_EventSetGetName
/*********************************************************************************************************
+ VUTEX
+*********************************************************************************************************/
+
+#define Lw_Vutex_Pend API_VutexPend
+#define Lw_Vutex_Wait API_VutexPend
+
+#define Lw_Vutex_Post API_VutexPost
+#define Lw_Vutex_Wake API_VutexPost
+
+/*********************************************************************************************************
TIME
*********************************************************************************************************/
diff --git a/SylixOS/debug/dtrace/dtrace.c b/SylixOS/debug/dtrace/dtrace.c
index fdfd533..a85f61b 100644
--- a/SylixOS/debug/dtrace/dtrace.c
+++ b/SylixOS/debug/dtrace/dtrace.c
@@ -1235,6 +1235,9 @@ ULONG API_DtraceThreadExtraInfo (PVOID pvDtrace, LW_OBJECT_HANDLE ulThread,
} else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_MSGQUEUE) { /* 等待消息队列 */
pcPendType = "MSGQ";
+ } else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_VUTEX) { /* 等待变量条件 */
+ pcPendType = "VUTEX";
+
} else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_JOIN) { /* 等待其他线程 */
pcPendType = "JOIN";
diff --git a/SylixOS/fs/tsync/tsync.c b/SylixOS/fs/tsync/tsync.c
index f0d753c..cbcb7e6 100644
--- a/SylixOS/fs/tsync/tsync.c
+++ b/SylixOS/fs/tsync/tsync.c
@@ -38,7 +38,7 @@ typedef LW_TSYNC_NODE *PLW_TSYNC_NODE;
全局变量
*********************************************************************************************************/
static PLW_LIST_LINE _G_plineTSyncHeader = LW_NULL; /* 链表头 */
-static BOOL _G_bTSyncOnce = LW_FALSE;
+static INT _G_iTSyncOnce = 0;
/*********************************************************************************************************
背景线程属性
*********************************************************************************************************/
@@ -114,7 +114,7 @@ INT API_TSyncAdd (VOIDFUNCPTR pfuncSync, PVOID pvArg)
return (PX_ERROR);
}
- API_ThreadOnce(&_G_bTSyncOnce, __tsyncInit); /* 创建 t_sync 任务 */
+ API_ThreadOnce(&_G_iTSyncOnce, __tsyncInit); /* 创建 t_sync 任务 */
ptsync = (PLW_TSYNC_NODE)__SHEAP_ALLOC(sizeof(LW_TSYNC_NODE));
if (!ptsync) {
diff --git a/SylixOS/kernel/core/_ThreadInit.c b/SylixOS/kernel/core/_ThreadInit.c
index 1106213..46cc514 100644
--- a/SylixOS/kernel/core/_ThreadInit.c
+++ b/SylixOS/kernel/core/_ThreadInit.c
@@ -50,6 +50,7 @@
修正不合理的函数命名.
2014.05.13 加入对进程内线程链表的支持.
2014.07.26 加入对 GDB 变量的初始化.
+2020.12.27 使用新的 ONCE 回收算法.
*********************************************************************************************************/
#define __SYLIXOS_STDIO
#define __SYLIXOS_KERNEL
@@ -285,6 +286,8 @@ VOID _TCBBuild (UINT8 ucPriority,
ptcb->TCB_uiStatusChangeReq = 0;
ptcb->TCB_ulStopNesting = 0ul;
+ _VutexInitCtx(ptcb); /* VUTEX 初始化 */
+
#if (LW_CFG_DEVICE_EN > 0) /* 设备管理 */
ptcb->TCB_pvIoEnv = LW_NULL; /* 默认使用全局 io 环境 */
@@ -421,9 +424,9 @@ ULONG _TCBBuildExt (PLW_CLASS_TCB ptcb)
#if LW_CFG_THREAD_EXT_EN > 0
REGISTER __PLW_THREAD_EXT ptex = &ptcb->TCB_texExt;
- ptex->TEX_pbOnce = LW_NULL;
- ptex->TEX_ulMutex = 0ul; /* 暂时不需要内部互斥量 */
- ptex->TEX_pmonoCurHeader = LW_NULL;
+ ptex->TEX_ulMutex = 0ul; /* 暂时不需要内部互斥量 */
+ ptex->TEX_pmonoOnceHeader = LW_NULL;
+ ptex->TEX_pmonoCurHeader = LW_NULL;
#endif /* LW_CFG_THREAD_EXT_EN > 0 */
return (ERROR_NONE);
@@ -439,12 +442,21 @@ ULONG _TCBBuildExt (PLW_CLASS_TCB ptcb)
VOID _TCBDestroyExt (PLW_CLASS_TCB ptcb)
{
#if LW_CFG_THREAD_EXT_EN > 0
- REGISTER __PLW_THREAD_EXT ptex = &ptcb->TCB_texExt;
+ REGISTER __PLW_THREAD_EXT ptex = &ptcb->TCB_texExt;
+ REGISTER __PLW_CLEANUP_ONCE pcur;
+ atomic_t *patomic;
- if (ptex->TEX_pbOnce) {
- *(ptex->TEX_pbOnce) = LW_FALSE; /* 未完成的 once 操作 */
- ptex->TEX_pbOnce = LW_NULL;
+ while (ptex->TEX_pmonoOnceHeader) {
+ pcur = (__PLW_CLEANUP_ONCE)(ptex->TEX_pmonoOnceHeader); /* 第一个元素 */
+ _list_mono_next(&ptex->TEX_pmonoOnceHeader);
+
+ patomic = (atomic_t *)pcur->CUO_piOnce;
+ __LW_ATOMIC_SET(0, patomic); /* 未完成的 once 操作 */
+ API_VutexPost(pcur->CUO_piOnce,
+ __ARCH_INT_MAX, LW_OPTION_VUTEX_LOCAL); /* 唤醒等待完成的任务 */
+ __KHEAP_FREE(pcur); /* 释放 */
}
+
if (ptex->TEX_ulMutex) { /* 是否需要删除互斥量 */
API_SemaphoreMDelete(&ptex->TEX_ulMutex);
}
diff --git a/SylixOS/kernel/core/_TimeTick.c b/SylixOS/kernel/core/_TimeTick.c
index 344ac91..1cc5d93 100644
--- a/SylixOS/kernel/core/_TimeTick.c
+++ b/SylixOS/kernel/core/_TimeTick.c
@@ -108,8 +108,11 @@ VOID _ThreadTick (VOID)
#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
if (ptcb->TCB_pesnPtr) {
_EventSetUnQueue(ptcb->TCB_pesnPtr);
- }
+ } else
#endif /* (LW_CFG_EVENTSET_EN > 0) && */
+ if (__VUTEX_IS_WAITING(ptcb)) { /* 等待变量条件 */
+ _VutexUnQueue(ptcb);
+ }
}
} else {
ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 没有等待事件 */
diff --git a/SylixOS/kernel/include/k_class.h b/SylixOS/kernel/include/k_class.h
index 64b633e..7e1e4ea 100644
--- a/SylixOS/kernel/include/k_class.h
+++ b/SylixOS/kernel/include/k_class.h
@@ -399,8 +399,14 @@ typedef struct {
typedef __LW_CLEANUP_ROUTINE *__PLW_CLEANUP_ROUTINE;
typedef struct {
- BOOL *TEX_pbOnce; /* 正在执行的 once 操作 */
+ LW_LIST_MONO CUO_monoNext; /* 单链表下一个节点 */
+ INT *CUO_piOnce; /* once 变量 */
+} __LW_CLEANUP_ONCE;
+typedef __LW_CLEANUP_ONCE *__PLW_CLEANUP_ONCE;
+
+typedef struct {
LW_OBJECT_HANDLE TEX_ulMutex; /* 互斥量 */
+ PLW_LIST_MONO TEX_pmonoOnceHeader; /* 正在执行的 once 操作 */
PLW_LIST_MONO TEX_pmonoCurHeader; /* cleanup node header */
} __LW_THREAD_EXT;
typedef __LW_THREAD_EXT *__PLW_THREAD_EXT;
@@ -454,6 +460,19 @@ typedef LW_SHELL_CONTEXT *PLW_SHELL_CONTEXT;
#endif /* LW_CFG_SHELL_EN > 0 */
/*********************************************************************************************************
+ VUTEX 上下文
+*********************************************************************************************************/
+
+typedef struct {
+ LW_LIST_LINE VUTEX_lineVutex; /* 等待链 */
+ INT VUTEX_iFlags; /* 等待 flags */
+ INT32 VUTEX_iVutexExpect; /* 期望的数值 */
+ UINT32 VUTEX_uiVutexHash; /* 等待变量 HASH index */
+ phys_addr_t VUTEX_phyaddrVutex; /* 等待的变量 */
+} LW_VUTEX_CONTEXT;
+typedef LW_VUTEX_CONTEXT *PLW_VUTEX_CONTEXT;
+
+/*********************************************************************************************************
线程控制块
注意: 浮点运算器上下文指针是否有效, 由 BSP FPU 相关实现决定,
@@ -636,6 +655,16 @@ typedef struct __lw_tcb {
PLW_LIST_LINE TCB_plinePrivateVars; /* 全局变量私有化线表 */
#endif
+/*********************************************************************************************************
+ VUTEX
+*********************************************************************************************************/
+
+ LW_VUTEX_CONTEXT TCB_vutex; /* VUTEX 上下文 */
+
+/*********************************************************************************************************
+ NAME
+*********************************************************************************************************/
+
CHAR TCB_cThreadName[LW_CFG_OBJECT_NAME_SIZE]; /* 线程名 */
/*********************************************************************************************************
diff --git a/SylixOS/kernel/include/k_internal.h b/SylixOS/kernel/include/k_internal.h
index 1bfdbed..15cdef5 100644
--- a/SylixOS/kernel/include/k_internal.h
+++ b/SylixOS/kernel/include/k_internal.h
@@ -394,6 +394,20 @@ VOID _MsgQueueMsgLen(PLW_CLASS_MSGQUEUE pmsgqueue, size_t *pstMsgLen
#endif /* (LW_CFG_MSGQUEUE_EN > 0) */
/* (LW_CFG_MAX_MSGQUEUES > 0) */
/*********************************************************************************************************
+ VUTEX
+*********************************************************************************************************/
+
+VOID _VutexInitCtx(PLW_CLASS_TCB ptcb);
+VOID _VutexUnQueue(PLW_CLASS_TCB ptcb);
+
+/*********************************************************************************************************
+ VUTEX 等待判断
+*********************************************************************************************************/
+
+#define __VUTEX_IS_GLOBAL(ptcb) (ptcb->TCB_vutex.VUTEX_iFlags & LW_OPTION_VUTEX_GLOBAL)
+#define __VUTEX_IS_WAITING(ptcb) (ptcb->TCB_vutex.VUTEX_phyaddrVutex != LW_PHY_ADDR_INVALID)
+
+/*********************************************************************************************************
构建句柄
*********************************************************************************************************/
diff --git a/SylixOS/kernel/include/k_kernel.h b/SylixOS/kernel/include/k_kernel.h
index e626b48..cfb9362 100644
--- a/SylixOS/kernel/include/k_kernel.h
+++ b/SylixOS/kernel/include/k_kernel.h
@@ -53,7 +53,7 @@
#define __SYLIXOS_MAJOR_VER 2
#define __SYLIXOS_MINOR_VER 1
-#define __SYLIXOS_PATCH_VER 1
+#define __SYLIXOS_PATCH_VER 2
#define __SYLIXOS_PATCH_PAD 0
/*********************************************************************************************************
@@ -292,6 +292,7 @@ __attribute__((weak)) char __sylixos_version[] = __SYLIXOS_VERSTR;
内部 API 函数声明
*********************************************************************************************************/
#include "../SylixOS/kernel/include/k_api.h"
+#include "../SylixOS/kernel/vutex/vutex.h"
#include "../SylixOS/kernel/threadext/threadext.h"
/*********************************************************************************************************
内核事件监控器
diff --git a/SylixOS/kernel/include/k_option.h b/SylixOS/kernel/include/k_option.h
index d24c1d7..151e904 100644
--- a/SylixOS/kernel/include/k_option.h
+++ b/SylixOS/kernel/include/k_option.h
@@ -266,6 +266,13 @@
#define LW_OPTION_EVENT_ALL (0xffffffff) /* 事件集的所有事件位 */
/*********************************************************************************************************
+ VUTEX FLAG
+*********************************************************************************************************/
+
+#define LW_OPTION_VUTEX_LOCAL 0x00000000 /* 进程内虚拟地址变量等待 */
+#define LW_OPTION_VUTEX_GLOBAL 0x80000000 /* 全局物理地址变量等待 */
+
+/*********************************************************************************************************
SCHEDLER
*********************************************************************************************************/
diff --git a/SylixOS/kernel/include/k_ptype.h b/SylixOS/kernel/include/k_ptype.h
index da784ed..3785e43 100644
--- a/SylixOS/kernel/include/k_ptype.h
+++ b/SylixOS/kernel/include/k_ptype.h
@@ -180,6 +180,8 @@ typedef ULONG phys_addr_t;
#endif
#endif
+#define LW_PHY_ADDR_INVALID ((phys_addr_t)-1)
+
/*********************************************************************************************************
BSD SOCKET basic type
*********************************************************************************************************/
diff --git a/SylixOS/kernel/include/k_typemacro.h b/SylixOS/kernel/include/k_typemacro.h
index 6c34751..c249ee0 100644
--- a/SylixOS/kernel/include/k_typemacro.h
+++ b/SylixOS/kernel/include/k_typemacro.h
@@ -69,11 +69,13 @@
#define LW_THREAD_STATUS_EVENTSET 0x0008 /* 等待事件标志组 */
#define LW_THREAD_STATUS_SIGNAL 0x0010 /* 等待信号 */
#define LW_THREAD_STATUS_JOIN 0x0020 /* 等待另外的线程 (信号不唤醒) */
+#define LW_THREAD_STATUS_VUTEX 0x8000 /* 等待变量条件 */
#define LW_THREAD_STATUS_PEND_ANY (LW_THREAD_STATUS_SEM | \
LW_THREAD_STATUS_MSGQUEUE | \
LW_THREAD_STATUS_EVENTSET | \
- LW_THREAD_STATUS_SIGNAL)
+ LW_THREAD_STATUS_SIGNAL | \
+ LW_THREAD_STATUS_VUTEX)
/*********************************************************************************************************
THREAD STATUS INTERNAL! (初始化的线程, 还没有得到执行)
diff --git a/SylixOS/kernel/interface/ThreadDelete.c b/SylixOS/kernel/interface/ThreadDelete.c
index d95554d..ceb4fd4 100644
--- a/SylixOS/kernel/interface/ThreadDelete.c
+++ b/SylixOS/kernel/interface/ThreadDelete.c
@@ -132,6 +132,10 @@ ULONG __threadDelete (PLW_CLASS_TCB ptcbDel, BOOL bIsInSafe,
}
#endif
+ if (__VUTEX_IS_WAITING(ptcbDel)) { /* 等待变量条件 */
+ _VutexUnQueue(ptcbDel); /* 解变量等待 */
+ }
+
#if LW_CFG_SMP_EN > 0
if (ptcbDel->TCB_ptcbWaitStatus ||
ptcbDel->TCB_plineStatusReqHeader) { /* 正在请求其他线程改变状态 */
diff --git a/SylixOS/kernel/interface/ThreadRestart.c b/SylixOS/kernel/interface/ThreadRestart.c
index 6228a01..82e30c5 100644
--- a/SylixOS/kernel/interface/ThreadRestart.c
+++ b/SylixOS/kernel/interface/ThreadRestart.c
@@ -128,6 +128,10 @@ static ULONG __threadRestart (PLW_CLASS_TCB ptcb,
}
#endif
+ if (__VUTEX_IS_WAITING(ptcb)) { /* 等待变量条件 */
+ _VutexUnQueue(ptcb); /* 解变量等待 */
+ }
+
#if LW_CFG_SMP_EN > 0
if (ptcb->TCB_ptcbWaitStatus ||
ptcb->TCB_plineStatusReqHeader) { /* 正在请求其他线程改变状态 */
diff --git a/SylixOS/kernel/interface/ThreadWakeup.c b/SylixOS/kernel/interface/ThreadWakeup.c
index f78b00a..8e27066 100644
--- a/SylixOS/kernel/interface/ThreadWakeup.c
+++ b/SylixOS/kernel/interface/ThreadWakeup.c
@@ -107,8 +107,11 @@ ULONG API_ThreadWakeupEx (LW_OBJECT_HANDLE ulId, BOOL bWithInfPend)
#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
if (ptcb->TCB_pesnPtr) {
_EventSetUnQueue(ptcb->TCB_pesnPtr);
- }
+ } else
#endif /* (LW_CFG_EVENTSET_EN > 0) && */
+ if (__VUTEX_IS_WAITING(ptcb)) { /* 等待变量条件 */
+ _VutexUnQueue(ptcb);
+ }
}
}
diff --git a/SylixOS/kernel/show/ThreadShow.c b/SylixOS/kernel/show/ThreadShow.c
index d9143bf..6a5456f 100644
--- a/SylixOS/kernel/show/ThreadShow.c
+++ b/SylixOS/kernel/show/ThreadShow.c
@@ -120,6 +120,9 @@ VOID API_ThreadShowEx (pid_t pid)
} else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_MSGQUEUE) { /* 等待消息队列 */
pcPendType = "MSGQ";
+ } else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_VUTEX) { /* 等待变量条件 */
+ pcPendType = "VUTEX";
+
} else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_JOIN) { /* 等待其他线程 */
pcPendType = "JOIN";
@@ -329,6 +332,9 @@ VOID API_ThreadPendShowEx (pid_t pid)
} else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_MSGQUEUE) { /* 等待消息队列 */
pcPendType = "MSGQ";
+ } else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_VUTEX) { /* 等待变量条件 */
+ pcPendType = "VUTEX";
+
} else if (tcbdesc.TCBD_usStatus & LW_THREAD_STATUS_JOIN) { /* 等待其他线程 */
pcPendType = "JOIN";
diff --git a/SylixOS/kernel/threadext/ThreadOnce.c b/SylixOS/kernel/threadext/ThreadOnce.c
index 3a1f3d7..a48fb59 100644
--- a/SylixOS/kernel/threadext/ThreadOnce.c
+++ b/SylixOS/kernel/threadext/ThreadOnce.c
@@ -24,53 +24,147 @@
#define __SYLIXOS_KERNEL
#include "../SylixOS/kernel/include/k_kernel.h"
/*********************************************************************************************************
+ STATUS
+*********************************************************************************************************/
+#define __THREAD_ONCE_STATUS_NONE 0
+#define __THREAD_ONCE_STATUS_INIT 1
+#define __THREAD_ONCE_STATUS_DOWN 2
+/*********************************************************************************************************
+** 函数名称: __threadOnceCleanPush
+** 功能描述: 安装一个正在执行的初始化操作.
+** 输 入 : piOnce once 变量.
+** 输 出 : TRUE or FALSE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+#if LW_CFG_THREAD_EXT_EN > 0
+
+static BOOL __threadOnceCleanPush (INT *piOnce)
+{
+ INTREG iregInterLevel;
+ PLW_CLASS_TCB ptcbCur;
+ __PLW_CLEANUP_ONCE pclean;
+ __PLW_THREAD_EXT ptex;
+
+ pclean = (__PLW_CLEANUP_ONCE)__KHEAP_ALLOC(sizeof(__LW_CLEANUP_ONCE));
+ if (pclean) {
+ pclean->CUO_piOnce = piOnce;
+ } else {
+ _DebugHandle(__ERRORMESSAGE_LEVEL, "Once buffer low memory.\r\n");
+ return (LW_FALSE);
+ }
+
+ iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */
+
+ LW_TCB_GET_CUR(ptcbCur);
+ ptex = &ptcbCur->TCB_texExt;
+
+ _LIST_MONO_LINK(&pclean->CUO_monoNext, ptex->TEX_pmonoOnceHeader);
+ ptex->TEX_pmonoOnceHeader = &pclean->CUO_monoNext;
+
+ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */
+
+ return (LW_TRUE);
+}
+/*********************************************************************************************************
+** 函数名称: __threadOnceCleanPop
+** 功能描述: 线程安全的仅执行一边指定函数.
+** 输 入 : NONE
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __threadOnceCleanPop (VOID)
+{
+ INTREG iregInterLevel;
+ PLW_CLASS_TCB ptcbCur;
+ __PLW_CLEANUP_ONCE pclean;
+ __PLW_THREAD_EXT ptex;
+
+ iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */
+
+ LW_TCB_GET_CUR(ptcbCur);
+ ptex = &ptcbCur->TCB_texExt;
+
+ pclean = (__PLW_CLEANUP_ONCE)ptex->TEX_pmonoOnceHeader;
+ if (pclean) {
+ _list_mono_next(&ptex->TEX_pmonoOnceHeader);
+ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */
+ __KHEAP_FREE(pclean);
+
+ } else {
+ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */
+ }
+}
+/*********************************************************************************************************
** 函数名称: API_ThreadOnce
** 功能描述: 线程安全的仅执行一边指定函数.
-** 输 入 : pbOnce once 相关 BOOL 全局变量, 必须初始化为 LW_FALSE.
+** 输 入 : piOnce 必须初始化为 0.
** pfuncRoutine 需要执行的函数.
** 输 出 : ERROR_NONE
** 全局变量:
** 调用模块:
API 函数
*********************************************************************************************************/
-#if LW_CFG_THREAD_EXT_EN > 0
-
LW_API
-INT API_ThreadOnce (BOOL *pbOnce, VOIDFUNCPTR pfuncRoutine)
+INT API_ThreadOnce (INT *piOnce, VOIDFUNCPTR pfuncRoutine)
{
- INTREG iregInterLevel;
- REGISTER INT iOk = LW_FALSE;
- PLW_CLASS_TCB ptcbCur;
-
- if (!pbOnce) {
+ BOOL bPush;
+ INT iValue;
+ atomic_t *patomic;
+
+ if (!piOnce && !pfuncRoutine) {
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
-
- __LW_ATOMIC_LOCK(iregInterLevel); /* 锁定 */
- LW_TCB_GET_CUR(ptcbCur);
- ptcbCur->TCB_texExt.TEX_pbOnce = pbOnce;
- if (*pbOnce == LW_FALSE) { /* 互斥的判断是否执行 */
- *pbOnce = LW_TRUE;
- iOk = LW_TRUE; /* 设置独立标志 */
- }
- __LW_ATOMIC_UNLOCK(iregInterLevel); /* 解锁 */
-
- if (pfuncRoutine && iOk) {
- LW_SOFUNC_PREPARE(pfuncRoutine);
- pfuncRoutine(); /* 执行 */
+ patomic = (atomic_t *)piOnce;
+
+ do {
+ iValue = __LW_ATOMIC_GET(patomic);
+ switch (iValue) {
+
+ case __THREAD_ONCE_STATUS_DOWN: /* 已经执行过了 */
+ return (ERROR_NONE);
+
+ case __THREAD_ONCE_STATUS_INIT: /* 正在被其他任务执行 */
+ API_VutexPend(piOnce,
+ __THREAD_ONCE_STATUS_DOWN,
+ LW_OPTION_VUTEX_LOCAL,
+ LW_OPTION_WAIT_INFINITE); /* 等待初始化执行完毕 */
+ continue;
+
+ case __THREAD_ONCE_STATUS_NONE: /* 可以尝试初始化 */
+ iValue = __LW_ATOMIC_CAS(patomic,
+ __THREAD_ONCE_STATUS_NONE,
+ __THREAD_ONCE_STATUS_DOWN);
+ break;
+
+ default: /* 状态错误 */
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+ } while (iValue != __THREAD_ONCE_STATUS_NONE); /* CAS 失败 */
+
+ bPush = __threadOnceCleanPush(piOnce); /* 添加中途退出回收点 */
+
+ LW_SOFUNC_PREPARE(pfuncRoutine);
+ pfuncRoutine(); /* 执行 */
+
+ if (bPush) {
+ __threadOnceCleanPop(); /* 删除回收点 */
}
- ptcbCur->TCB_texExt.TEX_pbOnce = LW_NULL; /* 结束 once 过程 */
- KN_SMP_WMB();
+ __LW_ATOMIC_SET(__THREAD_ONCE_STATUS_DOWN, patomic); /* 执行完毕 */
+
+ API_VutexPost(piOnce, __ARCH_INT_MAX, LW_OPTION_VUTEX_LOCAL); /* 唤醒等待的任务 */
return (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: API_ThreadOnce2
** 功能描述: 线程安全的仅执行一边指定函数.
-** 输 入 : pbOnce once 相关 BOOL 全局变量, 必须初始化为 LW_FALSE.
+** 输 入 : piOnce 必须初始化为 0.
** pfuncRoutine 需要执行的函数.
** pvArg 执行参数
** 输 出 : ERROR_NONE
@@ -79,34 +173,57 @@ INT API_ThreadOnce (BOOL *pbOnce, VOIDFUNCPTR pfuncRoutine)
API 函数
*********************************************************************************************************/
LW_API
-INT API_ThreadOnce2 (BOOL *pbOnce, VOIDFUNCPTR pfuncRoutine, PVOID pvArg)
+INT API_ThreadOnce2 (INT *piOnce, VOIDFUNCPTR pfuncRoutine, PVOID pvArg)
{
- INTREG iregInterLevel;
- REGISTER INT iOk = LW_FALSE;
- PLW_CLASS_TCB ptcbCur;
-
- if (!pbOnce) {
+ BOOL bPush;
+ INT iValue;
+ atomic_t *patomic;
+
+ if (!piOnce && !pfuncRoutine) {
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
-
- __LW_ATOMIC_LOCK(iregInterLevel); /* 锁定 */
- LW_TCB_GET_CUR(ptcbCur);
- ptcbCur->TCB_texExt.TEX_pbOnce = pbOnce;
- if (*pbOnce == LW_FALSE) { /* 互斥的判断是否执行 */
- *pbOnce = LW_TRUE;
- iOk = LW_TRUE; /* 设置独立标志 */
- }
- __LW_ATOMIC_UNLOCK(iregInterLevel); /* 解锁 */
-
- if (pfuncRoutine && iOk) {
- LW_SOFUNC_PREPARE(pfuncRoutine);
- pfuncRoutine(pvArg); /* 执行 */
+ patomic = (atomic_t *)piOnce;
+
+ do {
+ iValue = __LW_ATOMIC_GET(patomic);
+ switch (iValue) {
+
+ case __THREAD_ONCE_STATUS_DOWN: /* 已经执行过了 */
+ return (ERROR_NONE);
+
+ case __THREAD_ONCE_STATUS_INIT: /* 正在被其他任务执行 */
+ API_VutexPend(piOnce,
+ __THREAD_ONCE_STATUS_DOWN,
+ LW_OPTION_VUTEX_LOCAL,
+ LW_OPTION_WAIT_INFINITE); /* 等待初始化执行完毕 */
+ continue;
+
+ case __THREAD_ONCE_STATUS_NONE: /* 可以尝试初始化 */
+ iValue = __LW_ATOMIC_CAS(patomic,
+ __THREAD_ONCE_STATUS_NONE,
+ __THREAD_ONCE_STATUS_DOWN);
+ break;
+
+ default: /* 状态错误 */
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+ } while (iValue != __THREAD_ONCE_STATUS_NONE); /* CAS 失败 */
+
+ bPush = __threadOnceCleanPush(piOnce); /* 添加中途退出回收点 */
+
+ LW_SOFUNC_PREPARE(pfuncRoutine);
+ pfuncRoutine(pvArg); /* 执行 */
+
+ if (bPush) {
+ __threadOnceCleanPop(); /* 删除回收点 */
}
- ptcbCur->TCB_texExt.TEX_pbOnce = LW_NULL; /* 结束 once 过程 */
- KN_SMP_WMB();
+ __LW_ATOMIC_SET(__THREAD_ONCE_STATUS_DOWN, patomic); /* 执行完毕 */
+
+ API_VutexPost(piOnce, __ARCH_INT_MAX, LW_OPTION_VUTEX_LOCAL); /* 唤醒等待的任务 */
return (ERROR_NONE);
}
diff --git a/SylixOS/kernel/threadext/threadext.h b/SylixOS/kernel/threadext/threadext.h
index 072ea62..f1bf37d 100644
--- a/SylixOS/kernel/threadext/threadext.h
+++ b/SylixOS/kernel/threadext/threadext.h
@@ -41,8 +41,8 @@
API
*********************************************************************************************************/
-LW_API INT API_ThreadOnce(BOOL *pbOnce, VOIDFUNCPTR pfuncRoutine);
-LW_API INT API_ThreadOnce2(BOOL *pbOnce, VOIDFUNCPTR pfuncRoutine, PVOID pvArg);
+LW_API INT API_ThreadOnce(INT *piOnce, VOIDFUNCPTR pfuncRoutine);
+LW_API INT API_ThreadOnce2(INT *piOnce, VOIDFUNCPTR pfuncRoutine, PVOID pvArg);
LW_API ULONG API_ThreadCleanupPush(VOIDFUNCPTR pfuncRoutine, PVOID pvArg);
LW_API ULONG API_ThreadCleanupPushEx(LW_OBJECT_HANDLE ulId, VOIDFUNCPTR pfuncRoutine, PVOID pvArg);
diff --git a/SylixOS/kernel/vutex/vutex.c b/SylixOS/kernel/vutex/vutex.c
new file mode 100644
index 0000000..b0e4104
--- /dev/null
+++ b/SylixOS/kernel/vutex/vutex.c
@@ -0,0 +1,202 @@
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: vutex.c
+**
+** 创 建 人: Han.Hui (韩辉)
+**
+** 文件创建日期: 2020 年 12 月 26 日
+**
+** 描 述: 等待变量锁.
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "SylixOS.h"
+#include "vutexLib.h"
+/*********************************************************************************************************
+** 函数名称: API_VutexPend
+** 功能描述: 等待一个变量到达某个值
+** 输 入 : piVar 等待的变量地址
+** iExpect 期望的数值
+** iFlags 操作选项
+** ulTimeout 等待时间
+** 输 出 : ERROR or OK
+** 全局变量:
+** 调用模块:
+ API 函数
+
+ (不得在中断中调用)
+*********************************************************************************************************/
+LW_API
+INT API_VutexPend (INT *piVar, INT iExpect, INT iFlags, ULONG ulTimeout)
+{
+ phys_addr_t phyaddr;
+ PLW_CLASS_TCB ptcbCur;
+ ULONG ulTimeSave; /* 系统事件记录 */
+ INT iSchedRet;
+
+ if (!piVar) {
+ _ErrorHandle(EFAULT);
+ return (PX_ERROR);
+ }
+
+ if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */
+ _ErrorHandle(ERROR_KERNEL_IN_ISR);
+ return (PX_ERROR);
+ }
+
+__wait_again:
+ if (*(volatile INT *)piVar == iExpect) {
+ return (ERROR_NONE);
+
+ } else if (ulTimeout == LW_OPTION_NOT_WAIT) { /* 不等待 */
+ _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT); /* 超时 */
+ return (PX_ERROR);
+ }
+
+ if (iFlags & LW_OPTION_VUTEX_GLOBAL) { /* 是否为全局地址 */
+#if LW_CFG_VMM_EN > 0
+ if (vmmVirtualToPhysical((addr_t)piVar, &phyaddr)) { /* 转换为物理地址 */
+ return (PX_ERROR);
+ }
+#else /* LW_CFG_VMM_EN > 0 */
+ phyaddr = (phys_addr_t)piVar;
+#endif /* LW_CFG_VMM_EN == 0 */
+ } else {
+ phyaddr = (phys_addr_t)piVar;
+ }
+
+ if (phyaddr == LW_PHY_ADDR_INVALID) { /* 地址无效 */
+ _ErrorHandle(EFAULT);
+ return (PX_ERROR);
+ }
+
+ __KERNEL_ENTER(); /* 进入内核 */
+ if (*(volatile INT *)piVar == iExpect) {
+ __KERNEL_EXIT();
+ return (ERROR_NONE);
+ }
+
+ LW_TCB_GET_CUR(ptcbCur);
+
+ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_VUTEX; /* 写状态位,开始等待 */
+ ptcbCur->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 清空等待时间 */
+
+ if (ulTimeout == LW_OPTION_WAIT_INFINITE) { /* 是否是无穷等待 */
+ ptcbCur->TCB_ulDelay = 0ul;
+ } else {
+ ptcbCur->TCB_ulDelay = ulTimeout; /* 设置超时时间 */
+ }
+ __KERNEL_TIME_GET_IGNIRQ(ulTimeSave, ULONG); /* 记录系统时间 */
+
+ _VutexWaitQueue(ptcbCur, phyaddr, iExpect, iFlags); /* 加入等待表 */
+
+ iSchedRet = __KERNEL_EXIT(); /* 退出内核 */
+ if (*(volatile INT *)piVar == iExpect) {
+ return (ERROR_NONE);
+ }
+
+ if (iSchedRet == LW_SIGNAL_EINTR) {
+ _ErrorHandle(EINTR); /* 被信号打断 */
+ return (PX_ERROR);
+
+ } else if (iSchedRet == LW_SIGNAL_RESTART) {
+ ulTimeout = _sigTimeoutRecalc(ulTimeSave, ulTimeout);
+
+ } else {
+ if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_OUT) { /* 被唤醒或超时了 */
+ _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT); /* 等待超时 */
+ return (PX_ERROR);
+
+ } else {
+ ulTimeout = _sigTimeoutRecalc(ulTimeSave, ulTimeout);
+ }
+ }
+
+ if (ulTimeout != LW_OPTION_NOT_WAIT) {
+ goto __wait_again; /* 重新等待 */
+ }
+
+ _ErrorHandle(ERROR_THREAD_WAIT_TIMEOUT); /* 等待超时 */
+ return (PX_ERROR);
+}
+/*********************************************************************************************************
+** 函数名称: API_VutexPost
+** 功能描述: 改变一个变量为某个值
+** 输 入 : piVar 变量地址
+** iValue 要设置的值
+** iFlags 操作选项
+** 输 出 : ERROR or OK
+** 全局变量:
+** 调用模块:
+ API 函数
+
+ (不得在中断中调用)
+*********************************************************************************************************/
+LW_API
+INT API_VutexPost (INT *piVar, INT iValue, INT iFlags)
+{
+ phys_addr_t phyaddr;
+ PLW_CLASS_TCB ptcbCur;
+
+ if (!piVar) {
+ _ErrorHandle(EFAULT);
+ return (PX_ERROR);
+ }
+
+ if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */
+ _ErrorHandle(ERROR_KERNEL_IN_ISR);
+ return (PX_ERROR);
+ }
+
+ if (*(volatile INT *)piVar == iValue) {
+ return (ERROR_NONE);
+ }
+
+ if (iFlags & LW_OPTION_VUTEX_GLOBAL) { /* 是否为全局地址 */
+#if LW_CFG_VMM_EN > 0
+ if (vmmVirtualToPhysical((addr_t)piVar, &phyaddr)) { /* 转换为物理地址 */
+ return (PX_ERROR);
+ }
+#else /* LW_CFG_VMM_EN > 0 */
+ phyaddr = (phys_addr_t)piVar;
+#endif /* LW_CFG_VMM_EN == 0 */
+ } else {
+ phyaddr = (phys_addr_t)piVar;
+ }
+
+ if (phyaddr == LW_PHY_ADDR_INVALID) { /* 地址无效 */
+ _ErrorHandle(EFAULT);
+ return (PX_ERROR);
+ }
+
+ __KERNEL_ENTER(); /* 进入内核 */
+ if (*(volatile INT *)piVar == iValue) {
+ __KERNEL_EXIT();
+ return (ERROR_NONE);
+ }
+
+ if (iValue != __ARCH_INT_MAX) { /* __ARCH_INT_MAX 仅唤醒 */
+ *piVar = iValue;
+ KN_SMP_WMB();
+ }
+
+ LW_TCB_GET_CUR(ptcbCur);
+
+ _VutexWakeQueue(ptcbCur, phyaddr, iValue, iFlags); /* 唤醒合适的任务 */
+
+ __KERNEL_EXIT(); /* 退出内核 */
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/kernel/vutex/vutex.h b/SylixOS/kernel/vutex/vutex.h
new file mode 100644
index 0000000..097509a
--- /dev/null
+++ b/SylixOS/kernel/vutex/vutex.h
@@ -0,0 +1,39 @@
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: vutex.h
+**
+** 创 建 人: Han.Hui (韩辉)
+**
+** 文件创建日期: 2020 年 12 月 26 日
+**
+** 描 述: 等待变量锁.
+*********************************************************************************************************/
+
+#ifndef __VUTEX_H
+#define __VUTEX_H
+
+/*********************************************************************************************************
+ API
+
+ 只有 iFlags 相同, 才表示同一变量,
+ 仅对进程内多任务生效, 可以使用 LW_OPTION_VUTEX_LOCAL, Vutex 工作速度快, 不进行地址映射转换.
+ 对整个系统生效, 可以使用 LW_OPTION_VUTEX_GLOBAL, Vutex 将保存对应的物理地址关系, 可跨进程等待.
+*********************************************************************************************************/
+
+LW_API INT API_VutexPend(INT *piVar, INT iExpect, INT iFlags, ULONG ulTimeout);
+LW_API INT API_VutexPost(INT *piVar, INT iValue, INT iFlags);
+
+#endif /* __VUTEX_H */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/kernel/vutex/vutexLib.c b/SylixOS/kernel/vutex/vutexLib.c
new file mode 100644
index 0000000..d90e510
--- /dev/null
+++ b/SylixOS/kernel/vutex/vutexLib.c
@@ -0,0 +1,170 @@
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: vutexLib.c
+**
+** 创 建 人: Han.Hui (韩辉)
+**
+** 文件创建日期: 2020 年 12 月 26 日
+**
+** 描 述: 等待变量锁内部实现.
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "SylixOS.h"
+/*********************************************************************************************************
+ 宏定义
+*********************************************************************************************************/
+#define LW_VUTEX_ALIGN_LOG 3
+#define LW_VUTEX_HASH_SIZE 1024
+#define LW_VUTEX_HASH_MASK 0x3ff
+#define LW_VUTEX_HASH_INDEX(a) (((a) >> LW_VUTEX_ALIGN_LOG) & LW_VUTEX_HASH_MASK)
+/*********************************************************************************************************
+ 全局变量
+*********************************************************************************************************/
+static LW_LIST_LINE_HEADER _k_plineVutexHashHeader[LW_VUTEX_HASH_SIZE];
+/*********************************************************************************************************
+** 函数名称: _VutexWaitQueue
+** 功能描述: 将当前任务加入等待队列
+** 输 入 : ptcbCur 当前任务
+** phyaddr 等待的物理地址
+** iExpect 期望的值
+** iFlags 操作选项
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+VOID _VutexWaitQueue (PLW_CLASS_TCB ptcbCur, phys_addr_t phyaddr, INT32 iExpect, INT iFlags)
+{
+ REGISTER PLW_CLASS_PCB ppcb;
+ LW_LIST_LINE_HEADER *pplineHeader;
+ PLW_VUTEX_CONTEXT pvutex = &ptcbCur->TCB_vutex;
+
+ pvutex->VUTEX_phyaddrVutex = phyaddr;
+ ppcb = _GetPcb(ptcbCur);
+ __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪队列中删除 */
+
+ pvutex->VUTEX_iFlags = iFlags;
+ pvutex->VUTEX_iVutexExpect = iExpect;
+ pvutex->VUTEX_uiVutexHash = LW_VUTEX_HASH_INDEX(phyaddr);
+ pplineHeader = &_k_plineVutexHashHeader[pvutex->VUTEX_uiVutexHash];
+ _List_Line_Add_Ahead(&pvutex->VUTEX_lineVutex, pplineHeader); /* 加入等待队列 */
+
+ if (ptcbCur->TCB_ulDelay) {
+ __ADD_TO_WAKEUP_LINE(ptcbCur); /* 加入等待扫描链 */
+ }
+}
+/*********************************************************************************************************
+** 函数名称: _VutexWaitQueue
+** 功能描述: 根据地址和期望数据唤醒目标任务
+** 输 入 : ptcbCur 当前任务
+** phyaddr 物理地址
+** iValue 写入的值
+** iFlags 操作选项
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+VOID _VutexWakeQueue (PLW_CLASS_TCB ptcbCur, phys_addr_t phyaddr, INT32 iValue, INT iFlags)
+{
+ UINT32 uiHash = LW_VUTEX_HASH_INDEX(phyaddr);
+ BOOL bMatch, bGlobal = iFlags & LW_OPTION_VUTEX_GLOBAL;
+ PLW_CLASS_TCB ptcb;
+ PLW_CLASS_PCB ppcb;
+ PLW_VUTEX_CONTEXT pvutex;
+ LW_LIST_LINE_HEADER *pplineHeader;
+ PLW_LIST_LINE plineTemp, plineNext;
+
+ pplineHeader = &_k_plineVutexHashHeader[uiHash];
+ plineTemp = *pplineHeader;
+
+ while (plineTemp) {
+ plineNext = _list_line_get_next(plineTemp);
+
+ pvutex = _LIST_ENTRY(plineTemp, LW_VUTEX_CONTEXT, VUTEX_lineVutex);
+ bMatch = LW_FALSE;
+
+ if (bGlobal && (pvutex->VUTEX_iFlags & LW_OPTION_VUTEX_GLOBAL)) {
+ if ((pvutex->VUTEX_phyaddrVutex == phyaddr) &&
+ (pvutex->VUTEX_iVutexExpect == iValue || iValue == __ARCH_INT_MAX)) {
+ ptcb = _LIST_ENTRY(pvutex, LW_CLASS_TCB, TCB_vutex);
+ bMatch = LW_TRUE; /* 全局匹配 */
+ }
+
+ } else if (!(pvutex->VUTEX_iFlags & LW_OPTION_VUTEX_GLOBAL)) {
+ if ((pvutex->VUTEX_phyaddrVutex == phyaddr) &&
+ (pvutex->VUTEX_iVutexExpect == iValue || iValue == __ARCH_INT_MAX)) {
+ ptcb = _LIST_ENTRY(pvutex, LW_CLASS_TCB, TCB_vutex);
+ if (ptcbCur->TCB_pvVProcessContext == ptcb->TCB_pvVProcessContext) {
+ bMatch = LW_TRUE; /* 进程内匹配 */
+ }
+ }
+ }
+
+ if (bMatch) {
+ _List_Line_Del(&pvutex->VUTEX_lineVutex, pplineHeader);
+ if (ptcb->TCB_usStatus & LW_THREAD_STATUS_DELAY) {
+ __DEL_FROM_WAKEUP_LINE(ptcb); /* 退出等待队列 */
+ ptcb->TCB_ulDelay = 0ul;
+ }
+
+ if (ptcb->TCB_ucWaitTimeout) {
+ ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 清除超时位 */
+ } else {
+ ptcb->TCB_usStatus = (UINT16)(ptcb->TCB_usStatus & ~LW_THREAD_STATUS_VUTEX);
+ if (__LW_THREAD_IS_READY(ptcb)) { /* 是否就绪 */
+ ptcb->TCB_ucSchedActivate = LW_SCHED_ACT_OTHER; /* 调度激活方式 */
+ ppcb = _GetPcb(ptcb);
+ __ADD_TO_READY_RING(ptcb, ppcb); /* 加入到相对优先级就绪环 */
+ }
+ }
+ }
+
+ plineTemp = plineNext;
+ }
+}
+/*********************************************************************************************************
+** 函数名称: _VutexInitCtx
+** 功能描述: 初始化任务控制块 vutex 上下文
+** 输 入 : ptcb 任务
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+VOID _VutexInitCtx (PLW_CLASS_TCB ptcb)
+{
+ PLW_VUTEX_CONTEXT pvutex = &ptcb->TCB_vutex;
+
+ pvutex->VUTEX_phyaddrVutex = LW_PHY_ADDR_INVALID;
+ _LIST_LINE_INIT_IN_CODE(pvutex->VUTEX_lineVutex);
+}
+/*********************************************************************************************************
+** 函数名称: _VutexUnQueue
+** 功能描述: 将目标任务退出等待队列
+** 输 入 : ptcb 目标任务
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+VOID _VutexUnQueue (PLW_CLASS_TCB ptcb)
+{
+ PLW_VUTEX_CONTEXT pvutex = &ptcb->TCB_vutex;
+ LW_LIST_LINE_HEADER *pplineHeader;
+
+ pplineHeader = &_k_plineVutexHashHeader[pvutex->VUTEX_uiVutexHash];
+ _List_Line_Del(&pvutex->VUTEX_lineVutex, pplineHeader);
+
+ pvutex->VUTEX_uiVutexHash = 0;
+ pvutex->VUTEX_phyaddrVutex = LW_PHY_ADDR_INVALID;
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/kernel/vutex/vutexLib.h b/SylixOS/kernel/vutex/vutexLib.h
new file mode 100644
index 0000000..9beca42
--- /dev/null
+++ b/SylixOS/kernel/vutex/vutexLib.h
@@ -0,0 +1,35 @@
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: vutexLib.h
+**
+** 创 建 人: Han.Hui (韩辉)
+**
+** 文件创建日期: 2020 年 12 月 26 日
+**
+** 描 述: 等待变量锁内部实现.
+*********************************************************************************************************/
+
+#ifndef __VUTEXLIB_H
+#define __VUTEXLIB_H
+
+/*********************************************************************************************************
+ 内部函数
+*********************************************************************************************************/
+
+VOID _VutexWaitQueue(PLW_CLASS_TCB ptcbCur, phys_addr_t phyaddr, INT32 iExpect, INT iFlags);
+VOID _VutexWakeQueue(PLW_CLASS_TCB ptcbCur, phys_addr_t phyaddr, INT32 iValue, INT iFlags);
+
+#endif /* __VUTEXLIB_H */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/posix/include/px_pthread.h b/SylixOS/posix/include/px_pthread.h
index c337df6..86637bd 100644
--- a/SylixOS/posix/include/px_pthread.h
+++ b/SylixOS/posix/include/px_pthread.h
@@ -46,9 +46,9 @@ extern "C" {
pthread once & cancel
*********************************************************************************************************/
-typedef BOOL pthread_once_t;
+typedef INT pthread_once_t;
-#define PTHREAD_ONCE_INIT LW_FALSE
+#define PTHREAD_ONCE_INIT 0
#ifndef PTHREAD_CANCEL_ASYNCHRONOUS
#define PTHREAD_CANCEL_ASYNCHRONOUS LW_THREAD_CANCEL_ASYNCHRONOUS
diff --git a/SylixOS/posix/pthread/pthread_key.c b/SylixOS/posix/pthread/pthread_key.c
index 2c602b5..adf7e26 100644
--- a/SylixOS/posix/pthread/pthread_key.c
+++ b/SylixOS/posix/pthread/pthread_key.c
@@ -65,7 +65,7 @@ static LW_LIST_RING_HEADER _G_pringKeyHeader; /* 所有
/*********************************************************************************************************
协程删除回调函数声明
*********************************************************************************************************/
-static BOOL _G_bKeyDelHookAdd = LW_FALSE;
+static INT _G_iKeyDelHookAdd = 0;
static VOID __pthreadDataDeleteByThread(LW_OBJECT_HANDLE ulId, PVOID pvRetVal, PLW_CLASS_TCB ptcbDel);
/*********************************************************************************************************
** 函数名称: __pthreadKeyOnce
@@ -336,7 +336,7 @@ int pthread_key_create (pthread_key_t *pkey, void (*fdestructor)(void *))
return (EINVAL);
}
- API_ThreadOnce(&_G_bKeyDelHookAdd, __pthreadKeyOnce); /* 安装线程删除回调 */
+ API_ThreadOnce(&_G_iKeyDelHookAdd, __pthreadKeyOnce); /* 安装线程删除回调 */
pkeyn = (__PX_KEY_NODE *)__SHEAP_ALLOC(sizeof(__PX_KEY_NODE)); /* 创建节点内存 */
if (pkeyn == LW_NULL) {
diff --git a/SylixOS/system/ptimer/ptimer.c b/SylixOS/system/ptimer/ptimer.c
index c66bce5..f7db9b2 100644
--- a/SylixOS/system/ptimer/ptimer.c
+++ b/SylixOS/system/ptimer/ptimer.c
@@ -105,7 +105,7 @@ INT timer_create_internal (clockid_t clockid, struct sigevent *sigeventT,
timer_t *ptimer, ULONG ulOption)
{
#if LW_CFG_PTIMER_AUTO_DEL_EN > 0
- static BOOL bIsInstallHook = LW_FALSE;
+ static INT iIsInstallHook = 0;
#endif /* LW_CFG_PTIMER_AUTO_DEL_EN */
LW_OBJECT_HANDLE ulTimer;
@@ -135,7 +135,7 @@ INT timer_create_internal (clockid_t clockid, struct sigevent *sigeventT,
}
#if LW_CFG_PTIMER_AUTO_DEL_EN > 0
- API_ThreadOnce(&bIsInstallHook, __ptimerHookInstall); /* 安装回调 */
+ API_ThreadOnce(&iIsInstallHook, __ptimerHookInstall); /* 安装回调 */
#endif /* LW_CFG_PTIMER_AUTO_DEL_EN */
__KERNEL_ENTER(); /* 进入内核 */
diff --git a/SylixOS/system/signal/signalLib.c b/SylixOS/system/signal/signalLib.c
index 96c56f0..336d1ea 100644
--- a/SylixOS/system/signal/signalLib.c
+++ b/SylixOS/system/signal/signalLib.c
@@ -446,8 +446,11 @@ static VOID __sigMakeReady (PLW_CLASS_TCB ptcb,
#if (LW_CFG_EVENTSET_EN > 0) && (LW_CFG_MAX_EVENTSETS > 0)
if (ptcb->TCB_pesnPtr) {
_EventSetUnQueue(ptcb->TCB_pesnPtr);
- }
+ } else
#endif /* (LW_CFG_EVENTSET_EN > 0) && */
+ if (__VUTEX_IS_WAITING(ptcb)) { /* 等待变量条件 */
+ _VutexUnQueue(ptcb);
+ }
}
} else {
ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 没有等待事件 */