From 3df1b47cff946a53fe0e79b263757792979c6282 Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Fri, 28 Jan 2022 10:31:30 +0800 Subject: [PATCH] =?UTF-8?q?=20=E5=90=8C=E6=AD=A5=E5=AE=98=E6=96=B9?= =?UTF-8?q?=E6=BA=90=E7=A0=81,=E5=AF=B9=E8=B0=83=E5=BA=A6,=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=A8=A1=E5=9D=97=E6=9C=89=E5=BE=88=E5=A4=A7=E7=9A=84?= =?UTF-8?q?=E8=B0=83=E6=95=B4=20=20=20=20=20=E7=99=BE=E5=9B=BE=E7=94=BB?= =?UTF-8?q?=E9=B8=BF=E8=92=99=20+=20=E7=99=BE=E6=96=87=E8=AF=B4=E5=86=85?= =?UTF-8?q?=E6=A0=B8=20+=20=E7=99=BE=E4=B8=87=E6=B3=A8=E6=BA=90=E7=A0=81?= =?UTF-8?q?=20=20=3D>=20=E6=8C=96=E9=80=8F=E9=B8=BF=E8=92=99=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E6=BA=90=E7=A0=81=20=20=20=20=20=E9=B8=BF=E8=92=99?= =?UTF-8?q?=E7=A0=94=E7=A9=B6=E7=AB=99=20|=20http://weharmonyos.com=20(?= =?UTF-8?q?=E5=9B=BD=E5=86=85)=20=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20|=20https://weharmony.github.io=20(=E5=9B=BD=E5=A4=96)=20=20?= =?UTF-8?q?=20=20=20oschina=20|=20https://my.oschina.net/weharmony=20=20?= =?UTF-8?q?=20=20=20=E5=8D=9A=E5=AE=A2=E5=9B=AD=20|=20https://www.cnblogs.?= =?UTF-8?q?com/weharmony/=20=20=20=20=20=E7=9F=A5=E4=B9=8E=20|=20https://w?= =?UTF-8?q?ww.zhihu.com/people/weharmonyos=20=20=20=20=20csdn=20|=20https:?= =?UTF-8?q?//blog.csdn.net/kuangyufei=20=20=20=20=2051cto=20|=20https://ha?= =?UTF-8?q?rmonyos.51cto.com/column/34=20=20=20=20=20=E6=8E=98=E9=87=91=20?= =?UTF-8?q?|=20https://juejin.cn/user/756888642000808=20=20=20=20=20?= =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=20|=20=E9=B8=BF=E8=92=99=E7=A0=94?= =?UTF-8?q?=E7=A9=B6=E7=AB=99=20(weharmonyos)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mksh/BUILD.gn | 3 +- apps/toybox/BUILD.gn | 3 +- arch/arm/arm/src/los_exc.c | 44 +- drivers/char/bch/BUILD.gn | 13 +- drivers/char/video/BUILD.gn | 5 +- fs/fat/BUILD.gn | 10 +- fs/jffs2/BUILD.gn | 31 +- fs/nfs/BUILD.gn | 7 +- fs/ramfs/BUILD.gn | 3 +- fs/romfs/BUILD.gn | 6 +- fs/vfs/BUILD.gn | 70 +- kernel/base/core/los_process.c | 229 ++- kernel/base/core/los_smp.c | 2 - kernel/base/core/los_swtmr.c | 1232 ++++++++--------- kernel/base/core/los_task.c | 581 +++----- kernel/base/include/los_percpu_pri.h | 45 +- kernel/base/include/los_process_pri.h | 98 +- kernel/base/include/los_sched_pri.h | 486 +++++-- kernel/base/include/los_sortlink_pri.h | 25 +- kernel/base/include/los_swtmr_pri.h | 10 +- kernel/base/include/los_task_pri.h | 243 +--- kernel/base/ipc/los_futex.c | 6 +- kernel/base/ipc/los_signal.c | 4 +- kernel/base/misc/task_shellcmd.c | 68 +- kernel/base/mp/los_mp.c | 2 +- kernel/base/mp/los_percpu.c | 25 +- kernel/base/mp/los_spinlock.c | 31 +- kernel/base/sched/sched_sq/los_sched.c | 776 +++++------ kernel/base/sched/sched_sq/los_sortlink.c | 125 +- kernel/common/los_config.c | 2 + .../extended/dynload/include/los_load_elf.h | 1 + kernel/extended/dynload/src/los_load_elf.c | 25 +- kernel/extended/liteipc/hm_liteipc.c | 7 +- kernel/extended/pipes/BUILD.gn | 9 +- kernel/extended/power/los_pm.c | 4 +- kernel/extended/trace/los_trace.c | 3 +- lib/libc/BUILD.gn | 10 +- lib/libscrew/BUILD.gn | 3 +- net/telnet/src/telnet_dev.c | 2 +- shell/full/src/cmds/hwi_shellcmd.c | 1 + syscall/process_syscall.c | 15 +- testsuites/unittest/net/netdb/config.gni | 1 - .../net/netdb/full/net_netdb_test_002.cpp | 12 + .../net/netdb/full/net_netdb_test_004.cpp | 20 +- .../net/netdb/full/net_netdb_test_006.cpp | 11 + .../net/netdb/full/net_netdb_test_007.cpp | 12 + .../net/netdb/full/net_netdb_test_008.cpp | 12 + .../net/netdb/full/net_netdb_test_009.cpp | 12 + .../net/netdb/full/net_netdb_test_011.cpp | 17 +- .../net/netdb/full/net_netdb_test_012.cpp | 26 +- .../net/netdb/full/net_netdb_test_014.cpp | 48 - .../net/netdb/full/net_netdb_test_015.cpp | 4 - .../net/netdb/full/net_netdb_test_016.cpp | 18 + .../net/netdb/full/net_netdb_test_017.cpp | 12 + .../net/netdb/full/net_netdb_test_018.cpp | 38 +- .../net/netdb/full/net_netdb_test_019.cpp | 43 +- .../net/netdb/full/net_netdb_test_020.cpp | 31 +- .../net/netdb/full/net_netdb_test_021.cpp | 15 +- .../net/netdb/full/net_netdb_test_022.cpp | 15 +- testsuites/unittest/net/netdb/lt_net_netdb.h | 1 - .../unittest/net/netdb/net_netdb_test.cpp | 201 +++ .../net/resolv/full/net_resolv_test_004.cpp | 12 + .../net/resolv/full/net_resolv_test_008.cpp | 12 + .../basic/process/smoke/process_test_010.cpp | 57 +- tools/build/liteos.ld | 2 +- zzz/git/push.sh | 2 +- 66 files changed, 2578 insertions(+), 2321 deletions(-) delete mode 100644 testsuites/unittest/net/netdb/full/net_netdb_test_014.cpp diff --git a/apps/mksh/BUILD.gn b/apps/mksh/BUILD.gn index 30f2fb39..379d78f0 100644 --- a/apps/mksh/BUILD.gn +++ b/apps/mksh/BUILD.gn @@ -29,13 +29,14 @@ import("//build/lite/config/component/lite_component.gni") import("//kernel/liteos_a/liteos.gni") +import("//third_party/mksh/mksh.gni") group("mksh") { deps = [ ":build_mksh" ] } copy("copy_mksh_src") { - sources = [ "$LITEOSTHIRDPARTY/mksh" ] + sources = MKSH_SRC_DIR outputs = [ "$target_out_dir/mksh_build" ] } diff --git a/apps/toybox/BUILD.gn b/apps/toybox/BUILD.gn index c7b2f06f..a6d74a10 100644 --- a/apps/toybox/BUILD.gn +++ b/apps/toybox/BUILD.gn @@ -29,13 +29,14 @@ import("//build/lite/config/component/lite_component.gni") import("//kernel/liteos_a/liteos.gni") +import("//third_party/toybox/toybox.gni") group("toybox") { deps = [ ":build_toybox" ] } copy("copy_toybox_src") { - sources = [ "$LITEOSTHIRDPARTY/toybox" ] + sources = TOYBOX_SRC_DIR outputs = [ "$target_out_dir/toybox_build" ] } diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 8935f731..91e35128 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -83,6 +83,7 @@ #include "los_memory_pri.h" #include "los_printf_pri.h" #include "los_task_pri.h" +#include "los_percpu_pri.h" #include "los_hw_pri.h" #ifdef LOSCFG_SAVE_EXCINFO #include "los_excinfo_pri.h" @@ -108,10 +109,10 @@ #include "los_bitmap.h" #include "los_process_pri.h" #include "los_exc_pri.h" +#include "los_sched_pri.h" #ifdef LOSCFG_FS_VFS #include "console.h" #endif - #ifdef LOSCFG_BLACKBOX #include "los_blackbox.h" #endif @@ -269,7 +270,7 @@ UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT3 return LOS_ERRNO_VM_NOT_FOUND; } #if defined(LOSCFG_KERNEL_SMP) && defined(LOSCFG_DEBUG_VERSION) - BOOL irqEnable = !(LOS_SpinHeld(&g_taskSpin) && (OsPercpuGet()->taskLockCnt != 0)); + BOOL irqEnable = !(LOS_SpinHeld(&g_taskSpin) && OsSchedIsLock()); if (irqEnable) { ArchIrqEnable(); } else { @@ -632,9 +633,9 @@ STATIC VOID OsExcRestore(VOID) g_intCount[currCpuID] = 0; //CPU对应的中断数量清0 g_curNestCount[currCpuID] = 0; #ifdef LOSCFG_KERNEL_SMP - OsPercpuGet()->excFlag = CPU_RUNNING; + OsCpuStatusSet(CPU_RUNNING); #endif - OsPercpuGet()->taskLockCnt = 0; + OsSchedLockSet(0); } ///用户态异常处理函数 STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) @@ -684,7 +685,7 @@ STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) SCHEDULER_UNLOCK(intSave); /* Exception handling All operations should be kept prior to that operation */ OsExcRestore(); - OsTaskToExit(runTask, OS_PRO_EXIT_OK); + OsRunningTaskToExit(runTask, OS_PRO_EXIT_OK); } else { SCHEDULER_UNLOCK(intSave); @@ -1081,28 +1082,7 @@ VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr) #ifdef LOSCFG_KERNEL_SMP #define EXC_WAIT_INTER 50U //异常等待间隔时间 #define EXC_WAIT_TIME 2000U //异常等待时间 -//打印所有CPU的状态信息 -STATIC VOID OsAllCpuStatusOutput(VOID) -{ - UINT32 i; - for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { - switch (g_percpu[i].excFlag) { - case CPU_RUNNING: //处于运行状态 - PrintExcInfo("cpu%u is running.\n", i); - break; - case CPU_HALT: //处于停止状态 - PrintExcInfo("cpu%u is halted.\n", i); - break; - case CPU_EXC: //处于异常接管状态 - PrintExcInfo("cpu%u is in exc.\n", i); - break; - default: - break; - } - } - PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid()); //当前正在处理异常的CPU是: -} ///等待所有CPU停止 STATIC VOID WaitAllCpuStop(UINT32 cpuID) { @@ -1111,7 +1091,7 @@ STATIC VOID WaitAllCpuStop(UINT32 cpuID) while (time < EXC_WAIT_TIME) { for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { - if ((i != cpuID) && (g_percpu[i].excFlag != CPU_HALT)) { + if ((i != cpuID) && !OsCpuStatusIsHalt(i)) { LOS_Mdelay(EXC_WAIT_INTER); time += EXC_WAIT_INTER; break; @@ -1149,7 +1129,7 @@ STATIC VOID OsCheckAllCpuStatus(VOID) UINT32 currCpuID = ArchCurrCpuid(); UINT32 ret, target; - OsPercpuGet()->excFlag = CPU_EXC; //CPU处于异常接管状态 + OsCpuStatusSet(CPU_EXC); LOCKDEP_CLEAR_LOCKS(); LOS_SpinLock(&g_excSerializerSpin); @@ -1257,15 +1237,15 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsPrintExcHead(UINT32 far) STATIC VOID OsSysStateSave(UINT32 *intCount, UINT32 *lockCount) { *intCount = g_intCount[ArchCurrCpuid()]; - *lockCount = OsPercpuGet()->taskLockCnt; + *lockCount = OsSchedLockCountGet(); g_intCount[ArchCurrCpuid()] = 0; - OsPercpuGet()->taskLockCnt = 0; + OsSchedLockSet(0); } STATIC VOID OsSysStateRestore(UINT32 intCount, UINT32 lockCount) { g_intCount[ArchCurrCpuid()] = intCount; - OsPercpuGet()->taskLockCnt = lockCount; + OsSchedLockSet(lockCount); } #endif @@ -1281,7 +1261,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAd UINT32 lockCount; #endif /* Task scheduling is not allowed during exception handling */ - OsPercpuGet()->taskLockCnt++; + OsSchedLock(); g_curNestCount[ArchCurrCpuid()]++; diff --git a/drivers/char/bch/BUILD.gn b/drivers/char/bch/BUILD.gn index cc684575..634b1e7c 100644 --- a/drivers/char/bch/BUILD.gn +++ b/drivers/char/bch/BUILD.gn @@ -28,21 +28,12 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_FS_VFS_BLOCK_DEVICE) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { - sources = [ - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchdev_driver.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchdev_register.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchdev_unregister.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchlib_cache.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchlib_read.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchlib_sem.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchlib_setup.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchlib_teardown.c", - "$LITEOSTHIRDPARTY/NuttX/drivers/bch/bchlib_write.c", - ] + sources = NUTTX_DRIVERS_BCH_SRC_FILES public_configs = [ ":public" ] } diff --git a/drivers/char/video/BUILD.gn b/drivers/char/video/BUILD.gn index 1470983e..a7fcc3f9 100644 --- a/drivers/char/video/BUILD.gn +++ b/drivers/char/video/BUILD.gn @@ -28,15 +28,16 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_DRIVERS_VIDEO) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { - sources = [ "$LITEOSTHIRDPARTY/NuttX/drivers/video/fb.c" ] + sources = NUTTX_DRIVERS_VIDEO_SRC_FILES public_configs = [ ":public" ] } config("public") { - include_dirs = [ "$LITEOSTHIRDPARTY/NuttX/include/nuttx/video" ] + include_dirs = NUTTX_DRIVERS_VIDEO_INCLUDE_DIRS } diff --git a/fs/fat/BUILD.gn b/fs/fat/BUILD.gn index 34abc034..921f9ea6 100644 --- a/fs/fat/BUILD.gn +++ b/fs/fat/BUILD.gn @@ -28,6 +28,7 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/FatFs/FatFs.gni") module_switch = defined(LOSCFG_FS_FAT) module_name = get_path_info(rebase_path("."), "name") @@ -38,12 +39,7 @@ kernel_module(module_name) { "os_adapt/format.c", ] - sources += [ - "$LITEOSTHIRDPARTY/FatFs/source/diskio.c", - "$LITEOSTHIRDPARTY/FatFs/source/ff.c", - "$LITEOSTHIRDPARTY/FatFs/source/ffsystem.c", - "$LITEOSTHIRDPARTY/FatFs/source/ffunicode.c", - ] + sources += FATFS_SRC_FILES include_dirs = [ "os_adapt" ] @@ -51,5 +47,5 @@ kernel_module(module_name) { } config("public") { - include_dirs = [ "$LITEOSTHIRDPARTY/FatFs/source" ] + include_dirs = FATFS_INCLUDE_DIRS } diff --git a/fs/jffs2/BUILD.gn b/fs/jffs2/BUILD.gn index bf5eecc1..e90e0e28 100644 --- a/fs/jffs2/BUILD.gn +++ b/fs/jffs2/BUILD.gn @@ -28,6 +28,7 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/Linux_Kernel/Linux_Kernel.gni") module_switch = defined(LOSCFG_FS_JFFS) module_name = get_path_info(rebase_path("."), "name") @@ -37,35 +38,9 @@ kernel_module(module_name) { "src/vfs_jffs2.c", ] - sources += [ - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/background.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/build.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/compr.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/compr_rtime.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/compr_rubin.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/compr_zlib.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/debug.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/dir.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/erase.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/file.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/fs.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/gc.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/malloc.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/nodelist.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/nodemgmt.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/read.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/readinode.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/scan.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/summary.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/super.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/write.c", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2/writev.c", - ] + sources += LINUX_KERNEL_FS_JFFS2_SRC_FILES - include_dirs = [ - "$LITEOSTHIRDPARTY/Linux_Kernel/fs/jffs2", - "$LITEOSTHIRDPARTY/Linux_Kernel/fs", - ] + include_dirs = LINUX_KERNEL_FS_JFFS2_INCLUDE_DIRS public_configs = [ ":public" ] } diff --git a/fs/nfs/BUILD.gn b/fs/nfs/BUILD.gn index 8f987f9d..4a5c8cf4 100644 --- a/fs/nfs/BUILD.gn +++ b/fs/nfs/BUILD.gn @@ -28,13 +28,10 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_FS_NFS) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { - sources = [ - "$LITEOSTHIRDPARTY/NuttX/fs/nfs/nfs_adapter.c", - "$LITEOSTHIRDPARTY/NuttX/fs/nfs/nfs_util.c", - "$LITEOSTHIRDPARTY/NuttX/fs/nfs/rpc_clnt.c", - ] + sources = NUTTX_FS_NFS_SRC_FILES } diff --git a/fs/ramfs/BUILD.gn b/fs/ramfs/BUILD.gn index 5b593f83..716f4c3a 100644 --- a/fs/ramfs/BUILD.gn +++ b/fs/ramfs/BUILD.gn @@ -28,9 +28,10 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_FS_RAMFS) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { - sources = [ "$LITEOSTHIRDPARTY/NuttX/fs/tmpfs/fs_tmpfs.c" ] + sources = NUTTX_FS_TMPFS_SRC_FILES } diff --git a/fs/romfs/BUILD.gn b/fs/romfs/BUILD.gn index eef06c08..4e371f7d 100644 --- a/fs/romfs/BUILD.gn +++ b/fs/romfs/BUILD.gn @@ -28,12 +28,10 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_FS_ROMFS) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { - sources = [ - "$LITEOSTHIRDPARTY/NuttX/fs/romfs/fs_romfs.c", - "$LITEOSTHIRDPARTY/NuttX/fs/romfs/fs_romfsutil.c", - ] + sources = NUTTX_FS_ROMFS_SRC_FILES } diff --git a/fs/vfs/BUILD.gn b/fs/vfs/BUILD.gn index 5f128d49..b04eddfb 100644 --- a/fs/vfs/BUILD.gn +++ b/fs/vfs/BUILD.gn @@ -28,11 +28,17 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_FS_VFS) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { sources = [ + "$LITEOSTOPDIR/fs/vfs/epoll/fs_epoll.c", + "$LITEOSTOPDIR/fs/vfs/mount.c", + "$LITEOSTOPDIR/fs/vfs/path_cache.c", + "$LITEOSTOPDIR/fs/vfs/vnode.c", + "$LITEOSTOPDIR/fs/vfs/vnode_hash.c", "operation/fullpath.c", "operation/vfs_chattr.c", "operation/vfs_check.c", @@ -51,65 +57,11 @@ kernel_module(module_name) { "operation/vfs_writev.c", "vfs_cmd/vfs_shellcmd.c", ] - - sources += [ - "$LITEOSTHIRDPARTY/NuttX/fs/dirent/fs_closedir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/dirent/fs_opendir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/dirent/fs_readdir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/dirent/fs_rewinddir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/dirent/fs_seekdir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/dirent/fs_telldir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_blockproxy.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_closeblockdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_findblockdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_openblockdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_registerblockdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_registerdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_unregisterblockdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/driver/fs_unregisterdriver.c", - "$LITEOSTHIRDPARTY/NuttX/fs/inode/fs_files.c", - "$LITEOSTHIRDPARTY/NuttX/fs/mount/fs_foreachmountpoint.c", - "$LITEOSTHIRDPARTY/NuttX/fs/mount/fs_mount.c", - "$LITEOSTHIRDPARTY/NuttX/fs/mount/fs_sync.c", - "$LITEOSTHIRDPARTY/NuttX/fs/mount/fs_umount.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_close.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_dup.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_dup2.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_dupfd.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_dupfd2.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_fcntl.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_fsync.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_getfilep.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_ioctl.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_link.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_lseek.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_lseek64.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_mkdir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_open.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_poll.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_pread.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_pread64.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_pwrite.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_pwrite64.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_read.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_readlink.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_rename.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_rmdir.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_select.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_sendfile.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_stat.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_statfs.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_symlink.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_truncate.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_truncate64.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_unlink.c", - "$LITEOSTHIRDPARTY/NuttX/fs/vfs/fs_write.c", - "$LITEOSTOPDIR/fs/vfs/epoll/fs_epoll.c", - "$LITEOSTOPDIR/fs/vfs/mount.c", - "$LITEOSTOPDIR/fs/vfs/path_cache.c", - "$LITEOSTOPDIR/fs/vfs/vnode.c", - "$LITEOSTOPDIR/fs/vfs/vnode_hash.c", - ] + sources += NUTTX_FS_DIRENT_SRC_FILES + sources += NUTTX_FS_DRIVER_SRC_FILES + sources += NUTTX_FS_INODE_SRC_FILES + sources += NUTTX_FS_MOUNT_SRC_FILES + sources += NUTTX_FS_VFS_SRC_FILES include_dirs = [ "$LITEOSTOPDIR/syscall", diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 1f96c916..753e5cce 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -69,6 +69,9 @@ #ifdef LOSCFG_SECURITY_CAPABILITY #include "capability_api.h" #endif +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_load_elf.h" +#endif #include "los_swtmr_pri.h" #include "los_vm_map.h" #include "los_vm_phys.h" @@ -100,6 +103,50 @@ STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB) processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;//timeID初始化值 LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);//进程节点挂入g_freeProcess以分配给后续进程使用 } + +VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) +{ + LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); + + LOS_ListDelete(&taskCB->threadList); + processCB->threadNumber--; + OsTaskInsertToRecycleList(taskCB); +} + +UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB) +{ + UINT32 intSave; + UINT16 numCount; + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + + SCHEDULER_LOCK(intSave); + taskCB->processID = pid; + LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList)); + + if (OsProcessIsUserMode(processCB)) { + taskCB->taskStatus |= OS_TASK_FLAG_USER_MODE; + if (processCB->threadNumber > 0) { + taskCB->basePrio = OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio; + } else { + taskCB->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST; + } + } else { + taskCB->basePrio = OsCurrTaskGet()->basePrio; + } + +#ifdef LOSCFG_KERNEL_VM + taskCB->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; +#endif + if (!processCB->threadNumber) { + processCB->threadGroupID = taskCB->taskID; + } + processCB->threadNumber++; + + numCount = processCB->threadCount; + processCB->threadCount++; + SCHEDULER_UNLOCK(intSave); + return numCount; +} /** * @brief 创建进程组 * @details @@ -381,11 +428,6 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro /*! 回收指定进程的资源 */ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) { - if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {//初始化和正在运行的进程,不用/能回收 - PRINT_ERR("The process(%d) has no permission to release process(%d) resources!\n",// @note_thinking 此处应该直接 return回去吧 ! - OsCurrProcessGet()->processID, processCB->processID); - } - #ifdef LOSCFG_KERNEL_VM if (OsProcessIsUserMode(processCB)) { (VOID)OsVmSpaceRegionFree(processCB->vmSpace); @@ -440,6 +482,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, Proc OsExitProcessGroup(childCB, group);//退出进程组 LOS_ListDelete(&childCB->siblingList);//从父亲大人的子孙链表上摘除 if (childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) {//如果身上僵死状态的标签 + OsDeleteTaskFromProcess(OS_TCB_FROM_TID(childCB->threadGroupID)); childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;//去掉僵死标签 childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;//贴上没使用标签,进程由进程池分配,进程退出后重新回到空闲进程池 } @@ -502,13 +545,10 @@ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) } /*! 一个进程的自然消亡过程,参数是当前运行的任务*/ -STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) +VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status) { - LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID);//通过task找到所属PCB LosProcessCB *parentCB = NULL; - LOS_ASSERT(processCB->processStatus & OS_PROCESS_STATUS_RUNNING);//断言必须为正在运行的进程 - OsChildProcessResourcesFree(processCB);//释放孩子进程的资源 @@ -533,7 +573,6 @@ STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION);//以内核权限发送SIGCHLD(子进程退出)信号. #endif LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);//将进程通过其阻塞节点挂入全局进程回收链表 - OsRunTaskToDelete(runTask);//删除正在运行的任务 return; } @@ -693,13 +732,12 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) } /*! 初始化PCB(进程控制块)*/ -STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, const CHAR *name) +STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) { processCB->processMode = mode; //用户态进程还是内核态进程 processCB->processStatus = OS_PROCESS_STATUS_INIT; //进程初始状态 processCB->parentProcessID = OS_INVALID_VALUE; //爸爸进程,外面指定 processCB->threadGroupID = OS_INVALID_VALUE; //所属线程组 - processCB->priority = priority; //进程优先级 processCB->umask = OS_PROCESS_DEFAULT_UMASK; //掩码 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; @@ -816,10 +854,10 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) } /*! 进程创建初始化*/ -STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name, UINT16 priority) +STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name) { ProcessGroup *group = NULL; - UINT32 ret = OsInitPCB(processCB, flags, priority, name);//初始化进程控制块 + UINT32 ret = OsInitPCB(processCB, flags, name); if (ret != LOS_OK) { goto EXIT; } @@ -861,7 +899,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) } LosProcessCB *kerInitProcess = OS_PCB_FROM_PID(g_kernelInitProcess);//获取进程池中2号实体 - ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess", 0);//创建内核态祖宗进程 + ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess");//创建内核态祖宗进程 if (ret != LOS_OK) { return ret; } @@ -869,10 +907,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;//去掉初始化标签 g_processGroup = kerInitProcess->group;//进程组ID就是2号进程本身 LOS_ListInit(&g_processGroup->groupList);//初始化进程组链表 - OsCurrProcessSet(kerInitProcess);//设置为当前进程,注意当前进程是内核的视角,并不代表一旦设置就必须执行进程的任务. LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess);//获取进程池中0号实体 - ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, OS_TASK_PRIORITY_LOWEST, "KIdle");//创建内核态0号进程 + ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle");//创建内核态0号进程 if (ret != LOS_OK) { return ret; } @@ -886,12 +923,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) #ifdef LOSCFG_FS_VFS idleProcess->files = kerInitProcess->files;//共享文件 #endif + idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; ret = OsIdleTaskCreate();//创建cpu的idle任务,从此当前CPU OsPercpuGet()->idleTaskID 有了休息的地方. if (ret != LOS_OK) { return ret; } - idleProcess->threadGroupID = OsPercpuGet()->idleTaskID;//设置进程的多线程组长 + idleProcess->threadGroupID = OsGetIdleTaskId(); return LOS_OK; } @@ -928,7 +966,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) } /* user mode process can reduce the priority of itself */ - if ((runProcess->processID == processCB->processID) && (prio > processCB->priority)) {//用户模式下进程阔以降低自己的优先级 + if ((runProcess->processID == processCB->processID) && (prio > OsCurrTaskGet()->basePrio)) { return TRUE; } @@ -966,7 +1004,7 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio } #endif - needSched = OsSchedModifyProcessSchedParam(processCB, policy, prio); + needSched = OsSchedModifyProcessSchedParam(pid, policy, prio); SCHEDULER_UNLOCK(intSave);//还锁 LOS_MpSchedule(OS_MP_CPU_ALL);//核间中断 @@ -1012,7 +1050,6 @@ LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio) /// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户 LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) { - LosProcessCB *processCB = NULL; INT32 prio; UINT32 intSave; (VOID)which; @@ -1025,14 +1062,14 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) return -LOS_EINVAL; } + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); SCHEDULER_LOCK(intSave); - processCB = OS_PCB_FROM_PID(pid); if (OsProcessIsUnused(processCB)) { prio = -LOS_ESRCH; goto OUT; } - prio = (INT32)processCB->priority; + prio = (INT32)OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio; OUT: SCHEDULER_UNLOCK(intSave); @@ -1490,6 +1527,36 @@ STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size) return (VOID *)(UINTPTR)region->range.base; } +#ifdef LOSCFG_KERNEL_DYNLOAD +LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + + processCB->vmSpace = oldSpace; + runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; + LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu); +} + +LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + + OsProcessThreadGroupDestroy(); + OsTaskCBRecycleToFree(); + + LosVmSpace *oldSpace = processCB->vmSpace; + processCB->vmSpace = newSpace; + processCB->vmSpace->heapBase += OsGetRndOffset(randomDevFD); + processCB->vmSpace->heapNow = processCB->vmSpace->heapBase; + processCB->vmSpace->mapBase += OsGetRndOffset(randomDevFD); + processCB->vmSpace->mapSize = stackBase - processCB->vmSpace->mapBase; + runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; + LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu); + return oldSpace; +} + /** * @brief 进程的回收再利用,被LOS_DoExecveFile调用 * @param processCB @@ -1576,27 +1643,39 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT SCHEDULER_UNLOCK(intSave);//解锁 return LOS_OK; } +#endif /// 用户进程开始初始化 -STATIC UINT32 OsUserInitProcessStart(UINT32 processID, TSK_INIT_PARAM_S *param) +STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param) { UINT32 intSave; - UINT32 taskID; INT32 ret; - taskID = OsCreateUserTask(processID, param);//创建一个用户态任务 + UINT32 taskID = OsCreateUserTask(processCB->processID, param); if (taskID == OS_INVALID_VALUE) { return LOS_NOK; } + ret = LOS_SetProcessPriority(processCB->processID, OS_PROCESS_USERINIT_PRIORITY); + if (ret != LOS_OK) { + PRINT_ERR("User init process set priority failed! ERROR:%d \n", ret); + goto EXIT; + } + + SCHEDULER_LOCK(intSave); + processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; + SCHEDULER_UNLOCK(intSave); + ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST);//调度器:设置为抢占式调度和最低任务优先级(31级) if (ret != LOS_OK) { PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret); - SCHEDULER_LOCK(intSave); - (VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(taskID), OS_PRO_EXIT_OK, intSave); - return LOS_NOK; + goto EXIT; } return LOS_OK; + +EXIT: + (VOID)LOS_TaskDelete(taskID); + return ret; } STATIC UINT32 OsLoadUserInit(LosProcessCB *processCB) @@ -1672,7 +1751,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) VOID *stack = NULL; LosProcessCB *processCB = OS_PCB_FROM_PID(g_userInitProcess); - ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init", OS_PROCESS_USERINIT_PRIORITY); + ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init"); if (ret != LOS_OK) { return ret; } @@ -1693,7 +1772,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) param.userParam.userMapBase = (UINTPTR)stack; param.userParam.userMapSize = size; param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN; - ret = OsUserInitProcessStart(g_userInitProcess, ¶m); + ret = OsUserInitProcessStart(processCB, ¶m); if (ret != LOS_OK) { (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize); goto ERROR; @@ -1770,6 +1849,7 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID); childTaskCB->taskStatus = runTask->taskStatus;//任务状态先同步,注意这里是赋值操作. ...01101001 + childTaskCB->basePrio = runTask->basePrio; if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//因只能有一个运行的task,所以如果一样要改4号位 childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001 } else {//非运行状态下会发生什么? @@ -1777,7 +1857,6 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus); } childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED;//干净的Task - childProcessCB->priority = OS_PROCESS_PRIORITY_LOWEST;//进程设为最低优先级 } if (OsProcessIsUserMode(childProcessCB)) {//是否是用户进程 @@ -1795,7 +1874,6 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces LosProcessCB *parentProcessCB = NULL; SCHEDULER_LOCK(intSave); - childProcessCB->priority = runProcessCB->priority; //当前进程所处阶级 if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系 parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID);//找出当前进程的父亲大人 @@ -1860,7 +1938,7 @@ STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINT32 ret; LosProcessCB *run = OsCurrProcessGet();//获取当前进程 - ret = OsInitPCB(child, run->processMode, OS_PROCESS_PRIORITY_LOWEST, name); + ret = OsInitPCB(child, run->processMode, name); if (ret != LOS_OK) { return ret; } @@ -1888,6 +1966,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB * } } + child->processStatus &= ~OS_PROCESS_STATUS_INIT; OsSchedTaskEnQueue(OS_TCB_FROM_TID(child->threadGroupID)); SCHEDULER_UNLOCK(intSave); @@ -1927,7 +2006,7 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce /// 拷贝进程 STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size) { - UINT32 intSave, ret, processID; + UINT32 ret, processID; LosProcessCB *run = OsCurrProcessGet();//获取当前进程 LosProcessCB *child = OsGetFreePCB();//从进程池中申请一个进程控制块,鸿蒙进程池默认64 @@ -1959,8 +2038,7 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si return processID; ERROR_TASK: - SCHEDULER_LOCK(intSave); - (VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(child->threadGroupID), OS_PRO_EXIT_OK, intSave); + (VOID)LOS_TaskDelete(child->threadGroupID); ERROR_INIT: OsDeInitPCB(child); return -ret; @@ -2026,8 +2104,9 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) return; } SCHEDULER_UNLOCK(intSave); - OsTaskExitGroup((UINT32)status);//退出进程组 - OsProcessExit(OsCurrTaskGet(), (UINT32)status);//进程退出 + + OsProcessThreadGroupDestroy(); + OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK); } @@ -2091,17 +2170,77 @@ LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID) return OsCurrProcessGet()->processID; } /// 按指定状态退出指定进程 -LITE_OS_SEC_TEXT VOID OsProcessExit(LosTaskCB *runTask, INT32 status) +#ifdef LOSCFG_KERNEL_VM +STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB) { - UINT32 intSave; - LOS_ASSERT(runTask == OsCurrTaskGet());//只有当前进程才能调用这个函数,即进程最后的退出不假手他人 + INT32 ret; - OsTaskResourcesToFree(runTask);//释放任务资源 - OsProcessResourcesToFree(OsCurrProcessGet());//释放进程资源 + taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL; +#ifdef LOSCFG_KERNEL_SMP + /** The other core that the thread is running on and is currently running in a non-system call */ + if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + } else +#endif + { + ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n", + taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret); + } + } + if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { + taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + LOS_ListInit(&taskCB->joinList); + } + + ret = OsTaskJoinPendUnsafe(taskCB); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n", + taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret); + } +} +#endif + +LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID) +{ +#ifdef LOSCFG_KERNEL_VM + UINT32 intSave; + + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *currTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - OsProcessNaturalExit(runTask, status);//进程自然退出 + if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + processCB->processStatus |= OS_PROCESS_FLAG_EXIT; + processCB->threadGroupID = currTask->taskID; + + LOS_DL_LIST *list = &processCB->threadSiblingList; + LOS_DL_LIST *head = list; + do { + LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); + if ((OsTaskIsInactive(taskCB) || + ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) && + !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + OsInactiveTaskDelete(taskCB); + } else if (taskCB != currTask) { + ThreadGroupActiveTaskKilled(taskCB); + } else { + /* Skip the current task */ + list = list->pstNext; + } + } while (head != list->pstNext); + SCHEDULER_UNLOCK(intSave); + + LOS_ASSERT(processCB->threadNumber == 1); +#endif + return; } /// 获取系统支持的最大进程数目 LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID) diff --git a/kernel/base/core/los_smp.c b/kernel/base/core/los_smp.c index d92c7f55..01b919a6 100644 --- a/kernel/base/core/los_smp.c +++ b/kernel/base/core/los_smp.c @@ -45,8 +45,6 @@ STATIC VOID OsSmpSecondaryInit(VOID *arg) { UNUSED(arg); - OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID())); - #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE OsSwtmrInit(); #endif diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index ba2a22cd..6f49d391 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -1,637 +1,595 @@ -/* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*! -* @file los_swtmr.c -* @brief 软定时器主文件 -* @details -* @attention @verbatim -基本概念 - 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。 - 硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器, - 软件定时器功能,支持如下特性: - 创建软件定时器。 - 启动软件定时器。 - 停止软件定时器。 - 删除软件定时器。 - 获取软件定时器剩余Tick数。 - 可配置支持的软件定时器个数。 - - 运作机制 - 软件定时器是系统资源,在模块初始化的时候已经分配了一块连续内存。 - 软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则, - 先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先触发的准则。 - 软件定时器以Tick为基本计时单位,当创建并启动一个软件定时器时,Huawei LiteOS会根据 - 当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 - 当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时, - 若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高) - 被唤醒,在该任务中调用已经记录下来的定时器的回调函数。 - - 定时器状态 - OS_SWTMR_STATUS_UNUSED(定时器未使用) - 系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。 - - OS_SWTMR_STATUS_TICKING(定时器处于计数状态) - 在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。 - - OS_SWTMR_STATUS_CREATED(定时器创建后未启动,或已停止) - 定时器创建后,不处于计数状态时,定时器将变成该状态。 - - 软件定时器提供了三类模式: - 单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 - 周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。 - 单次触发定时器,但这类定时器超时触发后不会自动删除,需要调用定时器删除接口删除定时器。 - - 使用场景 - 创建一个单次触发的定时器,超时后执行用户自定义的回调函数。 - 创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。 - - 软件定时器的典型开发流程 - 通过make menuconfig配置软件定时器 - 创建定时器LOS_SwtmrCreate,设置定时器的定时时长、定时器模式、超时后的回调函数。 - 启动定时器LOS_SwtmrStart。 - 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。 - 停止定时器LOS_SwtmrStop。 - 删除定时器LOS_SwtmrDelete。 - - 注意事项 - 软件定时器的回调函数中不应执行过多操作,不建议使用可能引起任务挂起或者阻塞的接口或操作, - 如果使用会导致软件定时器响应不及时,造成的影响无法确定。 - 软件定时器使用了系统的一个队列和一个任务资源。软件定时器任务的优先级设定为0,且不允许修改 。 - 系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。 - 例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。 - 创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 - 软件定时器的定时精度与系统Tick时钟的周期有关。 - @endverbatim -*/ - -#include "los_swtmr_pri.h" -#include "los_init.h" -#include "los_process_pri.h" -#include "los_queue_pri.h" -#include "los_sched_pri.h" -#include "los_sortlink_pri.h" -#include "los_task_pri.h" -#include "los_hook.h" - -#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE -#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0) -#error "swtmr maxnum cannot be zero" -#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */ - -LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /**< First address in Timer memory space \n 定时器池 */ -LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /**< Pool of Swtmr Handler \n 用于注册软时钟的回调函数 */ -LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /**< Free list of Software Timer \n 空闲定时器链表 */ - -/* spinlock for swtmr module, only available on SMP mode */ -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);///< 初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步 -#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))///< 持有软时钟自旋锁 -#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))///< 释放软时钟自旋锁 - -/** - * @brief 软时钟的入口函数,拥有任务的最高优先级 0 级! - * - * @return LITE_OS_SEC_TEXT - */ -LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) -{ - SwtmrHandlerItemPtr swtmrHandlePtr = NULL; - SwtmrHandlerItem swtmrHandle; - UINT32 ret, swtmrHandlerQueue; - - swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue;//获取定时器超时队列 - for (;;) {//死循环获取队列item,一直读干净为止 - ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER);//一个一个读队列 - if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) { - swtmrHandle.handler = swtmrHandlePtr->handler;//超时中断处理函数,也称回调函数 - swtmrHandle.arg = swtmrHandlePtr->arg;//回调函数的参数 - (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存 - if (swtmrHandle.handler != NULL) { - swtmrHandle.handler(swtmrHandle.arg);//回调函数处理函数 - } - } - } -} -///创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务 -LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) -{ - UINT32 ret, swtmrTaskID; - TSK_INIT_PARAM_S swtmrTask; - UINT32 cpuid = ArchCurrCpuid();//获取当前CPU id - - (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0 - swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask;//入口函数 - swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K默认内核任务栈 - swtmrTask.pcName = "Swt_Task";//任务名称 - swtmrTask.usTaskPrio = 0;//哇塞! 逮到一个最高优先级的任务 @note_thinking 这里应该用 OS_TASK_PRIORITY_HIGHEST 表示 - swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式 -#ifdef LOSCFG_KERNEL_SMP - swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务 -#endif - ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask);//创建任务并申请调度 - if (ret == LOS_OK) { - g_percpu[cpuid].swtmrTaskID = swtmrTaskID;//全局变量记录 软时钟任务ID - OS_TCB_FROM_TID(swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是一个系统任务 - } - - return ret; -} -///回收指定进程的软时钟 -LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID) -{ - for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器 - if (g_swtmrCBArray[index].uwOwnerPid == processID) {//找到一个 - LOS_SwtmrDelete(index);//删除定时器 - } - } -} -///软时钟初始化 ,注意函数在多CPU情况下会执行多次 -LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) -{ - UINT32 size; - UINT16 index; - UINT32 ret; - SWTMR_CTRL_S *swtmr = NULL; - UINT32 swtmrHandlePoolSize; - UINT32 cpuid = ArchCurrCpuid(); - if (cpuid == 0) {//确保以下代码块由一个CPU执行,g_swtmrCBArray和g_swtmrHandlerPool 是所有CPU共用的 - size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT;//申请软时钟内存大小 - swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */ //常驻内存 - if (swtmr == NULL) { - ret = LOS_ERRNO_SWTMR_NO_MEMORY; - goto ERROR; - } - - (VOID)memset_s(swtmr, size, 0, size);//清0 - g_swtmrCBArray = swtmr;//软时钟 - LOS_ListInit(&g_swtmrFreeList);//初始化空闲链表 - for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { - swtmr->usTimerID = index;//按顺序赋值 - LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表 - } - //想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息. - swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//计算所有注册函数内存大小 - //规划一片内存区域作为软时钟处理函数的静态内存池。 - g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource *///常驻内存 - if (g_swtmrHandlerPool == NULL) { - ret = LOS_ERRNO_SWTMR_NO_MEMORY; - goto ERROR; - } - - ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem));//初始化软时钟注册池 - if (ret != LOS_OK) { - ret = LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM; - goto ERROR; - } - ret = OsSchedSwtmrScanRegister((SchedScan)OsSwtmrScan); - if (ret != LOS_OK) { - goto ERROR; - } - } - //每个CPU都会创建一个属于自己的 OS_SWTMR_HANDLE_QUEUE_SIZE 的队列 - ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &g_percpu[cpuid].swtmrHandlerQueue, 0, sizeof(CHAR *));//为当前CPU core 创建软时钟队列 maxMsgSize:sizeof(CHAR *) - if (ret != LOS_OK) { - ret = LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; - goto ERROR; - } - - ret = OsSwtmrTaskCreate();//每个CPU独自创建属于自己的软时钟任务,统一处理队列 - if (ret != LOS_OK) { - ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; - goto ERROR; - } - - ret = OsSortLinkInit(&g_percpu[cpuid].swtmrSortLink);//每个CPU独自对自己软时钟链表排序初始化,为啥要排序因为每个定时器的时间不一样,鸿蒙把用时短的排在前面 - if (ret != LOS_OK) { - ret = LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED; - goto ERROR; - } - - return LOS_OK; -ERROR: - PRINT_ERR("OsSwtmrInit error! ret = %u\n", ret); - return ret; -} - -/* - * Description: Start Software Timer \n 开始定时器 - * Input : swtmr --- Need to start software timer - */ -LITE_OS_SEC_TEXT VOID OsSwtmrStart(UINT64 currTime, SWTMR_CTRL_S *swtmr) -{ - UINT32 ticks; - - if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || - (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || - (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器 - ticks = swtmr->uwExpiry; //获取时间间隔 - } else { - ticks = swtmr->uwInterval;//获取周期性定时器时间间隔 - } - swtmr->ucState = OS_SWTMR_STATUS_TICKING;//计数状态 - - OsAdd2SortLink(&swtmr->stSortList, swtmr->startTime, ticks, OS_SORT_LINK_SWTMR);//加入链表中, 定时器任务将在tick处理函数中检查是否到期 - OsSchedUpdateExpireTime(currTime);//更新过期时间 - return; -} - -/* - * Description: Delete Software Timer - * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL. - */ -STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) -{ - /* insert to free list */ - LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用 - swtmr->ucState = OS_SWTMR_STATUS_UNUSED;//又干净着呢 - swtmr->uwOwnerPid = 0;//谁拥有这个定时器? 是 0号进程 -} - -STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_S *swtmr) -{ - LOS_SpinLock(&g_swtmrSpin); - SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); - if (swtmrHandler != NULL) { - swtmrHandler->handler = swtmr->pfnHandler; - swtmrHandler->arg = swtmr->uwArg; - - if (LOS_QueueWrite(cpu->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) { - (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler); - } - } - - if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) {//如果定时器只跑一次 - OsSwtmrDelete(swtmr);//删除定时器 - - if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { - swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; - } else { - swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; - } - } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { - swtmr->ucState = OS_SWTMR_STATUS_CREATED; - } else { - swtmr->uwOverrun++; - OsSwtmrStart(currTime, swtmr);//开始定时器 - } - - LOS_SpinUnlock(&g_swtmrSpin); -} -/* - * Description: Tick interrupt interface module of software timer - * Return : LOS_OK on success or error code on failure - */ -/*! - * @brief OsSwtmrScan 由系统时钟中断处理函数调用 - * 扫描定时器,如果碰到超时的,就放入超时队列 - * @return - * - * @see - */ -LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) -{ - Percpu *cpu = OsPercpuGet();//获取当前CPU - SortLinkAttribute* swtmrSortLink = &cpu->swtmrSortLink;//获取需由CPU处理的软件定时器总信息 - LOS_DL_LIST *listObject = &swtmrSortLink->sortLink;//获取定时器链表,上面挂的是等待时间到触发的定时器 - - /* - * it needs to be carefully coped with, since the swtmr is in specific sortlink - * while other cores still has the chance to process it, like stop the timer. - */ - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - - if (LOS_ListEmpty(listObject)) { - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - return; - } - SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//获取节点 - - UINT64 currTime = OsGetCurrSchedTimeCycle();//获取当前时间,用于比较所有定时器的时间是否到了 - while (sortList->responseTime <= currTime) {//说明有定时器的时间到了,需要去触发定时器了 - sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//这行代码多余了,可以删除 @note_why - SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);//获取软件定时器控制块 - swtmr->startTime = GET_SORTLIST_VALUE(sortList);//获取该定时器的响应时间 - OsDeleteNodeSortLink(swtmrSortLink, sortList);//将其从链表上摘除 - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - - OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr);//回调钩子函数 将调用 LOS_TraceSwtmrExpired - OsWakePendTimeSwtmr(cpu, currTime, swtmr);//触发定时器 - - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - if (LOS_ListEmpty(listObject)) {//链表为空就退出 - break; - } - - sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//继续下一个节点 - } - - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); -} - -LITE_OS_SEC_TEXT VOID OsSwtmrResponseTimeReset(UINT64 startTime) -{ - UINT32 intSave; - Percpu *cpu = OsPercpuGet(); - SortLinkAttribute* swtmrSortLink = &cpu->swtmrSortLink; - LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; - LOS_DL_LIST *listNext = listHead->pstNext; - - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - while (listNext != listHead) { - SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode); - OsDeleteNodeSortLink(swtmrSortLink, sortList); - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); - - SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); - - SWTMR_LOCK(intSave); - swtmr->startTime = startTime; - OsSwtmrStart(startTime, swtmr); - SWTMR_UNLOCK(intSave); - - LOS_SpinLock(&cpu->swtmrSortLinkSpin); - listNext = listNext->pstNext; - } - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); -} - -/* - * Description: Get next timeout - * Return : Count of the Timer list - */ -LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)//获取下一个timeout -{ - return OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink); -} - -/* - * Description: Stop of Software Timer interface - * Input : swtmr --- the software timer contrl handler - */ -LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) -{ - OsDeleteSortLink(&swtmr->stSortList, OS_SORT_LINK_SWTMR); - - swtmr->ucState = OS_SWTMR_STATUS_CREATED; - swtmr->uwOverrun = 0; - - OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle()); -} - -/* - * Description: Get next software timer expiretime - * Input : swtmr --- the software timer contrl handler - */ -LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) -{ - return OsSortLinkGetTargetExpireTime(&swtmr->stSortList); -} -///创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID -LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, - UINT8 mode, - SWTMR_PROC_FUNC handler, - UINT16 *swtmrID, - UINTPTR arg) -{ - SWTMR_CTRL_S *swtmr = NULL; - UINT32 intSave; - SortLinkList *sortList = NULL; - - if (interval == 0) { - return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED; - } - - if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) && - (mode != LOS_SWTMR_MODE_NO_SELFDELETE)) { - return LOS_ERRNO_SWTMR_MODE_INVALID; - } - - if (handler == NULL) { - return LOS_ERRNO_SWTMR_PTR_NULL; - } - - if (swtmrID == NULL) { - return LOS_ERRNO_SWTMR_RET_PTR_NULL; - } - - SWTMR_LOCK(intSave); - if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲链表不能为空 - SWTMR_UNLOCK(intSave); - return LOS_ERRNO_SWTMR_MAXSIZE; - } - - sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode); - swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); - LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));// - SWTMR_UNLOCK(intSave); - - swtmr->uwOwnerPid = OsCurrProcessGet()->processID;//定时器进程归属设定 - swtmr->pfnHandler = handler;//时间到了的回调函数 - swtmr->ucMode = mode; //定时器模式 - swtmr->uwOverrun = 0; - swtmr->uwInterval = interval; //周期性超时间隔 - swtmr->uwExpiry = interval; //一次性超时间隔 - swtmr->uwArg = arg; //回调函数的参数 - swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态 - SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); - *swtmrID = swtmr->usTimerID; - OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); - return LOS_OK; -} -///接口函数 启动定时器 参数定时任务ID -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) -{ - SWTMR_CTRL_S *swtmr = NULL; - UINT32 intSave; - UINT32 ret = LOS_OK; - UINT16 swtmrCBID; - - if (swtmrID >= OS_SWTMR_MAX_TIMERID) { - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 - swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 - - SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) {//ID必须一样 - SWTMR_UNLOCK(intSave); - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - switch (swtmr->ucState) {//判断定时器状态 - case OS_SWTMR_STATUS_UNUSED: - ret = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - /* 如果定时器的状态为启动中,应先停止定时器再重新启动 - * If the status of swtmr is timing, it should stop the swtmr first, - * then start the swtmr again. - */ - case OS_SWTMR_STATUS_TICKING://正在计数的定时器 - OsSwtmrStop(swtmr);//先停止定时器,注意这里没有break;,在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CREATED 接下来就是执行启动了 - /* fall-through */ - case OS_SWTMR_STATUS_CREATED://已经创建好了 - swtmr->startTime = OsGetCurrSchedTimeCycle(); - OsSwtmrStart(swtmr->startTime, swtmr); - break; - default: - ret = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; - } - - SWTMR_UNLOCK(intSave); - OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); - return ret; -} -///接口函数 停止定时器 参数定时任务ID -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) -{ - SWTMR_CTRL_S *swtmr = NULL; - UINT32 intSave; - UINT32 ret = LOS_OK; - UINT16 swtmrCBID; - - if (swtmrID >= OS_SWTMR_MAX_TIMERID) { - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 - swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 - SWTMR_LOCK(intSave); - - if (swtmr->usTimerID != swtmrID) {//ID必须一样 - SWTMR_UNLOCK(intSave); - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - switch (swtmr->ucState) {//判断定时器状态 - case OS_SWTMR_STATUS_UNUSED: - ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建 - break; - case OS_SWTMR_STATUS_CREATED: - ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始 - break; - case OS_SWTMR_STATUS_TICKING://正在计数 - OsSwtmrStop(swtmr);//执行正在停止定时器操作 - break; - default: - ret = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; - } - - SWTMR_UNLOCK(intSave); - OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); - return ret; -} -///接口函数 获得软件定时器剩余Tick数 通过 *tick 带走 -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) -{ - SWTMR_CTRL_S *swtmr = NULL; - UINT32 intSave; - UINT32 ret = LOS_OK; - UINT16 swtmrCBID; - - if (swtmrID >= OS_SWTMR_MAX_TIMERID) { - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - if (tick == NULL) { - return LOS_ERRNO_SWTMR_TICK_PTR_NULL; - } - - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 - swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 - SWTMR_LOCK(intSave); - - if (swtmr->usTimerID != swtmrID) {//ID必须一样 - SWTMR_UNLOCK(intSave); - return LOS_ERRNO_SWTMR_ID_INVALID; - } - switch (swtmr->ucState) { - case OS_SWTMR_STATUS_UNUSED: - ret = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - case OS_SWTMR_STATUS_CREATED: - ret = LOS_ERRNO_SWTMR_NOT_STARTED; - break; - case OS_SWTMR_STATUS_TICKING://正在计数的定时器 - *tick = OsSwtmrTimeGet(swtmr);//获取 - break; - default: - ret = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; - } - SWTMR_UNLOCK(intSave); - return ret; -} -///接口函数 删除定时器 -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) -{ - SWTMR_CTRL_S *swtmr = NULL; - UINT32 intSave; - UINT32 ret = LOS_OK; - UINT16 swtmrCBID; - - if (swtmrID >= OS_SWTMR_MAX_TIMERID) { - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 - swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 - SWTMR_LOCK(intSave); - - if (swtmr->usTimerID != swtmrID) {//ID必须一样 - SWTMR_UNLOCK(intSave); - return LOS_ERRNO_SWTMR_ID_INVALID; - } - - switch (swtmr->ucState) { - case OS_SWTMR_STATUS_UNUSED: - ret = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - case OS_SWTMR_STATUS_TICKING://正在计数就先停止再删除,这里没有break; - OsSwtmrStop(swtmr); - /* fall-through */ - case OS_SWTMR_STATUS_CREATED://再删除定时器 - OsSwtmrDelete(swtmr); - break; - default: - ret = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; - } - - SWTMR_UNLOCK(intSave); - OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr); - return ret; -} - -#endif /* (LOSCFG_BASE_CORE_SWTMR == YES) */ - +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*! +* @file los_swtmr.c +* @brief 软定时器主文件 +* @details +* @attention @verbatim +基本概念 + 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。 + 硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器, + 软件定时器功能,支持如下特性: + 创建软件定时器。 + 启动软件定时器。 + 停止软件定时器。 + 删除软件定时器。 + 获取软件定时器剩余Tick数。 + 可配置支持的软件定时器个数。 + + 运作机制 + 软件定时器是系统资源,在模块初始化的时候已经分配了一块连续内存。 + 软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则, + 先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先触发的准则。 + 软件定时器以Tick为基本计时单位,当创建并启动一个软件定时器时,Huawei LiteOS会根据 + 当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 + 当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时, + 若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高) + 被唤醒,在该任务中调用已经记录下来的定时器的回调函数。 + + 定时器状态 + OS_SWTMR_STATUS_UNUSED(定时器未使用) + 系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。 + + OS_SWTMR_STATUS_TICKING(定时器处于计数状态) + 在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。 + + OS_SWTMR_STATUS_CREATED(定时器创建后未启动,或已停止) + 定时器创建后,不处于计数状态时,定时器将变成该状态。 + + 软件定时器提供了三类模式: + 单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 + 周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。 + 单次触发定时器,但这类定时器超时触发后不会自动删除,需要调用定时器删除接口删除定时器。 + + 使用场景 + 创建一个单次触发的定时器,超时后执行用户自定义的回调函数。 + 创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。 + + 软件定时器的典型开发流程 + 通过make menuconfig配置软件定时器 + 创建定时器LOS_SwtmrCreate,设置定时器的定时时长、定时器模式、超时后的回调函数。 + 启动定时器LOS_SwtmrStart。 + 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。 + 停止定时器LOS_SwtmrStop。 + 删除定时器LOS_SwtmrDelete。 + + 注意事项 + 软件定时器的回调函数中不应执行过多操作,不建议使用可能引起任务挂起或者阻塞的接口或操作, + 如果使用会导致软件定时器响应不及时,造成的影响无法确定。 + 软件定时器使用了系统的一个队列和一个任务资源。软件定时器任务的优先级设定为0,且不允许修改 。 + 系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。 + 例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。 + 创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 + 软件定时器的定时精度与系统Tick时钟的周期有关。 + @endverbatim +*/ + +#include "los_swtmr_pri.h" +#include "los_init.h" +#include "los_process_pri.h" +#include "los_queue_pri.h" +#include "los_sched_pri.h" +#include "los_sortlink_pri.h" +#include "los_task_pri.h" +#include "los_hook.h" + +#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE +#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0) +#error "swtmr maxnum cannot be zero" +#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */ + +LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /**< First address in Timer memory space \n 定时器池 */ +LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /**< Pool of Swtmr Handler \n 用于注册软时钟的回调函数 */ +LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /**< Free list of Software Timer \n 空闲定时器链表 */ + +/* spinlock for swtmr module, only available on SMP mode */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);///< 初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步 +#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))///< 持有软时钟自旋锁 +#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))///< 释放软时钟自旋锁 + +/** + * @brief 软时钟的入口函数,拥有任务的最高优先级 0 级! + * + * @return LITE_OS_SEC_TEXT + */ +STATIC VOID SwtmrTask(VOID) +{ + SwtmrHandlerItemPtr swtmrHandlePtr = NULL; + SwtmrHandlerItem swtmrHandle; + UINT32 ret, swtmrHandlerQueue; + + swtmrHandlerQueue = OsSchedSwtmrHandlerQueueGet(); + for (;;) {//死循环获取队列item,一直读干净为止 + ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER);//一个一个读队列 + if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) { + swtmrHandle.handler = swtmrHandlePtr->handler;//超时中断处理函数,也称回调函数 + swtmrHandle.arg = swtmrHandlePtr->arg;//回调函数的参数 + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存 + if (swtmrHandle.handler != NULL) { + swtmrHandle.handler(swtmrHandle.arg);//回调函数处理函数 + } + } + } +} +///创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务 +STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) +{ + UINT32 ret; + TSK_INIT_PARAM_S swtmrTask; + + (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0 + swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数 + swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K默认内核任务栈 + swtmrTask.pcName = "Swt_Task";//任务名称 + swtmrTask.usTaskPrio = 0;//哇塞! 逮到一个最高优先级的任务 @note_thinking 这里应该用 OS_TASK_PRIORITY_HIGHEST 表示 + swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式 +#ifdef LOSCFG_KERNEL_SMP + swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务 +#endif + ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);//创建任务并申请调度 + if (ret == LOS_OK) { + OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是一个系统任务 + } + + return ret; +} + +BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) +{ + if (taskCB->taskEntry == (TSK_ENTRY_FUNC)SwtmrTask) { + return TRUE; + } + return FALSE; +} +///回收指定进程的软时钟 +LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID) +{ + for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器 + if (g_swtmrCBArray[index].uwOwnerPid == processID) {//找到一个 + LOS_SwtmrDelete(index);//删除定时器 + } + } +} +///软时钟初始化 ,注意函数在多CPU情况下会执行多次 +LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) +{ + UINT32 size; + UINT16 index; + UINT32 ret; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 swtmrHandlePoolSize; + UINT32 cpuid = ArchCurrCpuid(); + UINT32 swtmrTaskID, swtmrHandlerQueue; + if (cpuid == 0) {//确保以下代码块由一个CPU执行,g_swtmrCBArray和g_swtmrHandlerPool 是所有CPU共用的 + size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT;//申请软时钟内存大小 + swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */ //常驻内存 + if (swtmr == NULL) { + ret = LOS_ERRNO_SWTMR_NO_MEMORY; + goto ERROR; + } + + (VOID)memset_s(swtmr, size, 0, size);//清0 + g_swtmrCBArray = swtmr;//软时钟 + LOS_ListInit(&g_swtmrFreeList);//初始化空闲链表 + for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { + swtmr->usTimerID = index;//按顺序赋值 + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表 + } + //想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息. + swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//计算所有注册函数内存大小 + //规划一片内存区域作为软时钟处理函数的静态内存池。 + g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource *///常驻内存 + if (g_swtmrHandlerPool == NULL) { + ret = LOS_ERRNO_SWTMR_NO_MEMORY; + goto ERROR; + } + + ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem));//初始化软时钟注册池 + if (ret != LOS_OK) { + ret = LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM; + goto ERROR; + } + } + + //每个CPU都会创建一个属于自己的 OS_SWTMR_HANDLE_QUEUE_SIZE 的队列 + ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &swtmrHandlerQueue, 0, sizeof(CHAR *));//为当前CPU core 创建软时钟队列 maxMsgSize:sizeof(CHAR *) + if (ret != LOS_OK) { + ret = LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; + goto ERROR; + } + + ret = SwtmrTaskCreate(cpuid, &swtmrTaskID); + if (ret != LOS_OK) { + ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; + goto ERROR; + } + + OsSchedRunQueSwtmrInit(swtmrTaskID, swtmrHandlerQueue); + return LOS_OK; +ERROR: + PRINT_ERR("OsSwtmrInit error! ret = %u\n", ret); + return ret; +} + +/* + * Description: Start Software Timer \n 开始定时器 + * Input : swtmr --- Need to start software timer + */ +LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) +{ + UINT32 ticks; + + if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || + (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || + (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器 + ticks = swtmr->uwExpiry; //获取时间间隔 + } else { + ticks = swtmr->uwInterval;//获取周期性定时器时间间隔 + } + swtmr->ucState = OS_SWTMR_STATUS_TICKING;//计数状态 + + OsSchedAddSwtmr2TimeList(&swtmr->stSortList, swtmr->startTime, ticks);//加入链表中, 定时器任务将在tick处理函数中检查是否到期 + + OsSchedUpdateExpireTime();//更新过期时间 + return; +} + +/* + * Description: Delete Software Timer + * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL. + */ +STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) +{ + /* insert to free list */ + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用 + swtmr->ucState = OS_SWTMR_STATUS_UNUSED;//又干净着呢 + swtmr->uwOwnerPid = 0;//谁拥有这个定时器? 是 0号进程 +} + +VOID OsSwtmrWake(SchedRunQue *rq, UINT64 startTime, SortLinkList *sortList) +{ + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + + OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr); + LOS_SpinLock(&g_swtmrSpin); + SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); + if (swtmrHandler != NULL) { + swtmrHandler->handler = swtmr->pfnHandler; + swtmrHandler->arg = swtmr->uwArg; + + if (LOS_QueueWrite(rq->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) { + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler); + } + } + + if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) {//如果定时器只跑一次 + OsSwtmrDelete(swtmr);//删除定时器 + + if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { + swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; + } else { + swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; + } + } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + } else { + swtmr->uwOverrun++; + swtmr->startTime = startTime; + OsSwtmrStart(swtmr); + } + + LOS_SpinUnlock(&g_swtmrSpin); +} + +VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList) +{ + UINT32 intSave; + + SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + SWTMR_LOCK(intSave); + swtmr->startTime = startTime; + OsSwtmrStart(swtmr); + SWTMR_UNLOCK(intSave); +} + +BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) +{ + UINT32 intSave; + + SWTMR_LOCK(intSave); + BOOL find = OsSchedSwtmrTimeListFind(checkFunc, arg); + SWTMR_UNLOCK(intSave); + return find; +} + +/* + * Description: Get next timeout + * Return : Count of the Timer list + */ +LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) +{ + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &OsSchedRunQue()->swtmrSortLink) / OS_CYCLE_PER_TICK); + if (time > OS_INVALID_VALUE) { + time = OS_INVALID_VALUE; + } + return (UINT32)time; +} + +/* + * Description: Stop of Software Timer interface + * Input : swtmr --- the software timer contrl handler + */ +LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) +{ + OsSchedDeSwtmrFromTimeList(&swtmr->stSortList); + + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + swtmr->uwOverrun = 0; + + OsSchedUpdateExpireTime(); +} + +/* + * Description: Get next software timer expiretime + * Input : swtmr --- the software timer contrl handler + */ +LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) +{ + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 time = (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK); + if (time > OS_INVALID_VALUE) { + time = OS_INVALID_VALUE; + } + return (UINT32)time; +} +///创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrID, + UINTPTR arg) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + SortLinkList *sortList = NULL; + + if (interval == 0) { + return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED; + } + + if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) && + (mode != LOS_SWTMR_MODE_NO_SELFDELETE)) { + return LOS_ERRNO_SWTMR_MODE_INVALID; + } + + if (handler == NULL) { + return LOS_ERRNO_SWTMR_PTR_NULL; + } + + if (swtmrID == NULL) { + return LOS_ERRNO_SWTMR_RET_PTR_NULL; + } + + SWTMR_LOCK(intSave); + if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲链表不能为空 + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_MAXSIZE; + } + + sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode); + swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));// + SWTMR_UNLOCK(intSave); + + swtmr->uwOwnerPid = OsCurrProcessGet()->processID;//定时器进程归属设定 + swtmr->pfnHandler = handler;//时间到了的回调函数 + swtmr->ucMode = mode; //定时器模式 + swtmr->uwOverrun = 0; + swtmr->uwInterval = interval; //周期性超时间隔 + swtmr->uwExpiry = interval; //一次性超时间隔 + swtmr->uwArg = arg; //回调函数的参数 + swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态 + SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); + *swtmrID = swtmr->usTimerID; + OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); + return LOS_OK; +} +///接口函数 启动定时器 参数定时任务ID +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 + + SWTMR_LOCK(intSave); + if (swtmr->usTimerID != swtmrID) {//ID必须一样 + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) {//判断定时器状态 + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + /* 如果定时器的状态为启动中,应先停止定时器再重新启动 + * If the status of swtmr is timing, it should stop the swtmr first, + * then start the swtmr again. + */ + case OS_SWTMR_STATUS_TICKING://正在计数的定时器 + OsSwtmrStop(swtmr);//先停止定时器,注意这里没有break;,在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CREATED 接下来就是执行启动了 + /* fall-through */ + case OS_SWTMR_STATUS_CREATED://已经创建好了 + swtmr->startTime = OsGetCurrSchedTimeCycle(); + OsSwtmrStart(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); + return ret; +} +///接口函数 停止定时器 参数定时任务ID +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 + SWTMR_LOCK(intSave); + + if (swtmr->usTimerID != swtmrID) {//ID必须一样 + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) {//判断定时器状态 + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建 + break; + case OS_SWTMR_STATUS_CREATED: + ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始 + break; + case OS_SWTMR_STATUS_TICKING://正在计数 + OsSwtmrStop(swtmr);//执行正在停止定时器操作 + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); + return ret; +} +///接口函数 获得软件定时器剩余Tick数 通过 *tick 带走 +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + if (tick == NULL) { + return LOS_ERRNO_SWTMR_TICK_PTR_NULL; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 + SWTMR_LOCK(intSave); + + if (swtmr->usTimerID != swtmrID) {//ID必须一样 + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_CREATED: + ret = LOS_ERRNO_SWTMR_NOT_STARTED; + break; + case OS_SWTMR_STATUS_TICKING://正在计数的定时器 + *tick = OsSwtmrTimeGet(swtmr);//获取 + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + SWTMR_UNLOCK(intSave); + return ret; +} +///接口函数 删除定时器 +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 + SWTMR_LOCK(intSave); + + if (swtmr->usTimerID != swtmrID) {//ID必须一样 + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_TICKING://正在计数就先停止再删除,这里没有break; + OsSwtmrStop(swtmr); + /* fall-through */ + case OS_SWTMR_STATUS_CREATED://再删除定时器 + OsSwtmrDelete(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + SWTMR_UNLOCK(intSave); + OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr); + return ret; +} + +#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */ + diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 6a097a80..f14e92a5 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -173,6 +173,8 @@ VOID OsSetMainTask() for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED; g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;//128 + g_mainTask[i].processID = OS_KERNEL_PROCESS_GROUP; + g_mainTask[i].basePrio = OS_TASK_PRIORITY_HIGHEST; g_mainTask[i].priority = OS_TASK_PRIORITY_LOWEST;//31 #ifdef LOSCFG_KERNEL_SMP_LOCKDEP g_mainTask[i].lockDep.lockDepth = 0; @@ -190,15 +192,9 @@ LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) } } -//插入一个TCB到空闲链表 -STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB) +VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB) { - UINT32 taskID = taskCB->taskID; - (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB)); - taskCB->taskID = taskID; - taskCB->taskStatus = OS_TASK_STATUS_UNUSED; - taskCB->processID = OS_INVALID_VALUE; - LOS_ListAdd(&g_losFreeTask, &taskCB->pendList);//内核挂在g_losFreeTask上的任务都是由pendList完成 + LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList); } /*! @@ -226,11 +222,6 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB) /// 挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务 LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (!(processCB->processStatus & OS_PROCESS_STATUS_RUNNING)) { - return LOS_EPERM; - } - if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { return LOS_EINVAL; } @@ -249,11 +240,6 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) ///任务设置分离模式 Deatch和JOIN是一对有你没我的状态 LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);//获取进程实体 - if (!(processCB->processStatus & OS_PROCESS_STATUS_RUNNING)) {//进程必须是运行状态 - return LOS_EPERM; - } - if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join状态时 if (LOS_ListEmpty(&(taskCB->joinList))) {//joinlist中没有数据了 LOS_ListDelete(&(taskCB->joinList));//所谓删除就是自己指向自己 @@ -306,16 +292,14 @@ EXIT: ///获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理 UINT32 OsGetIdleTaskId(VOID) { - Percpu *perCpu = OsPercpuGet();//获取当前Cpu信息 - return perCpu->idleTaskID;//返回当前CPU 空闲任务ID + return OsSchedGetRunQueIdle(); } ///创建一个空闲任务 LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) { UINT32 ret; TSK_INIT_PARAM_S taskInitParam; - Percpu *perCpu = OsPercpuGet();//获取当前运行CPU信息 - UINT32 *idleTaskID = &perCpu->idleTaskID;//每个CPU都有一个空闲任务 + UINT32 idleTaskID; (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清0 taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数 @@ -326,9 +310,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) #ifdef LOSCFG_KERNEL_SMP taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的cpu上运行 #endif - ret = LOS_TaskCreateOnly(idleTaskID, &taskInitParam);//只创建任务,不调度 - LosTaskCB *idleTask = OS_TCB_FROM_TID(*idleTaskID);//获取任务实体 + ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam); + LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID); idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; //标记为系统任务,idle任务是给CPU休息用的,当然是个系统任务 + OsSchedRunQueIdleInit(idleTaskID); OsSchedSetIdleTaskSchedParam(idleTask);//设置空闲任务的调度参数 return ret; @@ -413,60 +398,88 @@ STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB) (VOID)taskCB; #endif } -/// -STATIC VOID OsTaskReleaseHoldLock(LosProcessCB *processCB, LosTaskCB *taskCB) + +STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB) { - LosMux *mux = NULL; - UINT32 ret; + UINT32 taskID = taskCB->taskID; + (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB)); + taskCB->taskID = taskID; + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + taskCB->processID = OS_INVALID_VALUE; + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); +} - while (!LOS_ListEmpty(&taskCB->lockList)) { - mux = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&taskCB->lockList), LosMux, holdList); - ret = OsMuxUnlockUnsafe(taskCB, mux, NULL); - if (ret != LOS_OK) { - LOS_ListDelete(&mux->holdList); - PRINT_ERR("mux ulock failed! : %u\n", ret); - } - } +STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack) +{ + OsTaskSyncDestroy(syncSignal); + + (VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack); +} + +STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) +{ + UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; + UINT32 intSave; + UINTPTR topOfStack; #ifdef LOSCFG_KERNEL_VM - if (processCB->processMode == OS_USER_MODE) { - OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); + if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) { + SCHEDULER_LOCK(intSave); + UINT32 mapBase = (UINTPTR)taskCB->userMapBase; + UINT32 mapSize = taskCB->userMapSize; + taskCB->userMapBase = 0; + taskCB->userArea = 0; + SCHEDULER_UNLOCK(intSave); + + LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); + LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL)); + UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize); + if ((ret != LOS_OK) && (mapBase != 0) && !OsProcessIsInit(processCB)) { + PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n", + taskCB->processID, taskCB->taskID, mapBase, mapSize, ret); + } + +#ifdef LOSCFG_KERNEL_LITEIPC + LiteIpcRemoveServiceHandle(taskCB->taskID); +#endif } #endif - OsTaskJoinPostUnsafe(taskCB); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + topOfStack = taskCB->topOfStack; + taskCB->topOfStack = 0; +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + syncSignal = taskCB->syncSignal; + taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; +#endif + OsTaskKernelResourcesToFree(syncSignal, topOfStack); - OsTaskSyncWake(taskCB); + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_KERNEL_VM + OsClearSigInfoTmpList(&(taskCB->sig)); +#endif + OsInsertTCBToFreeList(taskCB); + SCHEDULER_UNLOCK(intSave); + } + return; } -///一个任务的退出过程 -LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status) + +LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree() { + LosTaskCB *taskCB = NULL; UINT32 intSave; - LosProcessCB *runProcess = OS_PCB_FROM_PID(taskCB->processID); - LosTaskCB *mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID); - if (mainTask == taskCB) {//如果参数任务就是主任务 - OsTaskExitGroup(status);//task退出线程组 - } - SCHEDULER_LOCK(intSave); - if (runProcess->threadNumber == 1) { /* 1: The last task of the process exits *///进程的最后一个任务退出 + while (!LOS_ListEmpty(&g_taskRecycleList)) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList)); + LOS_ListDelete(&taskCB->pendList); SCHEDULER_UNLOCK(intSave); - (VOID)OsProcessExit(taskCB, status);//调用进程退出流程 - return; - } - - if ((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) || !(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { - UINT32 ret = OsTaskDeleteUnsafe(taskCB, status, intSave); - LOS_Panic("Task delete failed! ERROR : 0x%x\n", ret); - return; - } - OsTaskReleaseHoldLock(runProcess, taskCB); + OsTaskResourcesToFree(taskCB); - OsSchedResched();//申请调度 + SCHEDULER_LOCK(intSave); + } SCHEDULER_UNLOCK(intSave); - return; } /* @@ -494,13 +507,12 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) taskCB->joinRetval = 0;//结合数为0 } - OsTaskToExit(taskCB, 0);//到这里任务跑完了要退出了 + OsRunningTaskToExit(taskCB, 0); } ///任务创建参数检查 LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam, VOID **pool) { - LosProcessCB *process = NULL; UINT32 poolSize = OS_SYS_MEM_SIZE; *pool = (VOID *)m_aucSysMem1;//默认使用 @@ -512,11 +524,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID, return LOS_ERRNO_TSK_PTR_NULL; } - process = OS_PCB_FROM_PID(initParam->processID); - if (process->processMode > OS_USER_MODE) { - return LOS_ERRNO_TSK_ID_INVALID; - } - + LosProcessCB *process = OS_PCB_FROM_PID(initParam->processID); if (!OsProcessIsUserMode(process)) { if (initParam->pcName == NULL) { return LOS_ERRNO_TSK_NAME_EMPTY; @@ -552,81 +560,6 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskStackAlloc(VOID **topStack, UINT32 stack *topStack = (VOID *)LOS_MemAllocAlign(pool, stackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); } -//释放任务内核资源 -STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack) -{ - VOID *poolTmp = (VOID *)m_aucSysMem1; - - OsTaskSyncDestroy(syncSignal); - - (VOID)LOS_MemFree(poolTmp, (VOID *)topOfStack); -} -///从回收链表中回收任务到空闲链表 -LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree() -{ - LosTaskCB *taskCB = NULL; - UINT32 intSave; - - SCHEDULER_LOCK(intSave); - while (!LOS_ListEmpty(&g_taskRecycleList)) {//不空就一个一个回收任务 - taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));//取出第一个待回收任务 - LOS_ListDelete(&taskCB->pendList);//从回收链表上将自己摘除 - SCHEDULER_UNLOCK(intSave); - - OsTaskResourcesToFree(taskCB);//释放任务资源 - - SCHEDULER_LOCK(intSave); - } - SCHEDULER_UNLOCK(intSave); -} - -LITE_OS_SEC_TEXT VOID OsTaskResourcesToFree(LosTaskCB *taskCB) -{ - UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; - UINT32 intSave; - UINTPTR topOfStack; - -#ifdef LOSCFG_KERNEL_VM - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (OsProcessIsUserMode(processCB) && (taskCB->userMapBase != 0)) { - SCHEDULER_LOCK(intSave); - UINT32 mapBase = (UINTPTR)taskCB->userMapBase; - UINT32 mapSize = taskCB->userMapSize; - taskCB->userMapBase = 0; - taskCB->userArea = 0; - SCHEDULER_UNLOCK(intSave); - - LOS_ASSERT(!(processCB->vmSpace == NULL)); - UINT32 ret = OsUnMMap(processCB->vmSpace, (UINTPTR)mapBase, mapSize); - if ((ret != LOS_OK) && (mapBase != 0) && !(processCB->processStatus & OS_PROCESS_STATUS_INIT)) { - PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n", - processCB->processID, taskCB->taskID, mapBase, mapSize, ret); - } - -#ifdef LOSCFG_KERNEL_LITEIPC - LiteIpcRemoveServiceHandle(taskCB->taskID); -#endif - } -#endif - - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { - topOfStack = taskCB->topOfStack; - taskCB->topOfStack = 0; -#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC - syncSignal = taskCB->syncSignal; - taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; -#endif - OsTaskKernelResourcesToFree(syncSignal, topOfStack); - - SCHEDULER_LOCK(intSave); -#ifdef LOSCFG_KERNEL_VM - OsClearSigInfoTmpList(&(taskCB->sig)); -#endif - OsInsertTCBToFreeList(taskCB); - SCHEDULER_UNLOCK(intSave); - } - return; -} ///任务基本信息的初始化 LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, const VOID *stackPtr, @@ -656,7 +589,6 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, LOS_ListInit(&taskCB->joinList); } - taskCB->futex.index = OS_INVALID_VALUE; LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表 SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); } @@ -664,36 +596,23 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, const VOID *stackPtr, const VOID *topStack) { - UINT32 intSave; UINT32 ret; UINT32 numCount; - UINT16 mode; - LosProcessCB *processCB = NULL; OsTaskCBInitBase(taskCB, stackPtr, topStack, initParam);//初始化任务的基本信息, //taskCB->stackPointer指向内核态栈 sp位置,该位置存着 任务初始上下文 - SCHEDULER_LOCK(intSave); - processCB = OS_PCB_FROM_PID(initParam->processID);//通过ID获取PCB ,单核进程数最多64个 - taskCB->processID = processCB->processID;//进程-线程的父子关系绑定 - mode = processCB->processMode;//模式方式同步process - LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));//挂入进程的线程链表 - if (mode == OS_USER_MODE) {//任务支持用户态时,将改写 taskCB->stackPointer = initParam->userParam.userSP + numCount = OsProcessAddNewTask(initParam->processID, taskCB); +#ifdef LOSCFG_KERNEL_VM + taskCB->futex.index = OS_INVALID_VALUE; + if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { taskCB->userArea = initParam->userParam.userArea; taskCB->userMapBase = initParam->userParam.userMapBase; taskCB->userMapSize = initParam->userParam.userMapSize; OsUserTaskStackInit(taskCB->stackPointer, (UINTPTR)taskCB->taskEntry, initParam->userParam.userSP);//初始化用户态任务栈 //这里要注意,任务的上下文是始终保存在内核栈空间,而用户态时运行在用户态栈空间.(context->SP = userSP 指向了用户态栈空间) } - - if (!processCB->threadNumber) {//进程线程数量为0时, - processCB->threadGroupID = taskCB->taskID;//任务为线程组 组长 - } - processCB->threadNumber++;//这里说明 线程和TASK是一个意思 threadNumber代表活动线程数,thread消亡的时候会 threadNumber-- - - numCount = processCB->threadCount;//代表总线程数,包括销毁的,只要存在过的都算,这个值也就是在这里用下, - processCB->threadCount++;//线程总数++,注意这个数会一直累加的,哪怕thread最后退出了,这个统计这个进程曾经存在过的线程数量 - SCHEDULER_UNLOCK(intSave); +#endif if (initParam->pcName != NULL) { ret = (UINT32)OsSetTaskName(taskCB, initParam->pcName, FALSE); @@ -797,7 +716,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in { UINT32 ret; UINT32 intSave; - LosTaskCB *taskCB = NULL; if (initParam == NULL) { return LOS_ERRNO_TSK_PTR_NULL; @@ -817,7 +735,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in if (ret != LOS_OK) { return ret; } - taskCB = OS_TCB_FROM_TID(*taskID); + + LosTaskCB *taskCB = OS_TCB_FROM_TID(*taskID); SCHEDULER_LOCK(intSave); OsSchedTaskEnQueue(taskCB); @@ -962,104 +881,79 @@ STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB) OS_MEM_CLEAR(taskCB->taskID); } -//删除一个正在运行的任务 -LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *runTask) +STATIC VOID OsTaskReleaseHoldLock(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID);//拿到task所属进程 - OsTaskReleaseHoldLock(processCB, runTask);//task还锁 - OsTaskStatusUnusedSet(runTask);//task重置为未使用状态,等待回收 + LosMux *mux = NULL; + UINT32 ret; - LOS_ListDelete(&runTask->threadList);//从进程的线程链表中将自己摘除 - processCB->threadNumber--;//进程的活动task --,注意进程还有一个记录总task的变量 processCB->threadCount - LOS_ListTailInsert(&g_taskRecycleList, &runTask->pendList);//将task插入回收链表,等待回收资源再利用 - OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL);//发送释放资源的事件,事件由 OsResourceRecoveryTask 消费 + while (!LOS_ListEmpty(&taskCB->lockList)) { + mux = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&taskCB->lockList), LosMux, holdList); + ret = OsMuxUnlockUnsafe(taskCB, mux, NULL); + if (ret != LOS_OK) { + LOS_ListDelete(&mux->holdList); + PRINT_ERR("mux ulock failed! : %u\n", ret); + } + } - OsSchedResched();//申请调度 - return; +#ifdef LOSCFG_KERNEL_VM + if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { + OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); + } +#endif + + OsTaskJoinPostUnsafe(taskCB); + + OsTaskSyncWake(taskCB); } -/** - * @brief 获取参数位图中最高位为1的索引位 例如: 00110110 返回 5 - * @verbatim - CLZ 用于计算操作数最高端0的个数,这条指令主要用于以下两个场合 -   1.计算操作数规范化(使其最高位为1)时需要左移的位数 -   2.确定一个优先级掩码中最高优先级 - * @endverbatim - * @param bitmap - * @return UINT16 - */ -/* - * Check if needs to do the delete operation on the running task. - * Return TRUE, if needs to do the deletion. - * Rerturn FALSE, if meets following circumstances: - * 1. Do the deletion across cores, if SMP is enabled - * 2. Do the deletion when preemption is disabled - * 3. Do the deletion in hard-irq - * then LOS_TaskDelete will directly return with 'ret' value. - */ -/** - * @brief - * @verbatim - 检查是否需要对正在运行的任务执行删除操作,如果需要删除,则返回TRUE。 - 如果满足以下情况,则返回FALSE: - 1.如果启用了SMP,则跨CPU执行删除 - 2.禁用抢占时执行删除 - 3.在硬irq中删除 - 然后LOS_TaskDelete将直接返回ret值 - * @endverbatim - * @param taskCB - * @param ret - * @return STATIC - */ -STATIC BOOL OsRunTaskToDeleteCheckOnRun(LosTaskCB *taskCB, UINT32 *ret) +LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status) { - /* init default out return value */ - *ret = LOS_OK; + UINT32 intSave; -#ifdef LOSCFG_KERNEL_SMP - /* ASYNCHRONIZED. No need to do task lock checking *///异步操作,不需要进行任务锁检查 - if (taskCB->currCpu != ArchCurrCpuid()) {//任务运行在其他CPU,跨核心执行删除 - /* - * the task is running on another cpu. - * mask the target task with "kill" signal, and trigger mp schedule - * which might not be essential but the deletion could more in time. - */ - taskCB->signal = SIGNAL_KILL; //贴上干掉标记 - LOS_MpSchedule(taskCB->currCpu);//通知任务所属CPU发生调度 - *ret = OsTaskSyncWait(taskCB); //同步等待可怜的任务被干掉 - return FALSE; + if (OsProcessThreadGroupIDGet(runTask) == runTask->taskID) { + OsProcessThreadGroupDestroy(); } -#endif - if (!OsPreemptableInSched()) {//如果任务正在运行且调度程序已锁定,则无法删除它 - /* If the task is running and scheduler is locked then you can not delete it */ - *ret = LOS_ERRNO_TSK_DELETE_LOCKED; - return FALSE; - } + OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, runTask); - if (OS_INT_ACTIVE) {//硬中断进行中...会屏蔽掉所有信号,当然包括kill了 - /* - * delete running task in interrupt. - * mask "kill" signal and later deletion will be handled. - */ - taskCB->signal = SIGNAL_KILL;//硬中断后将处理删除。 - return FALSE; + SCHEDULER_LOCK(intSave); + if (OsProcessThreadNumberGet(runTask) == 1) { /* 1: The last task of the process exits */ + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(runTask); + OsProcessResourcesToFree(OS_PCB_FROM_PID(runTask->processID)); + + SCHEDULER_LOCK(intSave); + + OsProcessNaturalExit(OS_PCB_FROM_PID(runTask->processID), status); + OsTaskReleaseHoldLock(runTask); + OsTaskStatusUnusedSet(runTask); + } else if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + OsTaskReleaseHoldLock(runTask); + } else { + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(runTask); + + SCHEDULER_LOCK(intSave); + OsInactiveTaskDelete(runTask); + OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); } - return TRUE; + OsSchedResched(); + SCHEDULER_UNLOCK(intSave); + return; } -///删除不活动的任务 !OS_TASK_STATUS_RUNNING -STATIC VOID OsTaskDeleteInactive(LosProcessCB *processCB, LosTaskCB *taskCB) + +LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB) { - LosMux *mux = (LosMux *)taskCB->taskMux; //任务 UINT16 taskStatus = taskCB->taskStatus; - LOS_ASSERT(!(taskStatus & OS_TASK_STATUS_RUNNING)); - - OsTaskReleaseHoldLock(processCB, taskCB); + OsTaskReleaseHoldLock(taskCB); OsSchedTaskExit(taskCB); if (taskStatus & OS_TASK_STATUS_PENDING) { + LosMux *mux = (LosMux *)taskCB->taskMux; if (LOS_MuxIsValid(mux) == TRUE) { OsMuxBitmapRestore(mux, taskCB, (LosTaskCB *)mux->owner); } @@ -1067,58 +961,15 @@ STATIC VOID OsTaskDeleteInactive(LosProcessCB *processCB, LosTaskCB *taskCB) OsTaskStatusUnusedSet(taskCB); - LOS_ListDelete(&taskCB->threadList); - processCB->threadNumber--; - LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList); - return; -} -///以不安全的方式删除参数任务 -LITE_OS_SEC_TEXT UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave) -{ - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);//获取进程实体 - UINT32 mode = processCB->processMode; - UINT32 errRet = LOS_OK; + OsDeleteTaskFromProcess(taskCB); - if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//系统任务是不能被删除的, 请您说出3个系统任务. - errRet = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; - goto EXIT; - } - - if ((taskCB->taskStatus & OS_TASK_STATUS_RUNNING) && !OsRunTaskToDeleteCheckOnRun(taskCB, &errRet)) {//正在运行且检测正在运行不能删除的情况 - goto EXIT; - } - - if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {//任务不在活动 - OsTaskDeleteInactive(processCB, taskCB);//删除未活动的任务 - SCHEDULER_UNLOCK(intSave);//释放自旋锁,这就是不安全的标记,函数内部并没有拿自旋锁 - OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE);//写一个资源释放事件,资源回收任务会收到事件,并回收任务的资源. - return errRet;//消费OS_RESOURCE_EVENT_FREE事件可见于 OsResourceRecoveryTask 的处理 - } OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB); - if (mode == OS_USER_MODE) { //用户态模式 - SCHEDULER_UNLOCK(intSave);//先释放锁 - OsTaskResourcesToFree(taskCB);//释放任务资源 - SCHEDULER_LOCK(intSave); - } - -#ifdef LOSCFG_KERNEL_SMP - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 1); -#else - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0); -#endif - OsRunTaskToDelete(taskCB);//删除一个正在运行的任务 - -EXIT: - SCHEDULER_UNLOCK(intSave); - return errRet; } -///删除指定的任务,回归任务池 + LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) { UINT32 intSave; - UINT32 ret; - LosTaskCB *taskCB = NULL; - LosProcessCB *processCB = NULL; + UINT32 ret = LOS_OK; if (OS_TID_CHECK_INVALID(taskID)) { return LOS_ERRNO_TSK_ID_INVALID; @@ -1128,31 +979,33 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) return LOS_ERRNO_TSK_YIELD_IN_INT; } - taskCB = OS_TCB_FROM_TID(taskID); - SCHEDULER_LOCK(intSave); - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { - ret = LOS_ERRNO_TSK_NOT_CREATED; - OS_GOTO_ERREND(); + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB == OsCurrTaskGet()) { + OsRunningTaskToExit(taskCB, OS_PRO_EXIT_OK); + return LOS_NOK; } - if (taskCB->taskStatus & (OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) { - SCHEDULER_UNLOCK(intSave); - OsBackTrace(); - return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; - } - processCB = OS_PCB_FROM_PID(taskCB->processID); - if (processCB->threadNumber == 1) {//此任务为进程的最后一个任务的处理 - if (processCB == OsCurrProcessGet()) {//是否为当前任务 - SCHEDULER_UNLOCK(intSave); - OsProcessExit(taskCB, OS_PRO_EXIT_OK);//进程退出 - return LOS_OK; + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + ret = LOS_ERRNO_TSK_NOT_CREATED; + } else { + ret = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; } + OS_GOTO_ERREND(); + } - ret = LOS_ERRNO_TSK_ID_INVALID; +#ifdef LOSCFG_KERNEL_SMP + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + ret = OsTaskSyncWait(taskCB); OS_GOTO_ERREND(); } +#endif - return OsTaskDeleteUnsafe(taskCB, OS_PRO_EXIT_OK, intSave);//任务以非安全模式删除 + OsInactiveTaskDelete(taskCB); + OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); LOS_ERREND: SCHEDULER_UNLOCK(intSave); @@ -1282,15 +1135,22 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID) UINT32 intSave; intSave = LOS_IntLock(); - OsCpuSchedLock(OsPercpuGet()); + OsSchedLock(); LOS_IntRestore(intSave); } LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) { - OsCpuSchedUnlock(OsPercpuGet(), LOS_IntLock()); -} + UINT32 intSave; + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + + if (needSched) { + LOS_Schedule(); + } +} //获取任务信息,给shell使用的 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) { @@ -1432,12 +1292,12 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) */ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) { - UINT32 intSave, ret; + UINT32 ret; //私有且不可中断,无需保护。这个任务在其他CPU核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号 /* * private and uninterruptable, no protection needed. * while this task is always running when others cores see it, - * so it keeps recieving signals while follow code excuting. + * so it keeps receiving signals while follow code executing. */ LosTaskCB *runTask = OsCurrTaskGet(); if (runTask->signal == SIGNAL_NONE) { @@ -1449,10 +1309,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) * clear the signal, and do the task deletion. if the signaled task has been * scheduled out, then this deletion will wait until next run. *///如果发出信号的任务已出调度就绪队列,则此删除将等待下次运行 - SCHEDULER_LOCK(intSave); runTask->signal = SIGNAL_NONE;//清除信号, - ret = OsTaskDeleteUnsafe(runTask, OS_PRO_EXIT_OK, intSave);//任务的自杀行动,这可是正在运行的任务. - if (ret) { + ret = LOS_TaskDelete(runTask->taskID); + if (ret != LOS_OK) { PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret); } } else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号 @@ -1474,7 +1333,6 @@ LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL s { UINT32 intSave; errno_t err; - LosProcessCB *processCB = NULL; const CHAR *namePtr = NULL; CHAR nameBuff[OS_TCB_NAME_LEN] = { 0 }; @@ -1501,10 +1359,9 @@ LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL s } err = LOS_OK; - processCB = OS_PCB_FROM_PID(taskCB->processID); /* if thread is main thread, then set processName as taskName */ - if ((taskCB->taskID == processCB->threadGroupID) && (setPName == TRUE)) { - err = (INT32)OsSetProcessName(processCB, (const CHAR *)taskCB->taskName); + if ((taskCB->taskID == OsProcessThreadGroupIDGet(taskCB)) && (setPName == TRUE)) { + err = (INT32)OsSetProcessName(OS_PCB_FROM_PID(taskCB->processID), (const CHAR *)taskCB->taskName); if (err != LOS_OK) { err = EINVAL; } @@ -1514,85 +1371,6 @@ EXIT: SCHEDULER_UNLOCK(intSave); return err; } -/// //退群并发起kill信号 -STATIC VOID OsExitGroupActiveTaskKilled(LosProcessCB *processCB, LosTaskCB *taskCB) -{ - INT32 ret; - - taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL; -#ifdef LOSCFG_KERNEL_SMP - /* The other core that the thread is running on and is currently running in a non-system call */ - if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - taskCB->signal = SIGNAL_KILL; - LOS_MpSchedule(taskCB->currCpu); - } else -#endif -#ifdef LOSCFG_KERNEL_VM - { - ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL); - if (ret != LOS_OK) { - PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n", - taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret); - } - } -#endif - - if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { - taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; - LOS_ListInit(&taskCB->joinList); - } - - ret = OsTaskJoinPendUnsafe(taskCB); - if (ret != LOS_OK) { - PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n", - taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret); - } -} -///1.当前进程中的任务集体退群, 2.当前进程贴上退出标签 -LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) -{ - UINT32 intSave; - - LosProcessCB *processCB = OsCurrProcessGet(); - LosTaskCB *currTask = OsCurrTaskGet(); - SCHEDULER_LOCK(intSave);//调度自旋锁,这块锁的代码有点多,容易出问题!出问题也不好复现,希望鸿蒙有充分测试这块的功能. @note_thinking - if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) { - SCHEDULER_UNLOCK(intSave); - return; - } - - processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//贴上进程要退出的标签 - processCB->threadGroupID = currTask->taskID; - - LOS_DL_LIST *list = &processCB->threadSiblingList;//获取进程的任务链表遍历 - LOS_DL_LIST *head = list; - do { - LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); - if ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT) || - ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) && - !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - OsTaskDeleteInactive(processCB, taskCB);//先删除不活动的任务 - } else { - if (taskCB != currTask) {//非当前任务 - OsExitGroupActiveTaskKilled(processCB, taskCB);//退群并发起kill信号 - } else { - /* Skip the current task | 跳过当前任务 */ - list = list->pstNext; - } - } - } while (head != list->pstNext);//遍历链表 - - SCHEDULER_UNLOCK(intSave);//释放锁 - - LOS_ASSERT(processCB->threadNumber == 1);//这一趟下来,进程只有一个正在活动的任务 - return; -} -///任务退群并销毁,进入任务的回收链表之后再进入空闲链表,等着再次被分配使用. -LITE_OS_SEC_TEXT VOID OsExecDestroyTaskGroup(VOID) -{ - OsTaskExitGroup(OS_PRO_EXIT_OK);//任务退出 - OsTaskCBRecycleToFree(); -} UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB) { @@ -1650,7 +1428,6 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, ///创建一个用户态任务 LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam) { - LosProcessCB *processCB = NULL; UINT32 taskID; UINT32 ret; UINT32 intSave; @@ -1665,15 +1442,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式 if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理 SCHEDULER_LOCK(intSave); - processCB = OsCurrProcessGet();//拿当前运行的进程 + LosProcessCB *processCB = OsCurrProcessGet(); initParam->processID = processCB->processID;//进程ID赋值 initParam->consoleID = processCB->consoleID;//任务控制台ID归属 SCHEDULER_UNLOCK(intSave); } else {//进程已经创建 - processCB = OS_PCB_FROM_PID(processID);//通过ID拿到进程PCB - if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {//进程未初始化和未正在运行时 - return OS_INVALID_VALUE;//@note_why 为什么这两种情况下会创建任务失败 - } initParam->processID = processID;//进程ID赋值 initParam->consoleID = 0;//默认0号控制台 } diff --git a/kernel/base/include/los_percpu_pri.h b/kernel/base/include/los_percpu_pri.h index ee89fb3b..adecbf57 100644 --- a/kernel/base/include/los_percpu_pri.h +++ b/kernel/base/include/los_percpu_pri.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -34,8 +34,6 @@ #include "los_base.h" #include "los_hw_cpu.h" -#include "los_spinlock.h" -#include "los_sortlink_pri.h" #ifdef __cplusplus #if __cplusplus @@ -44,38 +42,16 @@ extern "C" { #endif /* __cplusplus */ #ifdef LOSCFG_KERNEL_SMP -/*! \enum - -*/ typedef enum { CPU_RUNNING = 0, ///< cpu is running | CPU正在运行状态 CPU_HALT, ///< cpu in the halt | CPU处于暂停状态 CPU_EXC ///< cpu in the exc | CPU处于异常状态 } ExcFlag; -#endif -/*! \struct 内核对cpu的描述, per-CPU变量是linux系统一个非常有趣的特性,它为系统中的每个处理器都分配了该变量的副本。 - * 这样做的好处是,在多处理器系统中,当处理器操作属于它的变量副本时,不需要考虑与其他处理器的竞争的问题, - */ typedef struct { - SortLinkAttribute taskSortLink; /*! task sort link | 挂等待和延时的任务,这些任务从任务就绪队列中来,等待最后CPU执行 */ - SPIN_LOCK_S taskSortLinkSpin; ///< task sort link spin lock | 操作taskSortLink链表的自旋锁 - SortLinkAttribute swtmrSortLink; ///< swtmr sort link | 挂还没到时间的定时器 - SPIN_LOCK_S swtmrSortLinkSpin; ///< swtmr sort link spin lock |* 操作swtmrSortLink链表的自旋锁 - UINT64 responseTime; ///< Response time for current nuclear Tick interrupts | 当前CPU核 Tick 中断的响应时间 - UINT64 tickStartTime; ///< The time when the tick interrupt starts processing | 开始处理tick中断的时间 - UINT32 responseID; ///< The response ID of the current nuclear TICK interrupt | 当前CPU核TICK中断的响应任务ID - UINTPTR runProcess; ///< The address of the process control block pointer to which the current kernel is running | 当前进程控制块地址 - UINT32 idleTaskID; ///< idle task id | 每个CPU都有一个空闲任务 见于 OsIdleTaskCreate - UINT32 taskLockCnt; ///< task lock flag | 任务锁的数量,当 > 0 的时候,需要重新调度了 - UINT32 swtmrHandlerQueue; ///< software timer timeout queue id | 软时钟超时队列句柄 - UINT32 swtmrTaskID; ///< software timer task id | 软时钟任务ID - UINT32 schedFlag; ///< pending scheduler flag | 调度标识 INT_NO_RESCH INT_PEND_RESCH -#ifdef LOSCFG_KERNEL_SMP - UINT32 excFlag; ///< cpu halt or exc flag | cpu 停止或 异常 标志 + UINT32 excFlag; /* cpu halt or exc flag */ #ifdef LOSCFG_KERNEL_SMP_CALL - LOS_DL_LIST funcLink; ///< mp function call link | 回调函数链表,由 LOS_MP_IPI_FUNC_CALL 触发 -#endif + LOS_DL_LIST funcLink; /* mp function call link */ #endif } Percpu; @@ -92,6 +68,19 @@ STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid) return &g_percpu[cpuid]; } +STATIC INLINE UINT32 OsCpuStatusIsHalt(UINT16 cpuid) +{ + return (OsPercpuGetByID(cpuid)->excFlag == CPU_HALT); +} + +STATIC INLINE VOID OsCpuStatusSet(ExcFlag flag) +{ + OsPercpuGet()->excFlag = flag; +} + +VOID OsAllCpuStatusOutput(VOID); +#endif + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index a6f6cb29..681c1106 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -84,10 +84,8 @@ typedef struct ProcessCB { UINT32 processID; /**< Process ID = leader thread ID | 进程ID,由进程池分配,范围[0,64] */ UINT16 processStatus; /**< [15:4] Process Status; [3:0] The number of threads currently running in the process | 这里设计很巧妙.用一个变量表示了两层逻辑 数量和状态,点赞! @note_good 从这里也可以看出一个进程可以有多个正在运行的任务*/ - UINT16 priority; /**< Process priority | 进程优先级*/ UINT16 consoleID; /**< The console id of task belongs | 任务的控制台id归属 */ UINT16 processMode; /**< Kernel Mode:0; User Mode:1; | 模式指定为内核还是用户进程 */ - UINT16 readyTaskNum; /**< The number of ready tasks in the current process */ UINT32 parentProcessID; /**< Parent process ID | 父进程ID*/ UINT32 exitCode; /**< Process exit status | 进程退出状态码*/ LOS_DL_LIST pendList; /**< Block list to which the process belongs | 进程所在的阻塞列表,进程因阻塞挂入相应的链表.*/ @@ -154,7 +152,7 @@ typedef struct ProcessCB { * * The process is created but does not participate in scheduling. */ -#define OS_PROCESS_STATUS_INIT 0x0010U ///< 进程初始状态 +#define OS_PROCESS_STATUS_INIT OS_TASK_STATUS_INIT /** * @ingroup los_process @@ -162,7 +160,7 @@ typedef struct ProcessCB { * * The process is ready. */ -#define OS_PROCESS_STATUS_READY 0x0020U ///< 进程就绪状态 +#define OS_PROCESS_STATUS_READY OS_TASK_STATUS_READY /** * @ingroup los_process @@ -170,7 +168,7 @@ typedef struct ProcessCB { * * The process is running. */ -#define OS_PROCESS_STATUS_RUNNING 0x0040U ///< 进程状态: 运行中... +#define OS_PROCESS_STATUS_RUNNING OS_TASK_STATUS_RUNNING /** * @ingroup los_process @@ -178,7 +176,7 @@ typedef struct ProcessCB { * * The process is pending */ -#define OS_PROCESS_STATUS_PENDING 0x0080U ///< 进程状态: 挂起中... ,意思是进程还没开始,在等待其他条件成熟 +#define OS_PROCESS_STATUS_PENDING (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_SUSPENDED) /** * @ingroup los_process @@ -186,23 +184,7 @@ typedef struct ProcessCB { * * The process is run out but the resources occupied by the process are not recovered. */ -#define OS_PROCESS_STATUS_ZOMBIES 0x100U ///< 进程状态: 僵死 - -/** - * @ingroup los_process - * Flag that indicates the process or process control block status. - * - * The number of task currently running under the process, it only works with multiple cores. - */ -#define OS_PROCESS_RUNTASK_COUNT_MASK 0x000FU ///< 进程处于运行状态的数量掩码 -//进程当前运行的任务数,它只适用于多个内核,这里注意 一个进程的多个任务是可以同时给多个内核运行的. -/** - * @ingroup los_process - * Flag that indicates the process or process control block status. - * - * The process status mask. - */ -#define OS_PROCESS_STATUS_MASK 0xFFF0U ///< 进程状态掩码 +#define OS_PROCESS_STATUS_ZOMBIES 0x0100U ///< 进程状态: 僵死 /** * @ingroup los_process @@ -272,6 +254,11 @@ STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程 return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_ZOMBIES)) != 0); } +STATIC INLINE BOOL OsProcessIsInit(const LosProcessCB *processCB) +{ + return (processCB->processStatus & OS_PROCESS_STATUS_INIT); +} + /** * @ingroup los_process * The highest priority of a kernel mode process. @@ -302,16 +289,6 @@ STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程 */ #define OS_PROCESS_USERINIT_PRIORITY 28 ///< 用户进程默认的优先级,28级好低啊 -#define OS_GET_PROCESS_STATUS(status) ((UINT16)((UINT16)(status) & OS_PROCESS_STATUS_MASK)) -/// 获取进程处于运行中的任务数量 -#define OS_PROCESS_GET_RUNTASK_COUNT(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_RUNTASK_COUNT_MASK)) -/// 进程运行中的任务数量加1 -#define OS_PROCESS_RUNTASK_COUNT_ADD(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_STATUS_MASK) | \ - ((OS_PROCESS_GET_RUNTASK_COUNT(status) + 1) & OS_PROCESS_RUNTASK_COUNT_MASK)) -/// 进程运行中的任务数量减1 -#define OS_PROCESS_RUNTASK_COUNT_DEC(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_STATUS_MASK) | \ - ((OS_PROCESS_GET_RUNTASK_COUNT(status) - 1) & OS_PROCESS_RUNTASK_COUNT_MASK)) - #define OS_TASK_DEFAULT_STACK_SIZE 0x2000 ///< task默认栈大小 8K #define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000 ///< 用户通过系统调用的栈大小 12K ,这时是运行在内核模式下 #define OS_USER_TASK_STACK_SIZE 0x100000 ///< 用户任务运行在用户空间的栈大小 1M @@ -383,15 +360,10 @@ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID) UINT32 intSave; intSave = LOS_IntLock(); - LosProcessCB *runProcess = (LosProcessCB *)OsPercpuGet()->runProcess;//当前CPU正在运行的进程 + LosProcessCB *runProcess = OS_PCB_FROM_PID(OsCurrTaskGet()->processID); LOS_IntRestore(intSave); return runProcess; } -/// 设置当前进程 -STATIC INLINE VOID OsCurrProcessSet(const LosProcessCB *process) -{ - OsPercpuGet()->runProcess = (UINTPTR)process; -} #ifdef LOSCFG_SECURITY_CAPABILITY /*! 获取当前进程的所属用户 */ @@ -405,8 +377,44 @@ STATIC INLINE User *OsCurrUserGet(VOID) LOS_IntRestore(intSave); return user; } + +STATIC INLINE UINT32 OsProcessUserIDGet(const LosTaskCB *taskCB) +{ + UINT32 intSave = LOS_IntLock(); + UINT32 uid = OS_INVALID; + + LosProcessCB *process = OS_PCB_FROM_PID(taskCB->processID); + if (process->user != NULL) { + uid = process->user->userID; + } + LOS_IntRestore(intSave); + return uid; +} +#endif + +STATIC INLINE UINT32 OsProcessThreadGroupIDGet(const LosTaskCB *taskCB) +{ + return OS_PCB_FROM_PID(taskCB->processID)->threadGroupID; +} + +STATIC INLINE UINT32 OsProcessThreadNumberGet(const LosTaskCB *taskCB) +{ + return OS_PCB_FROM_PID(taskCB->processID)->threadNumber; +} + +#ifdef LOSCFG_KERNEL_VM +STATIC INLINE LosVmSpace *OsProcessVmSpaceGet(const LosProcessCB *processCB) +{ + return processCB->vmSpace; +} #endif +#ifdef LOSCFG_DRIVERS_TZDRIVER +STATIC INLINE struct Vnode *OsProcessExecVnodeGet(const LosProcessCB *processCB) +{ + return processCB->execVnode; +} +#endif /* * return immediately if no child has exited. */ @@ -465,15 +473,14 @@ extern UINTPTR __user_init_bss; ///< 查看 LITE_USER_SEC_BSS ,赋值由liteos extern UINTPTR __user_init_end; ///< init 进程的用户空间初始化结束地址 extern UINTPTR __user_init_load_addr;///< init进程的加载地址 extern UINT32 OsSystemProcessCreate(VOID); +extern VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status); extern VOID OsProcessCBRecycleToFree(VOID); extern VOID OsProcessResourcesToFree(LosProcessCB *processCB); -extern VOID OsProcessExit(LosTaskCB *runTask, INT32 status); extern UINT32 OsUserInitProcess(VOID); -extern VOID OsTaskSchedQueueDequeue(LosTaskCB *taskCB, UINT16 status); -extern VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 status); extern INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size); -extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, - LosVmSpace *oldAspace, UINTPTR oldFiles); +extern VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace); +extern LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD); +extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldAspace, UINTPTR oldFiles); extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize); extern UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name); extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy); @@ -488,6 +495,9 @@ extern UINTPTR OsGetSigHandler(VOID); extern VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID); extern INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission); extern INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission); +extern UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB); +extern VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB); +extern VOID OsProcessThreadGroupDestroy(VOID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index ce662d98..e0acd8d8 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -32,12 +32,22 @@ #ifndef _LOS_SCHED_PRI_H #define _LOS_SCHED_PRI_H -#include "los_percpu_pri.h" -#include "los_task_pri.h" +#include "los_sortlink_pri.h" #include "los_sys_pri.h" -#include "los_process_pri.h" #include "los_hwi.h" #include "hal_timer.h" +#ifdef LOSCFG_SCHED_DEBUG +#include "los_stat_pri.h" +#endif +#include "los_stackinfo_pri.h" +#include "los_futex_pri.h" +#include "los_signal.h" +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#ifdef LOSCFG_KERNEL_LITEIPC +#include "hm_liteipc.h" +#endif #ifdef __cplusplus #if __cplusplus @@ -50,170 +60,478 @@ extern "C" { #define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(((UINT64)-1) - 1U) extern UINT32 g_taskScheduled; -typedef BOOL (*SchedScan)(VOID); +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) +#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK) +typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR); //获取当前调度经历了多少个时间周期 STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) { return HalClockGetCycles(); } -/// 更新中断使用时间 -STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID) +typedef enum { + INT_NO_RESCH = 0x0, /* no needs to schedule */ + INT_PEND_RESCH = 0x1, /* pending schedule flag */ + INT_PEND_TICK = 0x2, /* pending tick */ +} SchedFlag; + +typedef struct { + SortLinkAttribute taskSortLink; /* task sort link */ + SortLinkAttribute swtmrSortLink; /* swtmr sort link */ + UINT64 responseTime; /* Response time for current CPU tick interrupts */ + UINT32 responseID; /* The response ID of the current CPU tick interrupt */ + UINT32 idleTaskID; /* idle task id */ + UINT32 taskLockCnt; /* task lock flag */ + UINT32 swtmrTaskID; /* software timer task id */ + UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ + UINT32 schedFlag; /* pending scheduler flag */ +} SchedRunQue; + +extern SchedRunQue g_schedRunQue[LOSCFG_KERNEL_CORE_NUM]; + +STATIC INLINE SchedRunQue *OsSchedRunQue(VOID) { - LosTaskCB *runTask = OsCurrTaskGet(); - runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime;//获取时间差 + return &g_schedRunQue[ArchCurrCpuid()]; } -/// 获取中断开始时间 -STATIC INLINE VOID OsSchedIrqStartTime(VOID) + +STATIC INLINE SchedRunQue *OsSchedRunQueByID(UINT16 id) { - LosTaskCB *runTask = OsCurrTaskGet(); - runTask->irqStartTime = OsGetCurrSchedTimeCycle(); //获取当前时间 + return &g_schedRunQue[id]; } -/* - * Schedule flag, one bit represents one core. - * This flag is used to prevent kernel scheduling before OSStartToRun. - */ -#define OS_SCHEDULER_SET(cpuid) do { \ - g_taskScheduled |= (1U << (cpuid)); \ -} while (0); -//清楚调度标识位,对应位设置为0 -#define OS_SCHEDULER_CLR(cpuid) do { \ - g_taskScheduled &= ~(1U << (cpuid)); \ -} while (0); +STATIC INLINE UINT32 OsSchedLockCountGet(VOID) +{ + return OsSchedRunQue()->taskLockCnt; +} -#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))///< 用于判断当前cpu是否在调度中 -#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK) +STATIC INLINE VOID OsSchedLockSet(UINT32 count) +{ + OsSchedRunQue()->taskLockCnt = count; +} -typedef enum { - INT_NO_RESCH = 0x0, /**< no needs to schedule | 不需要调度*/ - INT_PEND_RESCH = 0x1, /**< pending schedule flag | 因定时器/任务优先级调整等导致的调度,可以理解为内因触发的调度*/ - INT_PEND_TICK = 0x2, /**< pending tick | 因tick导致的调度,可以理解为外因触发的调度*/ -} SchedFlag; +STATIC INLINE VOID OsSchedLock(VOID) +{ + OsSchedRunQue()->taskLockCnt++; +} + +STATIC INLINE VOID OsSchedUnlock(VOID) +{ + OsSchedRunQue()->taskLockCnt--; +} + +STATIC INLINE BOOL OsSchedUnlockResch(VOID) +{ + SchedRunQue *rq = OsSchedRunQue(); + if (rq->taskLockCnt > 0) { + rq->taskLockCnt--; + if ((rq->taskLockCnt == 0) && (rq->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { + return TRUE; + } + } + + return FALSE; +} + +STATIC INLINE BOOL OsSchedIsLock(VOID) +{ + return (OsSchedRunQue()->taskLockCnt != 0); +} /* Check if preemptable with counter flag */ -STATIC INLINE BOOL OsPreemptable(VOID)//是否可抢占 +STATIC INLINE BOOL OsPreemptable(VOID) { + SchedRunQue *rq = OsSchedRunQue(); /* * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable * is called, needs mannually disable interrupt, to prevent current task from * being migrated to another core, and get the wrong preeptable status. */ - //与OsPreemptableInSched不同,当OsPreemptable时,中断可能不会被禁用,所以调用时,需要手动禁用中断,以防止当前任务 - //被迁移到另一个CPU核上,并得到错误的可接受状态。 - UINT32 intSave = LOS_IntLock();//手动禁用中断 - BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); + UINT32 intSave = LOS_IntLock(); + BOOL preemptable = (rq->taskLockCnt == 0); if (!preemptable) { /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag |= INT_PEND_RESCH; + rq->schedFlag |= INT_PEND_RESCH; } - LOS_IntRestore(intSave);//手动恢复中断 + LOS_IntRestore(intSave); return preemptable; } STATIC INLINE BOOL OsPreemptableInSched(VOID) { BOOL preemptable = FALSE; + SchedRunQue *rq = OsSchedRunQue(); #ifdef LOSCFG_KERNEL_SMP /* * For smp systems, schedule must hold the task spinlock, and this counter - * will increase by 1 in that case. | 对于 smp ,调度必须持有任务自旋锁,在这种情况下,此计数器将增加 1。 + * will increase by 1 in that case. */ - preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务 + preemptable = (rq->taskLockCnt == 1); #else - preemptable = (OsPercpuGet()->taskLockCnt == 0); + preemptable = (rq->taskLockCnt == 0); #endif if (!preemptable) { - /* Set schedule flag if preemption is disabled | 如果禁用抢占,则设置调度标志*/ - OsPercpuGet()->schedFlag |= INT_PEND_RESCH; + /* Set schedule flag if preemption is disabled */ + rq->schedFlag |= INT_PEND_RESCH; } return preemptable; } -/// 申请CPU调度锁 -STATIC INLINE VOID OsCpuSchedLock(Percpu *cpu) + +STATIC INLINE UINT32 OsSchedGetRunQueIdle(VOID) +{ + return OsSchedRunQue()->idleTaskID; +} + +STATIC INLINE VOID OsSchedRunQuePendingSet(VOID) { - cpu->taskLockCnt++; + OsSchedRunQue()->schedFlag |= INT_PEND_RESCH; } -/// 释放CPU调度锁 -STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave) + +#ifdef LOSCFG_KERNEL_SMP +STATIC INLINE VOID FindIdleRunQue(UINT16 *idleCpuID) { - if (cpu->taskLockCnt > 0) { - cpu->taskLockCnt--; - if ((cpu->taskLockCnt == 0) && (cpu->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) { - cpu->schedFlag &= ~INT_PEND_RESCH; - LOS_IntRestore(intSave); - LOS_Schedule(); - return; + SchedRunQue *idleRq = OsSchedRunQueByID(0); + UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->taskSortLink) + OsGetSortLinkNodeNum(&idleRq->swtmrSortLink); + UINT16 cpuID = 1; + do { + SchedRunQue *rq = OsSchedRunQueByID(cpuID); + UINT32 temp = OsGetSortLinkNodeNum(&rq->taskSortLink) + OsGetSortLinkNodeNum(&rq->swtmrSortLink); + if (nodeNum > temp) { + *idleCpuID = cpuID; + nodeNum = temp; } - } + cpuID++; + } while (cpuID < LOSCFG_KERNEL_CORE_NUM); +} +#endif - LOS_IntRestore(intSave); +STATIC INLINE VOID OsSchedAddTask2TimeList(SortLinkList *node, UINT64 startTime, UINT32 waitTicks) +{ + UINT16 idleCpu = 0; +#ifdef LOSCFG_KERNEL_SMP + FindIdleRunQue(&idleCpu); +#endif + SchedRunQue *rq = OsSchedRunQueByID(idleCpu); + UINT64 responseTime = startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK; + OsAdd2SortLink(&rq->taskSortLink, node, responseTime, idleCpu); +} + +STATIC INLINE UINT32 OsSchedSwtmrHandlerQueueGet(VOID) +{ + return OsSchedRunQue()->swtmrHandlerQueue; +} + +STATIC INLINE VOID OsSchedDeTaskFromTimeList(SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + SchedRunQue *rq = OsSchedRunQueByID(node->cpuid); +#else + SchedRunQue *rq = OsSchedRunQueByID(0); +#endif + OsDeleteFromSortLink(&rq->taskSortLink, node); +} + +STATIC INLINE VOID OsSchedAddSwtmr2TimeList(SortLinkList *node, UINT64 startTime, UINT32 waitTicks) +{ + UINT16 idleCpu = 0; +#ifdef LOSCFG_KERNEL_SMP + FindIdleRunQue(&idleCpu); +#endif + SchedRunQue *rq = OsSchedRunQueByID(idleCpu); + UINT64 responseTime = startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK; + OsAdd2SortLink(&rq->swtmrSortLink, node, responseTime, idleCpu); +} + +STATIC INLINE VOID OsSchedDeSwtmrFromTimeList(SortLinkList *node) +{ +#ifdef LOSCFG_KERNEL_SMP + SchedRunQue *rq = OsSchedRunQueByID(node->cpuid); +#else + SchedRunQue *rq = OsSchedRunQueByID(0); +#endif + OsDeleteFromSortLink(&rq->swtmrSortLink, node); } -extern VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); +VOID OsSchedRunQueIdleInit(UINT32 idleTaskID); +VOID OsSchedRunQueSwtmrInit(UINT32 swtmrTaskID, UINT32 swtmrQueue); +VOID OsSchedRunQueInit(VOID); +BOOL OsSchedSwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); + +/** + * @ingroup los_sched + * Define a usable task priority. + * + * Highest task priority. + */ +#define OS_TASK_PRIORITY_HIGHEST 0 + +/** + * @ingroup los_sched + * Define a usable task priority. + * + * Lowest task priority. + */ +#define OS_TASK_PRIORITY_LOWEST 31 + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is init. + */ +#define OS_TASK_STATUS_INIT 0x0001U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is ready. + */ +#define OS_TASK_STATUS_READY 0x0002U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is running. + */ +#define OS_TASK_STATUS_RUNNING 0x0004U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is suspended. + */ +#define OS_TASK_STATUS_SUSPENDED 0x0008U -extern UINT32 OsSchedSwtmrScanRegister(SchedScan func); +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is blocked. + */ +#define OS_TASK_STATUS_PENDING 0x0010U -extern VOID OsSchedResetSchedResponseTime(UINT64 responseTime); +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is delayed. + */ +#define OS_TASK_STATUS_DELAY 0x0020U -extern VOID OsSchedUpdateExpireTime(UINT64 startTime); +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The time for waiting for an event to occur expires. + */ +#define OS_TASK_STATUS_TIMEOUT 0x0040U -extern VOID OsSchedToUserReleaseLock(VOID); +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is pend for a period of time. + */ +#define OS_TASK_STATUS_PEND_TIME 0x0080U -extern VOID OsSchedTaskDeQueue(LosTaskCB *taskCB); +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is exit. + */ +#define OS_TASK_STATUS_EXIT 0x0100U + +#define OS_TCB_NAME_LEN 32 + +typedef struct { + VOID *stackPointer; /**< Task stack pointer | 内核栈指针位置(SP) */ + UINT16 taskStatus; /**< Task status | 各种状态标签,可以拥有多种标签,按位标识 */ + + /* The scheduling */ + UINT16 basePrio; + UINT16 priority; /**< Task priority | 任务优先级[0:31],默认是31级 */ + UINT16 policy; ///< 任务的调度方式(三种 .. LOS_SCHED_RR LOS_SCHED_FIFO .. ) + UINT64 startTime; /**< The start time of each phase of task | 任务开始时间 */ + UINT64 irqStartTime; /**< Interrupt start time | 任务中断开始时间 */ + UINT32 irqUsedTime; /**< Interrupt consumption time | 任务中断消耗时间 */ + UINT32 initTimeSlice; /**< Task init time slice | 任务初始的时间片 */ + INT32 timeSlice; /**< Task remaining time slice | 任务剩余时间片 */ + UINT32 waitTimes; /**< Task delay time, tick number | 设置任务调度延期时间 */ + SortLinkList sortList; /**< Task sortlink node | 跟CPU捆绑的任务排序链表节点,上面挂的是就绪队列的下一个阶段,进入CPU要执行的任务队列 */ + UINT32 stackSize; /**< Task stack size | 内核态栈大小,内存来自内核空间 */ + UINTPTR topOfStack; /**< Task stack top | 内核态栈顶 bottom = top + size */ + UINT32 taskID; /**< Task ID | 任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128 */ + TSK_ENTRY_FUNC taskEntry; /**< Task entrance function | 任务执行入口地址 */ + VOID *joinRetval; /**< pthread adaption | 用来存储join线程的入口地址 */ + VOID *taskMux; /**< Task-held mutex | task在等哪把锁 */ + VOID *taskEvent; /**< Task-held event | task在等哪个事件 */ + UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 | 入口函数的参数 例如 main (int argc,char *argv[]) */ + CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name | 任务的名称 */ + LOS_DL_LIST pendList; /**< Task pend node | 如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 */ + LOS_DL_LIST threadList; /**< thread list | 挂到所属进程的线程链表上 */ + UINT32 eventMask; /**< Event mask | 任务对哪些事件进行屏蔽 */ + UINT32 eventMode; /**< Event mode | 事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR) */ + UINT32 priBitMap; /**< BitMap for recording the change of task priority,the priority can not be greater than 31 + | 任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级 */ +#ifdef LOSCFG_KERNEL_CPUP + OsCpupBase taskCpup; /**< task cpu usage | CPU 使用统计 */ +#endif + INT32 errorNo; /**< Error Num | 错误序号 */ + UINT32 signal; /**< Task signal | 任务信号类型,(SIGNAL_NONE,SIGNAL_KILL,SIGNAL_SUSPEND,SIGNAL_AFFI) */ + sig_cb sig; ///< 信号控制块,用于异步通信,类似于 linux singal模块 +#ifdef LOSCFG_KERNEL_SMP + UINT16 currCpu; /**< CPU core number of this task is running on | 正在运行此任务的CPU内核号 */ + UINT16 lastCpu; /**< CPU core number of this task is running on last time | 上次运行此任务的CPU内核号 */ + UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores | CPU亲和力掩码,最多支持16核,亲和力很重要,多核情况下尽量一个任务在一个CPU核上运行,提高效率 */ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC //多核情况下的任务同步开关,采用信号量实现 + UINT32 syncSignal; /**< Synchronization for signal handling | 用于CPU之间同步信号量 */ +#endif +#ifdef LOSCFG_KERNEL_SMP_LOCKDEP //SMP死锁检测开关 + LockDep lockDep; ///< 死锁依赖检测 +#endif +#endif +#ifdef LOSCFG_SCHED_DEBUG //调试调度开关 + SchedStat schedStat; /**< Schedule statistics | 调度统计 */ +#endif +#ifdef LOSCFG_KERNEL_VM + UINTPTR archMmu; + UINTPTR userArea; ///< 用户空间的堆区开始位置 + UINTPTR userMapBase; ///< 用户空间的栈顶位置,内存来自用户空间,和topOfStack有本质的区别. + UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE | 用户栈大小 */ + FutexNode futex; ///< 实现快锁功能 +#endif + UINT32 processID; /**< Which belong process */ + LOS_DL_LIST joinList; /**< join list | 联结链表,允许任务之间相互释放彼此 */ + LOS_DL_LIST lockList; /**< Hold the lock list | 该链表上挂的都是已持有的锁 */ + UINTPTR waitID; /**< Wait for the PID or GID of the child process | 等待子进程的PID或GID */ + UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent, + a specific child process, or any child process | 等待的子进程以什么样的方式结束(OS_TASK_WAIT_PROCESS | OS_TASK_WAIT_GID | ..) */ +#ifdef LOSCFG_KERNEL_LITEIPC //轻量级进程间通信开关 + IpcTaskInfo *ipcTaskInfo; ///< 任务间通讯信息结构体 +#endif +#ifdef LOSCFG_KERNEL_PERF + UINTPTR pc; ///< pc寄存器 + UINTPTR fp; ///< fp寄存器 +#endif +} LosTaskCB; -extern VOID OsSchedTaskEnQueue(LosTaskCB *taskCB); -extern UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched); +STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_RUNNING) != 0); +} -extern VOID OsSchedTaskWake(LosTaskCB *resumedTask); +STATIC INLINE BOOL OsTaskIsReady(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_READY) != 0); +} -extern BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priority); +STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) != 0); +} -extern BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT16 priority); +STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_PENDING) != 0); +} -extern VOID OsSchedSuspend(LosTaskCB *taskCB); +STATIC INLINE BOOL OsTaskIsSuspended(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_SUSPENDED) != 0); +} -extern BOOL OsSchedResume(LosTaskCB *taskCB); +STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_SUSPENDED | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) != 0); +} -extern VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick); +STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) +{ + return (LosTaskCB *)ArchCurrTaskGet(); +} -extern VOID OsSchedYield(VOID); +STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) +{ + ArchCurrTaskSet(task); +} -extern VOID OsSchedTaskExit(LosTaskCB *taskCB); +STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) +{ + ArchCurrUserTaskSet(thread); +} -extern VOID OsSchedTick(VOID); +STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime;//获取时间差 +} +/// 获取中断开始时间 +STATIC INLINE VOID OsSchedIrqStartTime(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + runTask->irqStartTime = OsGetCurrSchedTimeCycle(); //获取当前时间 +} -extern UINT32 OsSchedInit(VOID); +/* + * Schedule flag, one bit represents one core. + * This flag is used to prevent kernel scheduling before OSStartToRun. + */ +#define OS_SCHEDULER_SET(cpuid) do { \ + g_taskScheduled |= (1U << (cpuid)); \ +} while (0); +//清楚调度标识位,对应位设置为0 +#define OS_SCHEDULER_CLR(cpuid) do { \ + g_taskScheduled &= ~(1U << (cpuid)); \ +} while (0); -extern VOID OsSchedStart(VOID); +VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask); +VOID OsSchedResetSchedResponseTime(UINT64 responseTime); +VOID OsSchedUpdateExpireTime(VOID); +VOID OsSchedToUserReleaseLock(VOID); +VOID OsSchedTaskDeQueue(LosTaskCB *taskCB); +VOID OsSchedTaskEnQueue(LosTaskCB *taskCB); +UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched); +VOID OsSchedTaskWake(LosTaskCB *resumedTask); +BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priority); +BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority); +VOID OsSchedSuspend(LosTaskCB *taskCB); +BOOL OsSchedResume(LosTaskCB *taskCB); +VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick); +VOID OsSchedYield(VOID); +VOID OsSchedTaskExit(LosTaskCB *taskCB); +VOID OsSchedTick(VOID); +UINT32 OsSchedInit(VOID); +VOID OsSchedStart(VOID); /* * This function simply picks the next task and switches to it. * Current task needs to already be in the right state or the right * queues it needs to be in. */ -extern VOID OsSchedResched(VOID); - -extern VOID OsSchedIrqEndCheckNeedSched(VOID); +VOID OsSchedResched(VOID); +VOID OsSchedIrqEndCheckNeedSched(VOID); /* * This function inserts the runTask to the lock pending list based on the * task priority. */ -extern LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList); +LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList); #ifdef LOSCFG_SCHED_TICK_DEBUG -extern VOID OsSchedDebugRecordData(VOID); +VOID OsSchedDebugRecordData(VOID); #endif -extern UINT32 OsShellShowTickRespo(VOID); +UINT32 OsShellShowTickRespo(VOID); -extern UINT32 OsShellShowSchedParam(VOID); +UINT32 OsShellShowSchedParam(VOID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index 666b7e4f..4d85f849 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -34,7 +34,7 @@ #include "los_typedef.h" #include "los_list.h" -#include "los_sys_pri.h" +#include "los_spinlock.h" #ifdef __cplusplus #if __cplusplus @@ -42,13 +42,6 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/*! \enum SortLinkType -* @brief 因为任务和定时器都是吃CPU的,让CPU不停工作的主要就是这两宝贝. -*/ -typedef enum { - OS_SORT_LINK_TASK = 1, ///< 任务 - OS_SORT_LINK_SWTMR = 2, ///< 定时器 -} SortLinkType; /*! \struct SortLinkList * @@ -67,6 +60,7 @@ typedef struct { typedef struct { LOS_DL_LIST sortLink; ///< 排序链表,上面挂的任务/软件定时器 UINT32 nodeNum; ///< 链表结点数量 + SPIN_LOCK_S spinLock; /* swtmr sort link spin lock */ } SortLinkAttribute; #define OS_SORT_LINK_INVALID_TIME ((UINT64)-1) @@ -97,11 +91,16 @@ STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, return listSorted->responseTime; } -extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader); -extern VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type); -extern VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type); -extern UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList); -extern UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader); +STATIC INLINE UINT32 OsGetSortLinkNodeNum(SortLinkAttribute *head) +{ + return head->nodeNum; +} + +VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader); +VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu); +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node); +UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList); +UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_swtmr_pri.h b/kernel/base/include/los_swtmr_pri.h index c13f5534..c2cc3c5d 100644 --- a/kernel/base/include/los_swtmr_pri.h +++ b/kernel/base/include/los_swtmr_pri.h @@ -34,6 +34,7 @@ #include "los_swtmr.h" #include "los_spinlock.h" +#include "los_sched_pri.h" #ifdef LOSCFG_SECURITY_VID #include "vid_api.h" @@ -75,7 +76,6 @@ typedef SwtmrHandlerItem *SwtmrHandlerItemPtr; extern SWTMR_CTRL_S *g_swtmrCBArray;//软件定时器数组,后续统一注解为定时器池 -extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */ //软件计时器计数链表 //通过参数ID找到对应定时器描述体 #define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT)) @@ -100,11 +100,13 @@ extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */ // * * @see LOS_SwtmrStop */ -extern VOID OsSwtmrScan(VOID); + +extern BOOL OsIsSwtmrTask(const LosTaskCB *taskCB); +extern VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList); +extern VOID OsSwtmrWake(SchedRunQue *rq, UINT64 currTime, SortLinkList *sortList); extern UINT32 OsSwtmrInit(VOID); -extern VOID OsSwtmrTask(VOID); extern VOID OsSwtmrRecycle(UINT32 processID); -extern VOID OsSwtmrResponseTimeReset(UINT64 startTime); +extern BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); extern SPIN_LOCK_S g_swtmrSpin; #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index fc4101ba..feebf93a 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -33,20 +33,8 @@ #define _LOS_TASK_PRI_H #include "los_task.h" -#include "los_percpu_pri.h" -#include "los_spinlock.h" -#ifdef LOSCFG_SCHED_DEBUG -#include "los_stat_pri.h" -#endif -#include "los_stackinfo_pri.h" -#include "los_futex_pri.h" -#include "los_signal.h" -#ifdef LOSCFG_KERNEL_CPUP -#include "los_cpup_pri.h" -#endif -#ifdef LOSCFG_KERNEL_LITEIPC -#include "hm_liteipc.h" -#endif +#include "los_sched_pri.h" + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -79,112 +67,29 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 */ #define OS_TASK_ERRORID 0xFFFFFFFF -/** - * @ingroup los_task - * Define a usable task priority. - * - * Highest task priority. - */ -#define OS_TASK_PRIORITY_HIGHEST 0 //任务最高优先级,软时钟任务就是最高级任务,见于 OsSwtmrTaskCreate - -/** - * @ingroup los_task - * Define a usable task priority. - * - * Lowest task priority. - */ -#define OS_TASK_PRIORITY_LOWEST 31 ///< 任务最低优先级 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is init. - */ -#define OS_TASK_STATUS_INIT 0x0001U ///< 初始化状态 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is ready. - */ -#define OS_TASK_STATUS_READY 0x0002U ///< 就绪状态的任务都将插入就绪队列,注意就绪队列的本质是个双向链表 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is running. - */ -#define OS_TASK_STATUS_RUNNING 0x0004U ///< 任务状态: 运行中 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is suspended. - */ -#define OS_TASK_STATUS_SUSPENDED 0x0008U ///< 任务状态: 暂停, 意思是发生了不需要等待资源的暂停,例如中断来了 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is blocked. - */ -#define OS_TASK_STATUS_PENDING 0x0010U ///< 任务状态: 挂起/待办 ,意思在需等待其他外在资源引起的停止,例如互斥锁/信号量 == - /** * @ingroup los_task * Flag that indicates the task or task control block status. * - * The task is delayed. - */ -#define OS_TASK_STATUS_DELAY 0x0020U ///< 延迟状态 ,例如 delay(100),因内部原因引起的等待 见于 OsSchedDelay 延期调度 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The time for waiting for an event to occur expires. - */ -#define OS_TASK_STATUS_TIMEOUT 0x0040U ///< 任务等待事件发生超时 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is pend for a period of time. - */ -#define OS_TASK_STATUS_PEND_TIME 0x0080U ///< 任务状态: 有时间限制的挂起/待办,例如等待某个事件时设置为时间到了就不等了 - -#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ - OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) ///< 任务状态: 阻塞 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is exit. + * The task control block is unused. */ -#define OS_TASK_STATUS_EXIT 0x0100U ///< 任务状态:退出 +#define OS_TASK_STATUS_UNUSED 0x0200U ///< 任务状态:未使用 /** * @ingroup los_task * Flag that indicates the task or task control block status. * - * The task control block is unused. + * The task is joinable. */ -#define OS_TASK_STATUS_UNUSED 0x0200U ///< 任务状态:未使用 +#define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U ///< 主task和子task连在一块不分离 /** * @ingroup los_task * Flag that indicates the task or task control block status. * - * The task is joinable. + * The task is user mode task. */ -#define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U ///< 主task和子task连在一块不分离 +#define OS_TASK_FLAG_USER_MODE 0x0800U /** * @ingroup los_task @@ -306,73 +211,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 #define OS_RESOURCE_EVENT_MASK 0xFF ///< 资源事件的掩码 #define OS_RESOURCE_EVENT_OOM 0x02 ///< 内存溢出事件 #define OS_RESOURCE_EVENT_FREE 0x04 ///< 资源释放事件 -#define OS_TCB_NAME_LEN 32 ///< 任务名称长度上限 -typedef struct { - VOID *stackPointer; /**< Task stack pointer | 内核栈指针位置(SP) */ - UINT16 taskStatus; /**< Task status | 各种状态标签,可以拥有多种标签,按位标识 */ - UINT16 priority; /**< Task priority | 任务优先级[0:31],默认是31级 */ - UINT16 policy; ///< 任务的调度方式(三种 .. LOS_SCHED_RR LOS_SCHED_FIFO .. ) - UINT64 startTime; /**< The start time of each phase of task | 任务开始时间 */ - UINT64 irqStartTime; /**< Interrupt start time | 任务中断开始时间 */ - UINT32 irqUsedTime; /**< Interrupt consumption time | 任务中断消耗时间 */ - UINT32 initTimeSlice; /**< Task init time slice | 任务初始的时间片 */ - INT32 timeSlice; /**< Task remaining time slice | 任务剩余时间片 */ - UINT32 waitTimes; /**< Task delay time, tick number | 设置任务调度延期时间 */ - SortLinkList sortList; /**< Task sortlink node | 跟CPU捆绑的任务排序链表节点,上面挂的是就绪队列的下一个阶段,进入CPU要执行的任务队列 */ - UINT32 stackSize; /**< Task stack size | 内核态栈大小,内存来自内核空间 */ - UINTPTR topOfStack; /**< Task stack top | 内核态栈顶 bottom = top + size */ - UINT32 taskID; /**< Task ID | 任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128 */ - TSK_ENTRY_FUNC taskEntry; /**< Task entrance function | 任务执行入口地址 */ - VOID *joinRetval; /**< pthread adaption | 用来存储join线程的入口地址 */ - VOID *taskMux; /**< Task-held mutex | task在等哪把锁 */ - VOID *taskEvent; /**< Task-held event | task在等哪个事件 */ - UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 | 入口函数的参数 例如 main (int argc,char *argv[]) */ - CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name | 任务的名称 */ - LOS_DL_LIST pendList; /**< Task pend node | 如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 */ - LOS_DL_LIST threadList; /**< thread list | 挂到所属进程的线程链表上 */ - UINT32 eventMask; /**< Event mask | 任务对哪些事件进行屏蔽 */ - UINT32 eventMode; /**< Event mode | 事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR) */ - UINT32 priBitMap; /**< BitMap for recording the change of task priority,the priority can not be greater than 31 - | 任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级 */ -#ifdef LOSCFG_KERNEL_CPUP - OsCpupBase taskCpup; /**< task cpu usage | CPU 使用统计 */ -#endif - INT32 errorNo; /**< Error Num | 错误序号 */ - UINT32 signal; /**< Task signal | 任务信号类型,(SIGNAL_NONE,SIGNAL_KILL,SIGNAL_SUSPEND,SIGNAL_AFFI) */ - sig_cb sig; ///< 信号控制块,用于异步通信,类似于 linux singal模块 -#ifdef LOSCFG_KERNEL_SMP - UINT16 currCpu; /**< CPU core number of this task is running on | 正在运行此任务的CPU内核号 */ - UINT16 lastCpu; /**< CPU core number of this task is running on last time | 上次运行此任务的CPU内核号 */ - UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores | CPU亲和力掩码,最多支持16核,亲和力很重要,多核情况下尽量一个任务在一个CPU核上运行,提高效率 */ -#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC //多核情况下的任务同步开关,采用信号量实现 - UINT32 syncSignal; /**< Synchronization for signal handling | 用于CPU之间同步信号量 */ -#endif -#ifdef LOSCFG_KERNEL_SMP_LOCKDEP //SMP死锁检测开关 - LockDep lockDep; ///< 死锁依赖检测 -#endif -#endif -#ifdef LOSCFG_SCHED_DEBUG //调试调度开关 - SchedStat schedStat; /**< Schedule statistics | 调度统计 */ -#endif - UINTPTR userArea; ///< 用户空间的堆区开始位置 - UINTPTR userMapBase; ///< 用户空间的栈顶位置,内存来自用户空间,和topOfStack有本质的区别. - UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE | 用户栈大小 */ - UINT32 processID; /**< Which belong process | 所属进程ID */ - FutexNode futex; ///< 实现快锁功能 - LOS_DL_LIST joinList; /**< join list | 联结链表,允许任务之间相互释放彼此 */ - LOS_DL_LIST lockList; /**< Hold the lock list | 该链表上挂的都是已持有的锁 */ - UINTPTR waitID; /**< Wait for the PID or GID of the child process | 等待子进程的PID或GID */ - UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent, - a specific child process, or any child process | 等待的子进程以什么样的方式结束(OS_TASK_WAIT_PROCESS | OS_TASK_WAIT_GID | ..) */ -#ifdef LOSCFG_KERNEL_LITEIPC //轻量级进程间通信开关 - IpcTaskInfo *ipcTaskInfo; ///< 任务间通讯信息结构体 -#endif -#ifdef LOSCFG_KERNEL_PERF - UINTPTR pc; ///< pc寄存器 - UINTPTR fp; ///< fp寄存器 -#endif -} LosTaskCB; ///< LosTask结构体是给外部使用的 typedef struct { LosTaskCB *runTask; @@ -414,21 +253,7 @@ typedef struct {//时间片结构体,任务轮询 UINT16 time; /**< Expiration time point | 到期时间点*/ UINT16 timeout; /**< Expiration duration | 有效期*/ } OsTaskRobin; -/// 获取当前CPU core运行的任务 -STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) -{ - return (LosTaskCB *)ArchCurrTaskGet(); -} -/// 告诉协处理器当前任务使用范围为内核空间 -STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) -{ - ArchCurrTaskSet(task); -} -/// 告诉协处理器当前任务使用范围为 用户空间 -STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) -{ - ArchCurrUserTaskSet(thread); -} + /// 通过任务ID获取任务实体,task由任务池分配,本质是个数组,彼此都挨在一块 STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID) { @@ -437,47 +262,17 @@ STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID) /// 任务是否在使用 STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB) { - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//在freelist中的任务都是 OS_TASK_STATUS_UNUSED 状态 - return TRUE; - } - - return FALSE; + return ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) != 0); } -/// 任务是否在运行 -STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//一个CPU core 只能有一个 OS_TASK_STATUS_RUNNING task - return TRUE; - } - return FALSE; -} -/// 任务是否不再活跃 -STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) +STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB) { - if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {//三个标签有一个 代表不在活动 - return TRUE; - } - - return FALSE; + return ((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) != 0); } -/// 任务是否挂起 -STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { - return TRUE; - } - return FALSE; -} -/// 任务是否被干掉 -STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB) +STATIC INLINE BOOL OsTaskIsUserMode(const LosTaskCB *taskCB) { - if (taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) { - return TRUE; - } - - return FALSE; + return ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) != 0); } #define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum)//是否有无效的任务 > 128 @@ -529,23 +324,19 @@ extern LosTaskCB *OsGetMainTask(VOID); extern VOID OsSetMainTask(VOID); extern UINT32 OsGetIdleTaskId(VOID); extern VOID OsTaskEntry(UINT32 taskID); -extern SortLinkAttribute *OsTaskSortLinkGet(VOID); extern VOID OsTaskProcSignal(VOID); -extern UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave); -extern VOID OsTaskResourcesToFree(LosTaskCB *taskCB); -extern VOID OsRunTaskToDelete(LosTaskCB *taskCB); extern UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam); extern INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName); extern VOID OsTaskCBRecycleToFree(VOID); -extern VOID OsTaskExitGroup(UINT32 status); -extern VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status); -extern VOID OsExecDestroyTaskGroup(VOID); +extern VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status); extern UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB); extern UINT32 OsUserProcessOperatePermissionsCheck(LosTaskCB *taskCB, UINT32 processID); extern INT32 OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info); extern VOID OsWriteResourceEvent(UINT32 events); extern VOID OsWriteResourceEventUnsafe(UINT32 events); extern UINT32 OsResourceFreeTaskCreate(VOID); +extern VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB); +extern VOID OsInactiveTaskDelete(LosTaskCB *taskCB); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/ipc/los_futex.c b/kernel/base/ipc/los_futex.c index 8203dc37..bcd9285a 100644 --- a/kernel/base/ipc/los_futex.c +++ b/kernel/base/ipc/los_futex.c @@ -653,18 +653,18 @@ STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const SCHEDULER_LOCK(intSave); OsTaskWaitSetPendMask(OS_TASK_WAIT_FUTEX, futexKey, timeOut); OsSchedTaskWait(&(node->pendList), timeOut, FALSE); - OsPercpuGet()->taskLockCnt++; + OsSchedLock(); LOS_SpinUnlock(&g_taskSpin); futexRet = OsFutexUnlock(&hashNode->listLock); if (futexRet) { - OsPercpuGet()->taskLockCnt--; + OsSchedUnlock(); LOS_IntRestore(intSave); goto EXIT_UNLOCK_ERR; } LOS_SpinLock(&g_taskSpin); - OsPercpuGet()->taskLockCnt--; + OsSchedUnlock(); /* * it will immediately do the scheduling, so there's no need to release the diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index 8a5c7c10..21f9e993 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -737,8 +737,8 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) return sp; } - if (task->taskStatus & OS_TASK_FLAG_EXIT_KILL) { - OsTaskToExit(task, 0); + if (OsTaskIsKilled(task)) { + OsRunningTaskToExit(task, 0); return sp; } diff --git a/kernel/base/misc/task_shellcmd.c b/kernel/base/misc/task_shellcmd.c index c5ecc588..bafc32d8 100644 --- a/kernel/base/misc/task_shellcmd.c +++ b/kernel/base/misc/task_shellcmd.c @@ -112,7 +112,7 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdProcessMode(UINT16 mode) return (UINT8 *)"ERROR"; } -/// 获取调度方式的名称 +/// 获取调度方式的名? LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdSchedPolicy(UINT16 policy) { if (policy == LOS_SCHED_RR) { @@ -125,10 +125,9 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdSchedPolicy(UINT16 policy) return (UINT8 *)"ERROR"; } -/// 获取状态名称 + LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellProcessStatus(UINT16 status) { - status = status & OS_PROCESS_STATUS_MASK; if (status & OS_PROCESS_STATUS_ZOMBIES) { return (UINT8 *)"Zombies"; } else if (status & OS_PROCESS_STATUS_INIT) { @@ -137,11 +136,8 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellProcessStatus(UINT16 status) return (UINT8 *)"Running"; } else if (status & OS_PROCESS_STATUS_READY) { return (UINT8 *)"Ready"; - } else if (status & OS_PROCESS_STATUS_PENDING) { - return (UINT8 *)"Pending"; } - - return (UINT8 *)"Invalid"; + return (UINT8 *)"Pending"; } STATIC VOID OsShellCmdProcessTitle(VOID *seqBuf, UINT16 flag) @@ -189,7 +185,7 @@ STATIC VOID OsShellCmdProcessInfoShow(const LosProcessCB *processCB, const INT32 processCpup1s[pid].usage % LOS_CPUP_PRECISION_MULT); #endif /* LOSCFG_KERNEL_CPUP */ PROCESS_INFO_SHOW(seqBuf, "%6s%9u%5d%10u%7s ", - OsShellCmdSchedPolicy(LOS_SCHED_RR), processCB->priority, + OsShellCmdSchedPolicy(LOS_SCHED_RR), OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio, (INT32)processCB->threadGroupID, processCB->threadNumber, OsShellCmdProcessMode(processCB->processMode)); } else { @@ -246,17 +242,28 @@ STATIC VOID OsProcessMemUsageGet(UINT32 *memArray) } #endif -STATIC UINT32 OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, UINT32 **memArray, UINT16 flag) +#define OS_TASK_STATUS_MASK 0x00FF +STATIC VOID OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, + UINT32 **memArray, LosTaskCB **tcbArray, + UINT16 flag) { - UINT32 len = OS_PROCESS_ALL_INFO_LEN; - LosProcessCB *processCB = NULL; - INT32 *user = NULL; - - (VOID)memcpy_s(*pcbArray, OS_PROCESS_INFO_LEN, g_processCBArray, OS_PROCESS_INFO_LEN); *group = (INT32 *)((UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN); - user = (INT32 *)((UINTPTR)*group + OS_PROCESS_GROUP_INFO_LEN); + INT32 *user = (INT32 *)((UINTPTR)*group + OS_PROCESS_GROUP_INFO_LEN); + + for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) { + LosTaskCB *taskCB = *tcbArray + tid; + if (OsTaskIsUnused(taskCB)) { + continue; + } + + LosProcessCB *processCB = *pcbArray + taskCB->processID; + if (!OsProcessIsDead(processCB) && !OsProcessIsInit(processCB)) { + processCB->processStatus |= (taskCB->taskStatus & OS_TASK_STATUS_MASK); + } + } + for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) { - processCB = *pcbArray + pid; + LosProcessCB *processCB = *pcbArray + pid; if (OsProcessIsUnused(processCB)) { continue; } @@ -295,11 +302,8 @@ STATIC UINT32 OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, UINT32 ** if (flag & OS_PROCESS_MEM_INFO) { *memArray = (UINT32 *)((UINTPTR)*pcbArray + OS_PROCESS_ALL_INFO_LEN); OsProcessMemUsageGet(*memArray); - len += OS_PROCESS_MEM_ALL_INFO_LEN; } #endif - - return len; } STATIC VOID OsShellCmdProcessInfoData(const LosProcessCB *pcbArray, const INT32 *group, @@ -322,23 +326,23 @@ STATIC VOID OsShellCmdProcessInfoData(const LosProcessCB *pcbArray, const INT32 LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdConvertTskStatus(UINT16 taskStatus) { - if (taskStatus & OS_TASK_STATUS_INIT) {//初始化 + if (taskStatus & OS_TASK_STATUS_INIT) {//初始? return (UINT8 *)"Init"; - } else if (taskStatus & OS_TASK_STATUS_RUNNING) {//运行中 + } else if (taskStatus & OS_TASK_STATUS_RUNNING) {//运行? return (UINT8 *)"Running"; - } else if (taskStatus & OS_TASK_STATUS_READY) {//已就绪 + } else if (taskStatus & OS_TASK_STATUS_READY) {//已就? return (UINT8 *)"Ready"; } else if (taskStatus & OS_TASK_STATUS_SUSPENDED) {//暂停 return (UINT8 *)"Suspended"; } else if (taskStatus & OS_TASK_STATUS_DELAY) {//延迟 return (UINT8 *)"Delay"; } else if (taskStatus & OS_TASK_STATUS_PENDING) {//挂起/待办 - if (taskStatus & OS_TASK_STATUS_PEND_TIME) { //挂起/待办有时间限制 + if (taskStatus & OS_TASK_STATUS_PEND_TIME) { //挂起/待办有时间限? return (UINT8 *)"PendTime"; } else { - return (UINT8 *)"Pending";//挂起/待办无时间限制 + return (UINT8 *)"Pending";//挂起/待办无时间限? } - } else if (taskStatus & OS_TASK_STATUS_EXIT) {//退出 + } else if (taskStatus & OS_TASK_STATUS_EXIT) {//退? return (UINT8 *)"Exit"; } @@ -363,7 +367,7 @@ STATIC VOID OsShellCmdTaskWaterLineGet(const LosTaskCB *allTaskArray) #ifdef LOSCFG_SHELL_CMD_DEBUG #define OS_PEND_REASON_MAX_LEN 20 -//shell检查任务等待标�? +//shell检查任务等待标? STATIC CHAR *OsShellCheckTaskWaitFlag(const LosTaskCB *taskCB, UINTPTR *lockID) { *lockID = taskCB->waitID; @@ -522,16 +526,24 @@ STATIC VOID OsProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosT { BOOL lockFlag = FALSE; UINT32 intSave = 0; - UINT32 processInfoLen; + UINT32 processInfoLen = OS_PROCESS_ALL_INFO_LEN; if (LOS_SpinHeld(&g_taskSpin) == FALSE) { SCHEDULER_LOCK(intSave); lockFlag = TRUE; } - processInfoLen = OsProcessInfoGet(pcbArray, group, memArray, flag); +#ifdef LOSCFG_KERNEL_VM + if (flag & OS_PROCESS_MEM_INFO) { + processInfoLen += OS_PROCESS_MEM_ALL_INFO_LEN; + } +#endif + + (VOID)memcpy_s(*pcbArray, OS_PROCESS_INFO_LEN, g_processCBArray, OS_PROCESS_INFO_LEN); *tcbArray = (LosTaskCB *)((UINTPTR)*pcbArray + processInfoLen); (VOID)memcpy_s(*tcbArray, OS_TASK_INFO_LEN, g_taskCBArray, OS_TASK_INFO_LEN); + + OsProcessInfoGet(pcbArray, group, memArray, tcbArray, flag); taskWaterLine = (UINT32 *)((UINTPTR)*tcbArray + OS_TASK_INFO_LEN); OsShellCmdTaskWaterLineGet(*tcbArray); if (lockFlag == TRUE) { diff --git a/kernel/base/mp/los_mp.c b/kernel/base/mp/los_mp.c index dc634539..4c8fad61 100644 --- a/kernel/base/mp/los_mp.c +++ b/kernel/base/mp/los_mp.c @@ -91,7 +91,7 @@ VOID OsMpScheduleHandler(VOID) * set schedule flag to differ from wake function, * so that the scheduler can be triggered at the end of irq. */ - OsPercpuGet()->schedFlag |= INT_PEND_RESCH;//贴上调度标签 + OsSchedRunQuePendingSet(); } ///硬中断暂停处理函数 VOID OsMpHaltHandler(VOID) diff --git a/kernel/base/mp/los_percpu.c b/kernel/base/mp/los_percpu.c index 6c285a6a..a48d18a9 100644 --- a/kernel/base/mp/los_percpu.c +++ b/kernel/base/mp/los_percpu.c @@ -30,7 +30,30 @@ */ #include "los_percpu_pri.h" +#include "los_printf.h" - +#ifdef LOSCFG_KERNEL_SMP Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; ///< CPU池,池大小由CPU核数决定 +VOID OsAllCpuStatusOutput(VOID) +{ + UINT32 i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + switch (g_percpu[i].excFlag) { + case CPU_RUNNING: + PrintExcInfo("cpu%u is running.\n", i); + break; + case CPU_HALT: + PrintExcInfo("cpu%u is halted.\n", i); + break; + case CPU_EXC: + PrintExcInfo("cpu%u is in exc.\n", i); + break; + default: + break; + } + } + PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid()); +} +#endif diff --git a/kernel/base/mp/los_spinlock.c b/kernel/base/mp/los_spinlock.c index 991af71d..63d7fb50 100644 --- a/kernel/base/mp/los_spinlock.c +++ b/kernel/base/mp/los_spinlock.c @@ -50,7 +50,7 @@ BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) VOID LOS_SpinLock(SPIN_LOCK_S *lock) { UINT32 intSave = LOS_IntLock(); - OsCpuSchedLock(OsPercpuGet()); + OsSchedLock(); LOS_IntRestore(intSave); LOCKDEP_CHECK_IN(lock); @@ -60,17 +60,22 @@ VOID LOS_SpinLock(SPIN_LOCK_S *lock) INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) { - Percpu *cpu = OsPercpuGet(); UINT32 intSave = LOS_IntLock(); - OsCpuSchedLock(cpu); + OsSchedLock(); LOS_IntRestore(intSave); INT32 ret = ArchSpinTrylock(&lock->rawLock); if (ret == LOS_OK) { LOCKDEP_CHECK_IN(lock); LOCKDEP_RECORD(lock); - } else { - OsCpuSchedUnlock(cpu, LOS_IntLock()); + return ret; + } + + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); } return ret; @@ -78,16 +83,22 @@ INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) { + UINT32 intSave; LOCKDEP_CHECK_OUT(lock); ArchSpinUnlock(&lock->rawLock); - OsCpuSchedUnlock(OsPercpuGet(), LOS_IntLock()); + intSave = LOS_IntLock(); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } } VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) { *intSave = LOS_IntLock(); - OsCpuSchedLock(OsPercpuGet()); + OsSchedLock(); LOCKDEP_CHECK_IN(lock); ArchSpinLock(&lock->rawLock); @@ -99,7 +110,11 @@ VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) LOCKDEP_CHECK_OUT(lock); ArchSpinUnlock(&lock->rawLock); - OsCpuSchedUnlock(OsPercpuGet(), intSave); + BOOL needSched = OsSchedUnlockResch(); + LOS_IntRestore(intSave); + if (needSched) { + LOS_Schedule(); + } } #endif diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index 7bd74667..a378c9fa 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -60,8 +60,9 @@ #define OS_SCHED_READY_MAX 30 ///< 某个任务优先级上挂的最大就绪任务数量 #define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */ -#define OS_CHECK_TASK_BLOCK (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_SUSPENDED) -/// 调度队列 +#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ + OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) + typedef struct { LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];///< 各优先级任务调度队列,默认32级 UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM]; ///< 各优先级就绪任务数 @@ -72,11 +73,10 @@ typedef struct { typedef struct { SchedQueue queueList[OS_PRIORITY_QUEUE_NUM];///< 进程优先级调度队列,默认32级 UINT32 queueBitmap;///< 进程优先级调度位图 - SchedScan taskScan;///< 函数指针,扫描任务的回调函数 - SchedScan swtmrScan;///< 函数指针,扫描定时器的回调函数 } Sched; -STATIC Sched *g_sched = NULL;///< 全局调度器 +SchedRunQue g_schedRunQue[LOSCFG_KERNEL_CORE_NUM]; +STATIC Sched g_sched; #ifdef LOSCFG_SCHED_TICK_DEBUG #define OS_SCHED_DEBUG_DATA_NUM 1000 @@ -133,7 +133,8 @@ UINT32 OsShellShowTickRespo(VOID) (VOID)memcpy_s((CHAR *)schedDebug, tickSize, (CHAR *)OsSchedDebugGet(), tickSize); (VOID)memset_s((CHAR *)OsSchedDebugGet(), tickSize, 0, tickSize); for (cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) { - sortLinkNum[cpu] = OsPercpuGetByID(cpu)->taskSortLink.nodeNum + OsPercpuGetByID(cpu)->swtmrSortLink.nodeNum; + SchedRunQue *rq = OsSchedRunQueByID(cpu); + sortLinkNum[cpu] = OsGetSortLinkNodeNum(&rq->taskSortLink) + OsGetSortLinkNodeNum(&rq->swtmrSortLink); } SCHEDULER_UNLOCK(intSave); @@ -238,7 +239,7 @@ UINT32 OsShellShowSchedParam(VOID) #endif /// 更新时间片 -STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) +STATIC INLINE VOID TimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) { LOS_ASSERT(currTime >= taskCB->startTime); //断言参数时间必须大于开始时间 @@ -260,34 +261,33 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime) #endif } /// 重置节拍器 -STATIC INLINE UINT64 GetNextExpireTime(Percpu *cpu, UINT64 startTime, UINT32 tickPrecision) +STATIC INLINE UINT64 GetNextExpireTime(SchedRunQue *rq, UINT64 startTime, UINT32 tickPrecision) { - SortLinkAttribute *taskHeader = &cpu->taskSortLink; - SortLinkAttribute *swtmrHeader = &cpu->swtmrSortLink; + SortLinkAttribute *taskHeader = &rq->taskSortLink; + SortLinkAttribute *swtmrHeader = &rq->swtmrSortLink; - LOS_SpinLock(&cpu->taskSortLinkSpin); + LOS_SpinLock(&taskHeader->spinLock); UINT64 taskExpireTime = OsGetSortLinkNextExpireTime(taskHeader, startTime, tickPrecision); - LOS_SpinUnlock(&cpu->taskSortLinkSpin); + LOS_SpinUnlock(&taskHeader->spinLock); - LOS_SpinLock(&cpu->swtmrSortLinkSpin); + LOS_SpinLock(&swtmrHeader->spinLock); UINT64 swtmrExpireTime = OsGetSortLinkNextExpireTime(swtmrHeader, startTime, tickPrecision); - LOS_SpinUnlock(&cpu->swtmrSortLinkSpin); + LOS_SpinUnlock(&swtmrHeader->spinLock); return (taskExpireTime < swtmrExpireTime) ? taskExpireTime : swtmrExpireTime; } -STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, - UINT64 taskEndTime, UINT32 oldResponseID) +STATIC INLINE VOID SchedSetNextExpireTime(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID) { - Percpu *currCpu = OsPercpuGet(); - UINT64 nextResponseTime = 0; + SchedRunQue *rq = OsSchedRunQue(); BOOL isTimeSlice = FALSE; - UINT64 nextExpireTime = GetNextExpireTime(currCpu, startTime, OS_TICK_RESPONSE_PRECISION); + UINT64 currTime = OsGetCurrSchedTimeCycle(); + UINT64 nextExpireTime = GetNextExpireTime(rq, currTime, OS_TICK_RESPONSE_PRECISION); - currCpu->schedFlag &= ~INT_PEND_TICK; - if (currCpu->responseID == oldResponseID) { + rq->schedFlag &= ~INT_PEND_TICK; + if (rq->responseID == oldResponseID) { /* This time has expired, and the next time the theory has expired is infinite */ - currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; } /* The current thread's time slice has been consumed, but the current system lock task cannot @@ -298,28 +298,20 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, isTimeSlice = TRUE; } - if ((currCpu->responseTime <= nextExpireTime) || - ((currCpu->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) { + if ((rq->responseTime <= nextExpireTime) || + ((rq->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) { return; } - UINT64 currTime = OsGetCurrSchedTimeCycle(); - if (nextExpireTime >= currTime) { - nextResponseTime = nextExpireTime - currTime; - } - - if (nextResponseTime < OS_TICK_RESPONSE_PRECISION) { - nextResponseTime = OS_TICK_RESPONSE_PRECISION; - } - if (isTimeSlice) { /* The expiration time of the current system is the thread's slice expiration time */ - currCpu->responseID = responseID; + rq->responseID = responseID; } else { - currCpu->responseID = OS_INVALID_VALUE; + rq->responseID = OS_INVALID_VALUE; } - currCpu->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); + UINT64 nextResponseTime = nextExpireTime - currTime; + rq->responseTime = currTime + HalClockTickTimerReload(nextResponseTime); #ifdef LOSCFG_SCHED_TICK_DEBUG SchedTickDebug *schedDebug = &g_schedTickDebug[ArchCurrCpuid()]; @@ -330,35 +322,34 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID, } /// 更新过期时间 -VOID OsSchedUpdateExpireTime(UINT64 startTime) +VOID OsSchedUpdateExpireTime(VOID) { UINT64 endTime; - Percpu *cpu = OsPercpuGet(); LosTaskCB *runTask = OsCurrTaskGet(); if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) {//如果中断发生中或调度未发生 - cpu->schedFlag |= INT_PEND_TICK;//因为时间到了,所以贴上因时间引起的调度标签 + OsSchedRunQuePendingSet(); return; } if (runTask->policy == LOS_SCHED_RR) {//抢占式调度计算出当前任务的到期时间,时间到了就需要切换到其他任务运行 LOS_SpinLock(&g_taskSpin); INT32 timeSlice = (runTask->timeSlice <= OS_TIME_SLICE_MIN) ? runTask->initTimeSlice : runTask->timeSlice;//修改时间片,以时钟周期为单位 + endTime = runTask->startTime + timeSlice; LOS_SpinUnlock(&g_taskSpin); - endTime = startTime + timeSlice; } else { endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } - OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, runTask->taskID); + SchedSetNextExpireTime(runTask->taskID, endTime, runTask->taskID); } /// 计算时间片,参数为进程优先级和任务优先级, 结论是同一个优先级下 任务越多,时间片越短 -STATIC INLINE UINT32 OsSchedCalculateTimeSlice(UINT16 proPriority, UINT16 priority) +STATIC INLINE UINT32 SchedCalculateTimeSlice(UINT16 proPriority, UINT16 priority) { UINT32 retTime; UINT32 readyTasks; - SchedQueue *queueList = &g_sched->queueList[proPriority];//拿到进程优先级调度队列 + SchedQueue *queueList = &g_sched.queueList[proPriority]; readyTasks = queueList->readyTasks[priority];//获取指定优先级的任务数量 if (readyTasks > OS_SCHED_READY_MAX) {//如果就绪任务很多 return OS_SCHED_TIME_SLICES_MIN;//给个最小时间片 5ms @@ -367,9 +358,9 @@ STATIC INLINE UINT32 OsSchedCalculateTimeSlice(UINT16 proPriority, UINT16 priori return (retTime + OS_SCHED_TIME_SLICES_MIN);// 20, 19.5, ... 5 } -STATIC INLINE VOID OsSchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) +STATIC INLINE VOID SchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) { - SchedQueue *queueList = &g_sched->queueList[proPriority]; + SchedQueue *queueList = &g_sched.queueList[proPriority]; LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; UINT32 *bitMap = &queueList->queueBitmap; @@ -381,7 +372,7 @@ STATIC INLINE VOID OsSchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *prique LOS_ASSERT(priqueueItem->pstNext == NULL); if (*bitMap == 0) { - g_sched->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; + g_sched.queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; } if (LOS_ListEmpty(&priQueueList[priority])) { //链表为空 @@ -392,9 +383,9 @@ STATIC INLINE VOID OsSchedPriQueueEnHead(UINT32 proPriority, LOS_DL_LIST *prique queueList->readyTasks[priority]++;//就绪任务数增加 } /// 从就绪任务优先级链表尾部插入 -STATIC INLINE VOID OsSchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) +STATIC INLINE VOID SchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) { - SchedQueue *queueList = &g_sched->queueList[proPriority]; + SchedQueue *queueList = &g_sched.queueList[proPriority]; LOS_DL_LIST *priQueueList = &queueList->priQueueList[0]; UINT32 *bitMap = &queueList->queueBitmap; @@ -406,7 +397,7 @@ STATIC INLINE VOID OsSchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *prique LOS_ASSERT(priqueueItem->pstNext == NULL); if (*bitMap == 0) { - g_sched->queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; + g_sched.queueBitmap |= PRIQUEUE_PRIOR0_BIT >> proPriority; } if (LOS_ListEmpty(&priQueueList[priority])) { @@ -417,9 +408,9 @@ STATIC INLINE VOID OsSchedPriQueueEnTail(UINT32 proPriority, LOS_DL_LIST *prique queueList->readyTasks[priority]++; } /// 1.找出指定优先级的调度队列 2.摘除指定任务优先级链表中的指定任务节点 -STATIC INLINE VOID OsSchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) +STATIC INLINE VOID SchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *priqueueItem, UINT32 priority) { - SchedQueue *queueList = &g_sched->queueList[proPriority];//找到进程优先级对应的调度队列 + SchedQueue *queueList = &g_sched.queueList[proPriority]; LOS_DL_LIST *priQueueList = &queueList->priQueueList[0];//获取首个链表 UINT32 *bitMap = &queueList->queueBitmap;//获取位图 @@ -430,104 +421,22 @@ STATIC INLINE VOID OsSchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *prique }// ...111001110 --> ...111000110 if (*bitMap == 0) {//如果变量变成0, 000000000 - g_sched->queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> proPriority);//将进程对应优先级的位 置0 - } -} -/// 唤醒因等待时间而阻塞的任务,例如在一个任务中执行 delay(100)这样的操作 -STATIC INLINE VOID OsSchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOOL *needSchedule) -{ -#ifndef LOSCFG_SCHED_DEBUG - (VOID)currTime; -#endif - - LOS_SpinLock(&g_taskSpin); - UINT16 tempStatus = taskCB->taskStatus; - if (tempStatus & (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) {//任务被挂起或被延迟执行 - taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY);//去掉这些标签 - if (tempStatus & OS_TASK_STATUS_PENDING) {//如果贴有挂起/待办标签 - taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT;//贴上时间到了的标签 - LOS_ListDelete(&taskCB->pendList);//从挂起/待办链表中删除 - taskCB->taskMux = NULL; - OsTaskWakeClearPendMask(taskCB); - } - - if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) { -#ifdef LOSCFG_SCHED_DEBUG - taskCB->schedStat.pendTime += currTime - taskCB->startTime; - taskCB->schedStat.pendCount++; -#endif - OsSchedTaskEnQueue(taskCB);//将任务加入就绪队列 - *needSchedule = TRUE; - } - } - - LOS_SpinUnlock(&g_taskSpin); -} -///扫描那些处于等待状态的任务是否时间到了 -STATIC INLINE BOOL OsSchedScanTimerList(VOID) -{ - Percpu *cpu = OsPercpuGet(); - BOOL needSchedule = FALSE; - SortLinkAttribute *taskSortLink = &OsPercpuGet()->taskSortLink;//获取本CPU核上挂的所有等待的任务排序链表 - LOS_DL_LIST *listObject = &taskSortLink->sortLink;//按到达时间从前到后排序 - /* - * When task is pended with timeout, the task block is on the timeout sortlink - * (per cpu) and ipc(mutex,sem and etc.)'s block at the same time, it can be waken - * up by either timeout or corresponding ipc it's waiting. - * - * Now synchronize sortlink preocedure is used, therefore the whole task scan needs - * to be protected, preventing another core from doing sortlink deletion at same time. - */ - LOS_SpinLock(&cpu->taskSortLinkSpin); - - if (LOS_ListEmpty(listObject)) { - LOS_SpinUnlock(&cpu->taskSortLinkSpin); - return needSchedule; - } - - SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//获取每个优先级上的任务链表头节点 - UINT64 currTime = OsGetCurrSchedTimeCycle();//获取当前时间 - while (sortList->responseTime <= currTime) {//到达时间小于当前时间,说明任务时间过了,需要去执行了 - LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(sortList, LosTaskCB, sortList);//获取任务实体 - OsDeleteNodeSortLink(taskSortLink, &taskCB->sortList);//从排序链表中删除 - LOS_SpinUnlock(&cpu->taskSortLinkSpin);//释放自旋锁 - - OsSchedWakePendTimeTask(currTime, taskCB, &needSchedule);//需要唤醒任务,加入就绪队列 - - LOS_SpinLock(&cpu->taskSortLinkSpin); - if (LOS_ListEmpty(listObject)) {//因为上面已经执行了删除操作,所以此处可能有空 - break;//为空则直接退出循环 - } - - sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//处理下一个节点 + g_sched.queueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> proPriority); } - - LOS_SpinUnlock(&cpu->taskSortLinkSpin); - - return needSchedule;//返回是否需要调度 } -/*! - * @brief OsSchedEnTaskQueue - * 添加任务到进程的就绪队列中 - * @param processCB - * @param taskCB - * @return - * - * @see - */ -STATIC INLINE VOID OsSchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) +STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB) { - LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY));//必须是就绪状态,因为只有就绪状态才能入就绪队列 + LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); switch (taskCB->policy) { - case LOS_SCHED_RR: {//抢占式跳读 - if (taskCB->timeSlice > OS_TIME_SLICE_MIN) {//时间片大于最小的时间片 50微妙 - OsSchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority);//插入对应优先级的就绪队列中 - } else {//如果时间片不够了,咋办? - taskCB->initTimeSlice = OsSchedCalculateTimeSlice(processCB->priority, taskCB->priority);//重新计算时间片 - taskCB->timeSlice = taskCB->initTimeSlice;// - OsSchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); + case LOS_SCHED_RR: { + if (taskCB->timeSlice > OS_TIME_SLICE_MIN) { + SchedPriQueueEnHead(taskCB->basePrio, &taskCB->pendList, taskCB->priority); + } else { + taskCB->initTimeSlice = SchedCalculateTimeSlice(taskCB->basePrio, taskCB->priority); + taskCB->timeSlice = taskCB->initTimeSlice; + SchedPriQueueEnTail(taskCB->basePrio, &taskCB->pendList, taskCB->priority); #ifdef LOSCFG_SCHED_DEBUG taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime; taskCB->schedStat.timeSliceCount++; @@ -538,11 +447,11 @@ STATIC INLINE VOID OsSchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB case LOS_SCHED_FIFO: { /* The time slice of FIFO is always greater than 0 unless the yield is called */ if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - OsSchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnHead(taskCB->basePrio, &taskCB->pendList, taskCB->priority); } else { taskCB->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; taskCB->timeSlice = taskCB->initTimeSlice; - OsSchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(taskCB->basePrio, &taskCB->pendList, taskCB->priority); } break; } @@ -558,111 +467,77 @@ STATIC INLINE VOID OsSchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; taskCB->taskStatus |= OS_TASK_STATUS_READY; - - processCB->processStatus &= ~(OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_PENDING); - processCB->processStatus |= OS_PROCESS_STATUS_READY; - processCB->readyTaskNum++; } -STATIC INLINE VOID OsSchedDeTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) -{ - if (taskCB->policy != LOS_SCHED_IDLE) { - OsSchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); - } - taskCB->taskStatus &= ~OS_TASK_STATUS_READY; - - processCB->readyTaskNum--; - if (processCB->readyTaskNum == 0) { - processCB->processStatus &= ~OS_PROCESS_STATUS_READY; - } -} -/// 将任务从就绪队列中删除 VOID OsSchedTaskDeQueue(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);//通过任务获取所在进程 - - if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//任务处于就绪状态 - OsSchedDeTaskQueue(taskCB, processCB);//从该进程的就绪任务队列中删除 - } - - if (processCB->processStatus & OS_PROCESS_STATUS_READY) { //进程处于就绪状态不能删除任务,这是为什么呢 ? @note_thinking - return; - } - - /* If the current process has only the current thread running, - * the process becomes blocked after the thread leaves the scheduling queue - * 如果当前进程只有当前任务在运行,任务离开调度队列后进程设置为阻塞状态 - * 注意:一个进程下的任务可能同时被多个CPU在并行运行. - */ - if (OS_PROCESS_GET_RUNTASK_COUNT(processCB->processStatus) == 1) { //根据数量来这只状态,注意 processStatus 承载了两重含义 - processCB->processStatus |= OS_PROCESS_STATUS_PENDING; //将进程状态设为阻塞状态 + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + if (taskCB->policy != LOS_SCHED_IDLE) { + SchedPriQueueDelete(taskCB->basePrio, &taskCB->pendList, taskCB->priority); + } + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; } } VOID OsSchedTaskEnQueue(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); #ifdef LOSCFG_SCHED_DEBUG if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { taskCB->startTime = OsGetCurrSchedTimeCycle(); } #endif - OsSchedEnTaskQueue(taskCB, processCB); + SchedEnTaskQueue(taskCB); } -/// 任务退出 + VOID OsSchedTaskExit(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - - if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//就绪状态 - OsSchedTaskDeQueue(taskCB);//从就绪队列中删除 - processCB->processStatus &= ~OS_PROCESS_STATUS_PENDING;//进程贴上非挂起标签 - } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { //挂起状态 - LOS_ListDelete(&taskCB->pendList); //从任务挂起链表中摘除 - taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING;////任务贴上非挂起标签 + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + OsSchedTaskDeQueue(taskCB); + } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { + LOS_ListDelete(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; } - if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) {//如果任务延期或因时挂起 - OsDeleteSortLink(&taskCB->sortList, OS_SORT_LINK_TASK);//从CPU的等待执行任务链表上摘除任务 - taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME);//撕掉这两个标签 + if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { + OsSchedDeTaskFromTimeList(&taskCB->sortList); + taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME); } } -///通过本函数可以看出 yield 的真正含义是主动让出CPU,那怎么安置自己呢? 跑到末尾重新排队. 真是个活雷锋,好同志啊!!! + VOID OsSchedYield(VOID) { LosTaskCB *runTask = OsCurrTaskGet(); - runTask->timeSlice = 0;//时间片变成0,代表主动让出运行时间. + runTask->timeSlice = 0; - runTask->startTime = OsGetCurrSchedTimeCycle();//重新获取开始时间 - OsSchedTaskEnQueue(runTask);//跑队尾排队 - OsSchedResched();//发起调度 + runTask->startTime = OsGetCurrSchedTimeCycle(); + OsSchedTaskEnQueue(runTask); + OsSchedResched(); } -///延期调度 + VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick) { - OsSchedTaskDeQueue(runTask);//将任务从就绪队列中删除 - runTask->taskStatus |= OS_TASK_STATUS_DELAY;//任务状态改成延期 - runTask->waitTimes = tick;//延期节拍数 + OsSchedTaskDeQueue(runTask); + runTask->taskStatus |= OS_TASK_STATUS_DELAY; + runTask->waitTimes = tick; - OsSchedResched();//既然本任务延期,就需要发起新的调度. + OsSchedResched(); } -///任务进入等待链表 + UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 ticks, BOOL needSched) { - LosTaskCB *runTask = OsCurrTaskGet();//获取当前任务 - OsSchedTaskDeQueue(runTask);//将任务从就绪队列中删除 + LosTaskCB *runTask = OsCurrTaskGet(); - runTask->taskStatus |= OS_TASK_STATUS_PENDING;//任务状态改成挂起/待办 - LOS_ListTailInsert(list, &runTask->pendList);//挂入挂起/待办链表 + runTask->taskStatus |= OS_TASK_STATUS_PENDING; + LOS_ListTailInsert(list, &runTask->pendList); - if (ticks != LOS_WAIT_FOREVER) {//如果不是永久的等待 - runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME;//标记为有时间的挂起/待办 - runTask->waitTimes = ticks;//要挂起/待办多久 + if (ticks != LOS_WAIT_FOREVER) { + runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; + runTask->waitTimes = ticks; } - if (needSched == TRUE) {//是否需要调度 - OsSchedResched();//申请调度,将切换任务上下文 + if (needSched == TRUE) { + OsSchedResched(); if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; return LOS_ERRNO_TSK_TIMEOUT; @@ -671,79 +546,76 @@ UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 ticks, BOOL needSched) return LOS_OK; } -///任务从等待链表中恢复,并从链表中摘除. + VOID OsSchedTaskWake(LosTaskCB *resumedTask) { - LOS_ListDelete(&resumedTask->pendList);// 1.先从待办链表上摘除 - resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING;//撕掉挂起标签 + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING; - if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) {//如果是有时间限制的挂起 - OsDeleteSortLink(&resumedTask->sortList, OS_SORT_LINK_TASK);//从任务的CPU执行链表上摘除任务节点 - resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;//撕掉挂起有时间限制标签 + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsSchedDeTaskFromTimeList(&resumedTask->sortList); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; } - if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {//如果有暂停标签 + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) { #ifdef LOSCFG_SCHED_DEBUG - resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;//记录暂停的时间 - resumedTask->schedStat.pendCount++;//暂停的次数增加 + resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime; + resumedTask->schedStat.pendCount++; #endif - OsSchedTaskEnQueue(resumedTask);//加入就绪链表 + OsSchedTaskEnQueue(resumedTask); } } -/// 修改任务调度参数 + BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16 priority) { - if (taskCB->policy != policy) {//如果调度方式不一致 + if (taskCB->policy != policy) { taskCB->policy = policy; - taskCB->timeSlice = 0;//时间片清0 + taskCB->timeSlice = 0; } - if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//如果是就绪状态 - OsSchedTaskDeQueue(taskCB);//从就绪队列删除 - taskCB->priority = priority;//设置任务优先级 - OsSchedTaskEnQueue(taskCB);//从尾部加入就绪队列 + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + OsSchedTaskDeQueue(taskCB); + taskCB->priority = priority; + OsSchedTaskEnQueue(taskCB); return TRUE; } - taskCB->priority = priority;//设置任务优先级 - OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, taskCB->priority);//向往通知某任务优先级改变了 - if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {//如果任务处于初始状态 - OsSchedTaskEnQueue(taskCB);//直接加入就绪队列, 进入就绪状态 + taskCB->priority = priority; + OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, taskCB->priority); + if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { + OsSchedTaskEnQueue(taskCB); return TRUE; } - if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//处于运行状态 + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { return TRUE; } return FALSE; } -/// 修改进程调度参数 -BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT16 priority) + +BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority) { + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); LosTaskCB *taskCB = NULL; BOOL needSched = FALSE; (VOID)policy; - if (processCB->processStatus & OS_PROCESS_STATUS_READY) {//如果是就绪状态 - LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {//遍历进程的任务链表 - if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//如果任务处于就绪状态 - OsSchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority);//先从原任务优先级链表中摘除任务 - OsSchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority);//在根据新优先级插入对应优先级链表中 - needSched = TRUE; - } + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + SchedPriQueueDelete(taskCB->basePrio, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority); + needSched = TRUE; + } else if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + needSched = TRUE; } - } - - processCB->priority = priority; - if (processCB->processStatus & OS_PROCESS_STATUS_RUNNING) { - needSched = TRUE; + taskCB->basePrio = priority; } return needSched; } -//冻结任务 -STATIC VOID OsSchedFreezeTask(LosTaskCB *taskCB) + +STATIC VOID SchedFreezeTask(LosTaskCB *taskCB) { UINT64 responseTime; @@ -756,13 +628,13 @@ STATIC VOID OsSchedFreezeTask(LosTaskCB *taskCB) } responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); - OsDeleteSortLink(&taskCB->sortList, OS_SORT_LINK_TASK); + OsSchedDeTaskFromTimeList(&taskCB->sortList); SET_SORTLIST_VALUE(&taskCB->sortList, responseTime); taskCB->taskStatus |= OS_TASK_FLAG_FREEZE; return; } -//解冻任务 -STATIC VOID OsSchedUnfreezeTask(LosTaskCB *taskCB) + +STATIC VOID SchedUnfreezeTask(LosTaskCB *taskCB) { UINT64 currTime, responseTime; UINT32 remainTick; @@ -776,7 +648,7 @@ STATIC VOID OsSchedUnfreezeTask(LosTaskCB *taskCB) responseTime = GET_SORTLIST_VALUE(&taskCB->sortList); if (responseTime > currTime) { remainTick = ((responseTime - currTime) + OS_CYCLE_PER_TICK - 1) / OS_CYCLE_PER_TICK; - OsAdd2SortLink(&taskCB->sortList, currTime, remainTick, OS_SORT_LINK_TASK); + OsSchedAddTask2TimeList(&taskCB->sortList, currTime, remainTick); return; } @@ -794,7 +666,7 @@ VOID OsSchedSuspend(LosTaskCB *taskCB) OsSchedTaskDeQueue(taskCB); } - OsSchedFreezeTask(taskCB); + SchedFreezeTask(taskCB); taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED; OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); @@ -807,118 +679,270 @@ BOOL OsSchedResume(LosTaskCB *taskCB) { BOOL needSched = FALSE; - OsSchedUnfreezeTask(taskCB); + SchedUnfreezeTask(taskCB); taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; - if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) { + if (!OsTaskIsBlocked(taskCB)) { OsSchedTaskEnQueue(taskCB); needSched = TRUE; } return needSched; } -//由时钟发起的调度 -VOID OsSchedTick(VOID) + +STATIC INLINE BOOL SchedScanSwtmrTimeList(SchedRunQue *rq) { - Sched *sched = g_sched; //获取全局调度器 - Percpu *currCpu = OsPercpuGet(); //获取当前CPU BOOL needSched = FALSE; + SortLinkAttribute* swtmrSortLink = &rq->swtmrSortLink; + LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; - if (currCpu->responseID == OS_INVALID_VALUE) { - if (sched->swtmrScan != NULL) { - (VOID)sched->swtmrScan();//扫描软件定时器 实体函数是: OsSwtmrScan - } + /* + * it needs to be carefully coped with, since the swtmr is in specific sortlink + * while other cores still has the chance to process it, like stop the timer. + */ + LOS_SpinLock(&swtmrSortLink->spinLock); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return FALSE; + } + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + + UINT64 currTime = OsGetCurrSchedTimeCycle(); + while (sortList->responseTime <= currTime) { + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + UINT64 startTime = GET_SORTLIST_VALUE(sortList); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlock(&swtmrSortLink->spinLock); - needSched = sched->taskScan();//扫描任务, 实体函数是: OsSchedScanTimerList + OsSwtmrWake(rq, startTime, sortList); + needSched = TRUE; - if (needSched) {//若需调度 - LOS_MpSchedule(OS_MP_CPU_ALL);//当前CPU向所有cpu发起核间中断,让其发生一次调度 - currCpu->schedFlag |= INT_PEND_RESCH; //内因触发的调度 + LOS_SpinLock(&swtmrSortLink->spinLock); + if (LOS_ListEmpty(listObject)) { + break; } + + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + } + + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return needSched; +} + +STATIC INLINE VOID SchedSwtmrResponseTimeReset(SchedRunQue *rq, UINT64 startTime) +{ + SortLinkAttribute* swtmrSortLink = &rq->swtmrSortLink; + LOS_DL_LIST *listHead = &swtmrSortLink->sortLink; + LOS_DL_LIST *listNext = listHead->pstNext; + + LOS_SpinLock(&swtmrSortLink->spinLock); + while (listNext != listHead) { + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode); + OsDeleteNodeSortLink(swtmrSortLink, sortList); + LOS_SpinUnlock(&swtmrSortLink->spinLock); + + OsSwtmrRestart(startTime, sortList); + + LOS_SpinLock(&swtmrSortLink->spinLock); + listNext = listNext->pstNext; } - currCpu->schedFlag |= INT_PEND_TICK; //贴上外因触发的调度,这个外因指的就是tick时间到了 - currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;//响应时间默认设最大 + LOS_SpinUnlock(&swtmrSortLink->spinLock); } -/// 设置空闲任务调度参数,空闲 -VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) + +STATIC INLINE BOOL SchedSwtmrRunQueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) { - idleTask->policy = LOS_SCHED_IDLE; //空闲方式,CPU没事干的时候就跑这个任务 - idleTask->initTimeSlice = OS_SCHED_FIFO_TIMEOUT;//初始时间片超大 - idleTask->timeSlice = idleTask->initTimeSlice;//剩余时间片超大 - OsSchedTaskEnQueue(idleTask);//加入就绪队列 + LOS_DL_LIST *listObject = &swtmrSortLink->sortLink; + LOS_DL_LIST *list = listObject->pstNext; + + LOS_SpinLock(&swtmrSortLink->spinLock); + while (list != listObject) { + SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode); + if (checkFunc((UINTPTR)listSorted, arg)) { + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return TRUE; + } + list = list->pstNext; + } + + LOS_SpinUnlock(&swtmrSortLink->spinLock); + return FALSE; } -/// 重置回应时间 -VOID OsSchedResetSchedResponseTime(UINT64 responseTime) + +BOOL OsSchedSwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) { - Percpu *cpu = OsPercpuGet(); - cpu->responseTime = responseTime; + for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + SchedRunQue *rq = OsSchedRunQueByID(cpuid); + SortLinkAttribute *swtmrSortLink = &rq->swtmrSortLink; + return SchedSwtmrRunQueFind(swtmrSortLink, checkFunc, arg); + } + return FALSE; } -/// 向全局调度器注册扫描软件定时器的回调函数 -UINT32 OsSchedSwtmrScanRegister(SchedScan func) + +STATIC INLINE VOID SchedWakePendTimeTask(UINT64 currTime, LosTaskCB *taskCB, BOOL *needSchedule) { - if (func == NULL) { - return LOS_NOK; +#ifndef LOSCFG_SCHED_DEBUG + (VOID)currTime; +#endif + + LOS_SpinLock(&g_taskSpin); + UINT16 tempStatus = taskCB->taskStatus; + if (tempStatus & (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) {//任务被挂起或被延迟执行 + taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY);//去掉这些标签 + if (tempStatus & OS_TASK_STATUS_PENDING) {//如果贴有挂起/待办标签 + taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT;//贴上时间到了的标签 + LOS_ListDelete(&taskCB->pendList);//从挂起/待办链表中删除 + taskCB->taskMux = NULL; + OsTaskWakeClearPendMask(taskCB); + } + + if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) { +#ifdef LOSCFG_SCHED_DEBUG + taskCB->schedStat.pendTime += currTime - taskCB->startTime; + taskCB->schedStat.pendCount++; +#endif + OsSchedTaskEnQueue(taskCB);//将任务加入就绪队列 + *needSchedule = TRUE; + } } - g_sched->swtmrScan = func;//正式注册, func 将在 OsSchedTick 中被回调 - return LOS_OK; + LOS_SpinUnlock(&g_taskSpin); } -///调度初始化 -UINT32 OsSchedInit(VOID) +///扫描那些处于等待状态的任务是否时间到了 +STATIC INLINE BOOL SchedScanTaskTimeList(SchedRunQue *rq) { - UINT16 index, pri; - UINT32 ret; + BOOL needSchedule = FALSE; + SortLinkAttribute *taskSortLink = &rq->taskSortLink; + LOS_DL_LIST *listObject = &taskSortLink->sortLink; + /* + * When task is pended with timeout, the task block is on the timeout sortlink + * (per cpu) and ipc(mutex,sem and etc.)'s block at the same time, it can be waken + * up by either timeout or corresponding ipc it's waiting. + * + * Now synchronize sortlink procedure is used, therefore the whole task scan needs + * to be protected, preventing another core from doing sortlink deletion at same time. + */ + LOS_SpinLock(&taskSortLink->spinLock); - g_sched = (Sched *)LOS_MemAlloc(m_aucSysMem0, sizeof(Sched));//分配调度器内存 - if (g_sched == NULL) { - return LOS_ERRNO_TSK_NO_MEMORY; + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&taskSortLink->spinLock); + return needSchedule; } - (VOID)memset_s(g_sched, sizeof(Sched), 0, sizeof(Sched)); + SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//获取每个优先级上的任务链表头节点 + UINT64 currTime = OsGetCurrSchedTimeCycle();//获取当前时间 + while (sortList->responseTime <= currTime) {//到达时间小于当前时间,说明任务时间过了,需要去执行了 + LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(sortList, LosTaskCB, sortList);//获取任务实体 + OsDeleteNodeSortLink(taskSortLink, &taskCB->sortList);//从排序链表中删除 + LOS_SpinUnlock(&taskSortLink->spinLock); + + SchedWakePendTimeTask(currTime, taskCB, &needSchedule); - for (index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) {//初始化进程优先级队列 - SchedQueue *queueList = &g_sched->queueList[index]; - LOS_DL_LIST *priList = &queueList->priQueueList[0];//每个进程优先级都有同样的任务优先级链表 - for (pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) { - LOS_ListInit(&priList[pri]);//初始化任务优先级链表节点 + LOS_SpinLock(&taskSortLink->spinLock); + if (LOS_ListEmpty(listObject)) {//因为上面已经执行了删除操作,所以此处可能有空 + break;//为空则直接退出循环 } + + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);//处理下一个节点 } - for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {//初始化每个CPU核 - Percpu *cpu = OsPercpuGetByID(index);//获取某个CPU信息 - ret = OsSortLinkInit(&cpu->taskSortLink);//初始化任务排序链表 - if (ret != LOS_OK) { - return LOS_ERRNO_TSK_NO_MEMORY; + LOS_SpinUnlock(&taskSortLink->spinLock); + + return needSchedule;//返回是否需要调度 +} + +VOID OsSchedTick(VOID) +{ + SchedRunQue *rq = OsSchedRunQue(); + BOOL needSched = FALSE; + + if (rq->responseID == OS_INVALID_VALUE) { + + needSched |= SchedScanSwtmrTimeList(rq); + needSched |= SchedScanTaskTimeList(rq); + + if (needSched) { + LOS_MpSchedule(OS_MP_CPU_ALL); + rq->schedFlag |= INT_PEND_RESCH; } - cpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME; - LOS_SpinInit(&cpu->taskSortLinkSpin);//自旋锁初始化 - LOS_SpinInit(&cpu->swtmrSortLinkSpin);//操作具体CPU核定时器排序链表 } + rq->schedFlag |= INT_PEND_TICK; + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; +} + +VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) +{ + idleTask->basePrio = OS_TASK_PRIORITY_LOWEST; + idleTask->policy = LOS_SCHED_IDLE; + idleTask->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; + idleTask->timeSlice = idleTask->initTimeSlice; + OsSchedTaskEnQueue(idleTask); +} + +VOID OsSchedResetSchedResponseTime(UINT64 responseTime) +{ + OsSchedRunQue()->responseTime = responseTime; +} + +VOID OsSchedRunQueInit(VOID) +{ + if (ArchCurrCpuid() != 0) { + return; + } + + for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + SchedRunQue *rq = OsSchedRunQueByID(index); + OsSortLinkInit(&rq->taskSortLink); + OsSortLinkInit(&rq->swtmrSortLink); + rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME; + } +} + +VOID OsSchedRunQueSwtmrInit(UINT32 swtmrTaskID, UINT32 swtmrQueue) +{ + SchedRunQue *rq = OsSchedRunQue(); + rq->swtmrTaskID = swtmrTaskID; + rq->swtmrHandlerQueue = swtmrQueue; +} + +VOID OsSchedRunQueIdleInit(UINT32 idleTaskID) +{ + SchedRunQue *rq = OsSchedRunQue(); + rq->idleTaskID = idleTaskID; +} - g_sched->taskScan = OsSchedScanTimerList;// 注册回调函数,扫描那些处于等待状态的任务是否时间到了,将在 OsSchedTick 中回调 +UINT32 OsSchedInit(VOID) +{ + for (UINT16 index = 0; index < OS_PRIORITY_QUEUE_NUM; index++) { + SchedQueue *queueList = &g_sched.queueList[index]; + LOS_DL_LIST *priList = &queueList->priQueueList[0]; + for (UINT16 pri = 0; pri < OS_PRIORITY_QUEUE_NUM; pri++) { + LOS_ListInit(&priList[pri]); + } + } #ifdef LOSCFG_SCHED_TICK_DEBUG - ret = OsSchedDebugInit(); + UINT32 ret = OsSchedDebugInit(); if (ret != LOS_OK) { return ret; } #endif return LOS_OK; } -/// 获取就绪队列中优先级最高的任务 -STATIC LosTaskCB *OsGetTopTask(VOID) + +STATIC LosTaskCB *GetTopTask(SchedRunQue *rq) { UINT32 priority, processPriority; UINT32 bitmap; LosTaskCB *newTask = NULL; - UINT32 processBitmap = g_sched->queueBitmap; + UINT32 processBitmap = g_sched.queueBitmap; #ifdef LOSCFG_KERNEL_SMP UINT32 cpuid = ArchCurrCpuid(); #endif while (processBitmap) { processPriority = CLZ(processBitmap); - SchedQueue *queueList = &g_sched->queueList[processPriority]; + SchedQueue *queueList = &g_sched.queueList[processPriority]; bitmap = queueList->queueBitmap; while (bitmap) { priority = CLZ(bitmap); @@ -936,10 +960,10 @@ STATIC LosTaskCB *OsGetTopTask(VOID) processBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - processPriority - 1)); } - newTask = OS_TCB_FROM_TID(OsPercpuGet()->idleTaskID); + newTask = OS_TCB_FROM_TID(rq->idleTaskID); FIND_TASK: - OsSchedDeTaskQueue(newTask, OS_PCB_FROM_PID(newTask->processID)); + OsSchedTaskDeQueue(newTask); return newTask; } ///CPU的调度开始,每个CPU核都会执行这个函数一次. @@ -956,12 +980,9 @@ VOID OsSchedStart(VOID) OsTickStart();//开始了属于本核的tick } - LosTaskCB *newTask = OsGetTopTask();//拿一个优先级最高的任务 - LosProcessCB *newProcess = OS_PCB_FROM_PID(newTask->processID);//获取该任务的进程实体 - - newTask->taskStatus |= OS_TASK_STATUS_RUNNING;//变成运行状态,注意此时该任务还没真正的运行 - newProcess->processStatus |= OS_PROCESS_STATUS_RUNNING;//processStatus 具有两重含义,将它设为正在运行状态,但注意这是在进程的角度,实际上底层还没有切到它运行. - newProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(newProcess->processStatus);//当前任务的数量也增加一个 + SchedRunQue *rq = OsSchedRunQue(); + LosTaskCB *newTask = GetTopTask(rq); + newTask->taskStatus |= OS_TASK_STATUS_RUNNING; #ifdef LOSCFG_KERNEL_SMP //注意:需要设置当前cpu,以防第一个任务删除可能会失败,因为此标志与实际当前 cpu 不匹配。 /* @@ -975,13 +996,13 @@ VOID OsSchedStart(VOID) newTask->startTime = OsGetCurrSchedTimeCycle(); - OsSwtmrResponseTimeReset(newTask->startTime); + SchedSwtmrResponseTimeReset(rq, newTask->startTime); /* System start schedule */ OS_SCHEDULER_SET(cpuid); - OsPercpuGet()->responseID = OS_INVALID; - OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, newTask->startTime + newTask->timeSlice, OS_INVALID); + rq->responseID = OS_INVALID; + SchedSetNextExpireTime(newTask->taskID, newTask->startTime + newTask->timeSlice, OS_INVALID); OsTaskContextLoad(newTask); } @@ -992,12 +1013,12 @@ VOID OsSchedToUserReleaseLock(VOID) LOCKDEP_CHECK_OUT(&g_taskSpin); ArchSpinUnlock(&g_taskSpin.rawLock); - OsPercpuGet()->taskLockCnt--; + OsSchedUnlock(); } #endif #ifdef LOSCFG_BASE_CORE_TSK_MONITOR -STATIC VOID OsTaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC VOID TaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) { if (!OS_STACK_MAGIC_CHECK(runTask->topOfStack)) { LOS_Panic("CURRENT task ID: %s:%d stack overflow!\n", runTask->taskName, runTask->taskID); @@ -1011,35 +1032,14 @@ STATIC VOID OsTaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask) } #endif -STATIC INLINE VOID OsSchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC INLINE VOID SchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) { #ifdef LOSCFG_BASE_CORE_TSK_MONITOR - OsTaskStackCheck(runTask, newTask); + TaskStackCheck(runTask, newTask); #endif /* LOSCFG_BASE_CORE_TSK_MONITOR */ OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask); } -STATIC INLINE VOID OsSchedSwitchProcess(LosProcessCB *runProcess, LosProcessCB *newProcess) -{ - runProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_DEC(runProcess->processStatus); - newProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(newProcess->processStatus); - - LOS_ASSERT(!(OS_PROCESS_GET_RUNTASK_COUNT(newProcess->processStatus) > LOSCFG_KERNEL_CORE_NUM)); - if (OS_PROCESS_GET_RUNTASK_COUNT(runProcess->processStatus) == 0) { - runProcess->processStatus &= ~OS_PROCESS_STATUS_RUNNING; - } - - LOS_ASSERT(!(newProcess->processStatus & OS_PROCESS_STATUS_PENDING)); - newProcess->processStatus |= OS_PROCESS_STATUS_RUNNING; - -#ifdef LOSCFG_KERNEL_VM - if (OsProcessIsUserMode(newProcess)) { - LOS_ArchMmuContextSwitch(&newProcess->vmSpace->archMmu); - } -#endif - - OsCurrProcessSet(newProcess); -} /*! * @brief OsSchedTaskSwitch 实现新老两个任务切换 @@ -1050,11 +1050,11 @@ STATIC INLINE VOID OsSchedSwitchProcess(LosProcessCB *runProcess, LosProcessCB * * * @see */ -STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) +STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) { UINT64 endTime; - OsSchedSwitchCheck(runTask, newTask);//任务内容检查 + SchedSwitchCheck(runTask, newTask); runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING; //当前任务去掉正在运行的标签 newTask->taskStatus |= OS_TASK_STATUS_RUNNING; //新任务贴上正在运行的标签,虽标签贴上了,但目前还是在老任务中跑. @@ -1066,15 +1066,11 @@ STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) #endif OsCurrTaskSet((VOID *)newTask);//设置新任务为当前任务 - LosProcessCB *newProcess = OS_PCB_FROM_PID(newTask->processID);//获取新任务所在进程实体 - LosProcessCB *runProcess = OS_PCB_FROM_PID(runTask->processID);//获取老任务所在进程实体 - if (runProcess != newProcess) {//如果不是同一个进程,就需要换行进程上下文,也就是切换MMU,切换进程空间 - OsSchedSwitchProcess(runProcess, newProcess);//切换进程上下文 - } - - if (OsProcessIsUserMode(newProcess)) {//如果是用户模式即应用进程 - OsCurrUserTaskSet(newTask->userArea);//设置用户态栈空间 +#ifdef LOSCFG_KERNEL_VM + if (newTask->archMmu != runTask->archMmu) { + LOS_ArchMmuContextSwitch((LosArchMmu *)newTask->archMmu); } +#endif #ifdef LOSCFG_KERNEL_CPUP OsCpupCycleEndStart(runTask->taskID, newTask->taskID); @@ -1091,10 +1087,10 @@ STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) /* The currently running task is blocked */ newTask->startTime = OsGetCurrSchedTimeCycle();//重新获取时间 /* The task is in a blocking state and needs to update its time slice before pend */ - OsTimeSliceUpdate(runTask, newTask->startTime);//更新时间片 - //两种状态下将老任务放入CPU的工作链表中 + TimeSliceUpdate(runTask, newTask->startTime); + if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) { - OsAdd2SortLink(&runTask->sortList, runTask->startTime, runTask->waitTimes, OS_SORT_LINK_TASK); + OsSchedAddTask2TimeList(&runTask->sortList, runTask->startTime, runTask->waitTimes); } } @@ -1103,7 +1099,7 @@ STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) } else { endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION; } - OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime, runTask->taskID); + SchedSetNextExpireTime(newTask->taskID, endTime, runTask->taskID); #ifdef LOSCFG_SCHED_DEBUG newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime; @@ -1117,24 +1113,24 @@ STATIC VOID OsSchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) VOID OsSchedIrqEndCheckNeedSched(VOID) { - Percpu *percpu = OsPercpuGet(); + SchedRunQue *rq = OsSchedRunQue(); LosTaskCB *runTask = OsCurrTaskGet(); - OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); + TimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); if (runTask->timeSlice <= OS_TIME_SLICE_MIN) { - percpu->schedFlag |= INT_PEND_RESCH; + rq->schedFlag |= INT_PEND_RESCH; } - if (OsPreemptable() && (percpu->schedFlag & INT_PEND_RESCH)) { - percpu->schedFlag &= ~INT_PEND_RESCH; + if (OsPreemptable() && (rq->schedFlag & INT_PEND_RESCH)) { + rq->schedFlag &= ~INT_PEND_RESCH; LOS_SpinLock(&g_taskSpin); OsSchedTaskEnQueue(runTask); - LosTaskCB *newTask = OsGetTopTask(); + LosTaskCB *newTask = GetTopTask(rq); if (runTask != newTask) { - OsSchedTaskSwitch(runTask, newTask); + SchedTaskSwitch(runTask, newTask); LOS_SpinUnlock(&g_taskSpin); return; } @@ -1142,59 +1138,53 @@ VOID OsSchedIrqEndCheckNeedSched(VOID) LOS_SpinUnlock(&g_taskSpin); } - if (percpu->schedFlag & INT_PEND_TICK) { - OsSchedUpdateExpireTime(runTask->startTime); + if (rq->schedFlag & INT_PEND_TICK) { + OsSchedUpdateExpireTime(); } } -/// 申请一次调度 + VOID OsSchedResched(VOID) { LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + SchedRunQue *rq = OsSchedRunQue(); #ifdef LOSCFG_KERNEL_SMP - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 1); // @note_thinking 为何此处一定得 == 1, 大于1不行吗? + LOS_ASSERT(rq->taskLockCnt == 1); #else - LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0); + LOS_ASSERT(rq->taskLockCnt == 0); #endif - OsPercpuGet()->schedFlag &= ~INT_PEND_RESCH;//去掉标签 + rq->schedFlag &= ~INT_PEND_RESCH; LosTaskCB *runTask = OsCurrTaskGet(); - LosTaskCB *newTask = OsGetTopTask();//获取最高优先级任务 + LosTaskCB *newTask = GetTopTask(rq); if (runTask == newTask) { return; } - OsSchedTaskSwitch(runTask, newTask);//CPU将真正的换任务执行 + SchedTaskSwitch(runTask, newTask); } -/*! - * @brief LOS_Schedule 任务调度主函数,触发系统调度 - * - * @return - * - * @see - */ VOID LOS_Schedule(VOID) { UINT32 intSave; LosTaskCB *runTask = OsCurrTaskGet(); - if (OS_INT_ACTIVE) { //中断发生中...,需停止调度 - OsPercpuGet()->schedFlag |= INT_PEND_RESCH;//贴上原因 + if (OS_INT_ACTIVE) { + OsSchedRunQuePendingSet(); return; } - if (!OsPreemptable()) {//当不可抢占时直接返回 + if (!OsPreemptable()) { return; } /* * trigger schedule in task will also do the slice check - * if neccessary, it will give up the timeslice more in time. - * otherwhise, there's no other side effects. + * if necessary, it will give up the timeslice more in time. + * otherwise, there's no other side effects. */ SCHEDULER_LOCK(intSave); - OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle());//更新时间片 + TimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle()); /* add run task back to ready queue | 添加任务到就绪队列*/ OsSchedTaskEnQueue(runTask); diff --git a/kernel/base/sched/sched_sq/los_sortlink.c b/kernel/base/sched/sched_sq/los_sortlink.c index 672d326c..b4d20f6e 100644 --- a/kernel/base/sched/sched_sq/los_sortlink.c +++ b/kernel/base/sched/sched_sq/los_sortlink.c @@ -30,17 +30,13 @@ */ #include "los_sortlink_pri.h" -#include "los_memory.h" -#include "los_exc.h" -#include "los_percpu_pri.h" -#include "los_sched_pri.h" #include "los_mp.h" /// 排序链表初始化 -UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) +VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader) { - LOS_ListInit(&sortLinkHeader->sortLink);//初始化双向链表 - sortLinkHeader->nodeNum = 0;//nodeNum背后的含义是记录需要CPU工作的数量 - return LOS_OK; + LOS_ListInit(&sortLinkHeader->sortLink); + LOS_SpinInit(&sortLinkHeader->spinLock); + sortLinkHeader->nodeNum = 0; } /*! @@ -52,7 +48,7 @@ UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) * * @see */ -STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +STATIC INLINE VOID AddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) { LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; //获取双向链表 @@ -86,121 +82,50 @@ STATIC INLINE VOID OsAddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLin } while (1);//死循环 } -/// 根据函数的具体实现,这个函数应该是找出最空闲的CPU, 函数的实现有待优化, @note_thinking -STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID) +VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu) { - Percpu *idleCpu = OsPercpuGetByID(0); //获取0号CPU,0号CPU也可称主核 - *idleCpuID = 0; - -#ifdef LOSCFG_KERNEL_SMP //多核情况下 - UINT16 cpuID = 1; - UINT32 nodeNum = idleCpu->taskSortLink.nodeNum + idleCpu->swtmrSortLink.nodeNum; //获取还未跑完的工作数量 - //cpu执行两种工作: 1.普通任务 2.软件定时器 - do { - Percpu *cpu = OsPercpuGetByID(cpuID); //一个个cpu遍历 - UINT32 temp = cpu->taskSortLink.nodeNum + cpu->swtmrSortLink.nodeNum;//获取cpu的工作量 - if (nodeNum > temp) {//对工作量比较 - idleCpu = cpu;//取工作量最小的cpu实体 - *idleCpuID = cpuID;//获取cpu id - } - - cpuID++;//下一个cpu id - } while (cpuID < LOSCFG_KERNEL_CORE_NUM); + LOS_SpinLock(&head->spinLock); + SET_SORTLIST_VALUE(node, responseTime); + AddNode2SortLink(head, node); +#ifdef LOSCFG_KERNEL_SMP + node->cpuid = idleCpu; #endif + LOS_SpinUnlock(&head->spinLock); - return idleCpu; -} -/// 向cpu的排序链表上添加指定节点 -VOID OsAdd2SortLink(SortLinkList *node, UINT64 startTime, UINT32 waitTicks, SortLinkType type) -{ - Percpu *cpu = NULL; - SortLinkAttribute *sortLinkHeader = NULL; - SPIN_LOCK_S *spinLock = NULL; - UINT16 idleCpu; - - if (OS_SCHEDULER_ACTIVE) {//当前CPU正在调度 - cpu = OsFindIdleCpu(&idleCpu);//找一个最空闲的CPU - } else { - idleCpu = ArchCurrCpuid();//使用当前cpu - cpu = OsPercpuGet(); - } - - if (type == OS_SORT_LINK_TASK) {//任务类型 - sortLinkHeader = &cpu->taskSortLink; //获取任务链表 - spinLock = &cpu->taskSortLinkSpin; - } else if (type == OS_SORT_LINK_SWTMR) {//软件定时器类型 - sortLinkHeader = &cpu->swtmrSortLink;//获取软件定时器链表 - spinLock = &cpu->swtmrSortLinkSpin; - } else { - LOS_Panic("Sort link type error : %u\n", type); - } - - LOS_SpinLock(spinLock); - SET_SORTLIST_VALUE(node, startTime + (UINT64)waitTicks * OS_CYCLE_PER_TICK);//设置节点响应时间 - OsAddNode2SortLink(sortLinkHeader, node);//插入节点 #ifdef LOSCFG_KERNEL_SMP - node->cpuid = idleCpu; - if (idleCpu != ArchCurrCpuid()) { //如果插入的链表不是当前CPU的链表 - LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu));//核间中断,对该CPU发生一次调度申请 + if (idleCpu != ArchCurrCpuid()) { + LOS_MpSchedule(CPUID_TO_AFFI_MASK(idleCpu)); } #endif - LOS_SpinUnlock(spinLock); } -/// 从cpu的排序链表上摘除指定节点 -VOID OsDeleteSortLink(SortLinkList *node, SortLinkType type) -{ -#ifdef LOSCFG_KERNEL_SMP - Percpu *cpu = OsPercpuGetByID(node->cpuid);//获取CPU -#else - Percpu *cpu = OsPercpuGetByID(0); -#endif - SPIN_LOCK_S *spinLock = NULL; - SortLinkAttribute *sortLinkHeader = NULL; - if (type == OS_SORT_LINK_TASK) {//当为任务时 - sortLinkHeader = &cpu->taskSortLink;//获取该CPU的任务链表 - spinLock = &cpu->taskSortLinkSpin; - } else if (type == OS_SORT_LINK_SWTMR) { - sortLinkHeader = &cpu->swtmrSortLink;//获取该CPU的定时器链表 - spinLock = &cpu->swtmrSortLinkSpin; - } else { - LOS_Panic("Sort link type error : %u\n", type); - } - - LOS_SpinLock(spinLock); +VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node) +{ + LOS_SpinLock(&head->spinLock); if (node->responseTime != OS_SORT_LINK_INVALID_TIME) { - OsDeleteNodeSortLink(sortLinkHeader, node);//从CPU的执行链表上摘除 + OsDeleteNodeSortLink(head, node); } - LOS_SpinUnlock(spinLock); + LOS_SpinUnlock(&head->spinLock); } -/*! - * @brief OsSortLinkGetTargetExpireTime - * 返回离触发目标时间的tick数 - * @param targetSortList - * @return - * - * @see - */ -UINT32 OsSortLinkGetTargetExpireTime(const SortLinkList *targetSortList) +UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList) { - UINT64 currTimes = OsGetCurrSchedTimeCycle(); - if (currTimes >= targetSortList->responseTime) { + if (currTime >= targetSortList->responseTime) { return 0; } - return (UINT32)(targetSortList->responseTime - currTimes) / OS_CYCLE_PER_TICK;//响应时间减去当前时间置算出剩余tick数 + return (UINT32)(targetSortList->responseTime - currTime); } -UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) +UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader) { LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; if (LOS_ListEmpty(head)) { - return 0; + return OS_SORT_LINK_INVALID_TIME; } SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); - return OsSortLinkGetTargetExpireTime(listSorted); + return OsSortLinkGetTargetExpireTime(currTime, listSorted); } diff --git a/kernel/common/los_config.c b/kernel/common/los_config.c index 206c686d..20ed8982 100644 --- a/kernel/common/los_config.c +++ b/kernel/common/los_config.c @@ -48,6 +48,7 @@ #include "los_spinlock.h" #include "los_swtmr_pri.h" #include "los_task_pri.h" +#include "los_sched_pri.h" #include "los_tick.h" #include "los_vm_boot.h" #include "los_smp.h" @@ -72,6 +73,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 EarliestInit(VOID) /* Must be placed at the beginning of the boot process *///必须放在启动过程的开头 OsSetMainTask();//为每个CPU核设置临时主任务 OsCurrTaskSet(OsGetMainTask());//设置当前任务 + OsSchedRunQueInit(); g_sysClock = OS_SYS_CLOCK; g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND; diff --git a/kernel/extended/dynload/include/los_load_elf.h b/kernel/extended/dynload/include/los_load_elf.h index 3ae9cc69..baa97b33 100644 --- a/kernel/extended/dynload/include/los_load_elf.h +++ b/kernel/extended/dynload/include/los_load_elf.h @@ -129,6 +129,7 @@ STATIC INLINE BOOL OsIsBadUserAddress(VADDR_T vaddr) return (vaddr >= USER_STACK_TOP_MAX); } +extern UINT32 OsGetRndOffset(INT32 randomDevFD); extern INT32 OsLoadELFFile(ELFLoadInfo *loadInfo); #ifdef __cplusplus diff --git a/kernel/extended/dynload/src/los_load_elf.c b/kernel/extended/dynload/src/los_load_elf.c index badad451..f60d2b9a 100644 --- a/kernel/extended/dynload/src/los_load_elf.c +++ b/kernel/extended/dynload/src/los_load_elf.c @@ -716,18 +716,18 @@ STATIC INT32 OsGetParamNum(CHAR *const *argv) return count; } -STATIC UINT32 OsGetRndOffset(const ELFLoadInfo *loadInfo) +UINT32 OsGetRndOffset(INT32 randomDevFD) { UINT32 randomValue = 0; #ifdef LOSCFG_ASLR - if (read(loadInfo->randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) { + if (read(randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) { randomValue &= RANDOM_MASK; } else { randomValue = (UINT32)random() & RANDOM_MASK; } #else - (VOID)loadInfo; + (VOID)randomDevFD; #endif return ROUNDDOWN(randomValue, PAGE_SIZE); @@ -805,7 +805,7 @@ STATIC INT32 OsSetArgParams(ELFLoadInfo *loadInfo, CHAR *const *argv, CHAR *cons if (((UINT32)loadInfo->stackProt & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)) { return -ENOEXEC; } - loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo); + loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo->randomDevFD); loadInfo->stackBase = loadInfo->stackTopMax - USER_STACK_SIZE; loadInfo->stackSize = USER_STACK_SIZE; loadInfo->stackParamBase = loadInfo->stackTopMax - USER_PARAM_BYTE_MAX; @@ -963,7 +963,7 @@ STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo) loadInfo->loadAddr = 0; if (loadInfo->execInfo.elfEhdr.elfType == LD_ET_DYN) { - loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo); + loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo->randomDevFD); mapSize = OsGetAllocSize(elfPhdrTemp, loadInfo->execInfo.elfEhdr.elfPhNum); if (mapSize == 0) { PRINT_ERR("%s[%d], Failed to get allocation size of file: %s!\n", __FUNCTION__, __LINE__, @@ -1009,17 +1009,7 @@ STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo) STATIC VOID OsFlushAspace(ELFLoadInfo *loadInfo) { - LosProcessCB *processCB = OsCurrProcessGet(); - - OsExecDestroyTaskGroup(); - - loadInfo->oldSpace = processCB->vmSpace; - processCB->vmSpace = loadInfo->newSpace; - processCB->vmSpace->heapBase += OsGetRndOffset(loadInfo); - processCB->vmSpace->heapNow = processCB->vmSpace->heapBase; - processCB->vmSpace->mapBase += OsGetRndOffset(loadInfo); - processCB->vmSpace->mapSize = loadInfo->stackBase - processCB->vmSpace->mapBase; - LOS_ArchMmuContextSwitch(&OsCurrProcessGet()->vmSpace->archMmu); + loadInfo->oldSpace = OsExecProcessVmSpaceReplace(loadInfo->newSpace, loadInfo->stackBase, loadInfo->randomDevFD); } STATIC VOID OsDeInitLoadInfo(ELFLoadInfo *loadInfo) @@ -1079,8 +1069,7 @@ INT32 OsLoadELFFile(ELFLoadInfo *loadInfo) ret = OsLoadELFSegment(loadInfo); if (ret != LOS_OK) { - OsCurrProcessGet()->vmSpace = loadInfo->oldSpace; - LOS_ArchMmuContextSwitch(&OsCurrProcessGet()->vmSpace->archMmu); + OsExecProcessVmSpaceRestore(loadInfo->oldSpace); goto OUT; } diff --git a/kernel/extended/liteipc/hm_liteipc.c b/kernel/extended/liteipc/hm_liteipc.c index 4004d1c6..150772ba 100644 --- a/kernel/extended/liteipc/hm_liteipc.c +++ b/kernel/extended/liteipc/hm_liteipc.c @@ -299,7 +299,7 @@ ERROR_REGION_OUT: LITE_OS_SEC_TEXT_INIT STATIC UINT32 LiteIpcPoolInit(ProcIpcInfo *ipcInfo) { ipcInfo->pool.uvaddr = NULL; - ipcInfo->pool.kvaddr = NULL + ipcInfo->pool.kvaddr = NULL; ipcInfo->pool.poolSize = 0; ipcInfo->ipcTaskID = INVAILD_ID; LOS_ListInit(&ipcInfo->ipcUsedNodelist);//上面将挂已使用的节点 @@ -765,7 +765,10 @@ LITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID) return FALSE; } tcb = OS_TCB_FROM_TID(taskID); //获取任务控制块 - if (!OsProcessIsUserMode(OS_PCB_FROM_PID(tcb->processID))) {//判断是否为用户进程 + if (!OsTaskIsUserMode(tcb)) { + return FALSE; + } + if (OsTaskIsUnused(tcb)) { return FALSE; } if (OsTaskIsInactive(tcb)) {//任务是否活跃 diff --git a/kernel/extended/pipes/BUILD.gn b/kernel/extended/pipes/BUILD.gn index 85058ea0..5d589735 100644 --- a/kernel/extended/pipes/BUILD.gn +++ b/kernel/extended/pipes/BUILD.gn @@ -28,19 +28,16 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/NuttX/NuttX.gni") module_switch = defined(LOSCFG_KERNEL_PIPE) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { - sources = [ - "//third_party/NuttX/drivers/pipes/fifo.c", - "//third_party/NuttX/drivers/pipes/pipe.c", - "//third_party/NuttX/drivers/pipes/pipe_common.c", - ] + sources = NUTTX_DRIVERS_PIPES_SRC_FILES public_configs = [ ":public" ] } config("public") { - include_dirs = [ "//third_party/NuttX/drivers/pipes" ] + include_dirs = NUTTX_DRIVERS_PIPES_INCLUDE_DIRS } diff --git a/kernel/extended/power/los_pm.c b/kernel/extended/power/los_pm.c index 073560c3..d6838aed 100644 --- a/kernel/extended/power/los_pm.c +++ b/kernel/extended/power/los_pm.c @@ -224,7 +224,6 @@ STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm) LOS_SysSleepEnum mode; UINT32 prepare = 0; BOOL tickTimerStop = FALSE; - UINT64 currTime; ret = OsPmSuspendCheck(pm, &sysSuspendEarly, &deviceSuspend, &mode); if (ret != LOS_OK) { @@ -247,9 +246,8 @@ STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm) tickTimerStop = OsPmTickTimerStop(pm); if (!tickTimerStop) { - currTime = OsGetCurrSchedTimeCycle(); OsSchedResetSchedResponseTime(0); - OsSchedUpdateExpireTime(currTime); + OsSchedUpdateExpireTime(); } OsPmCpuSuspend(pm); diff --git a/kernel/extended/trace/los_trace.c b/kernel/extended/trace/los_trace.c index 01fec29b..7ca72703 100644 --- a/kernel/extended/trace/los_trace.c +++ b/kernel/extended/trace/los_trace.c @@ -72,6 +72,7 @@ #include "trace_cnv.h" #include "los_init.h" #include "los_process.h" +#include "los_sched_pri.h" #ifdef LOSCFG_KERNEL_SMP #include "los_mp.h" @@ -137,7 +138,7 @@ STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR id #ifdef LOSCFG_TRACE_FRAME_CORE_MSG frame->core.cpuId = ArchCurrCpuid(); frame->core.hwiActive = OS_INT_ACTIVE ? TRUE : FALSE; - frame->core.taskLockCnt = MIN(OsPercpuGet()->taskLockCnt, 0xF); /* taskLockCnt is 4 bits, max value = 0xF */ + frame->core.taskLockCnt = MIN(OsSchedLockCountGet(), 0xF); /* taskLockCnt is 4 bits, max value = 0xF */ frame->core.paramCount = paramCount; #endif diff --git a/lib/libc/BUILD.gn b/lib/libc/BUILD.gn index c5beae17..6df2221c 100644 --- a/lib/libc/BUILD.gn +++ b/lib/libc/BUILD.gn @@ -30,8 +30,8 @@ import("//kernel/liteos_a/liteos.gni") MUSLDIR = "$LITEOSTHIRDPARTY/musl" -OPTRTDIR = "$LITEOSTHIRDPARTY/optimized-routines" +import("//third_party/optimized-routines/optimized-routines.gni") import("$MUSLDIR/porting/liteos_a/kernel/musl.gni") module_switch = defined(LOSCFG_LIB_LIBC) @@ -54,13 +54,7 @@ kernel_module(module_name) { "$MUSLPORTINGDIR/src/string/strcpy.c", "$MUSLPORTINGDIR/src/string/strlen.c", ] - sources += [ - "$OPTRTDIR/string/arm/memchr.S", - "$OPTRTDIR/string/arm/memcpy.S", - "$OPTRTDIR/string/arm/strcmp.S", - "$OPTRTDIR/string/arm/strcpy.c", - "$OPTRTDIR/string/arm/strlen-armv6t2.S", - ] + sources += OPTRT_STRING_ARM_SRC_FILES asmflags = [ "-D__strlen_armv6t2=strlen", "-D__strcmp_arm=strcmp", diff --git a/lib/libscrew/BUILD.gn b/lib/libscrew/BUILD.gn index 227fced9..e3cb2647 100644 --- a/lib/libscrew/BUILD.gn +++ b/lib/libscrew/BUILD.gn @@ -28,6 +28,7 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import("//kernel/liteos_a/liteos.gni") +import("//third_party/FreeBSD/FreeBSD.gni") module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { @@ -38,7 +39,7 @@ kernel_module(module_name) { "src/los_seq_buf.c", ] - sources += [ "$LITEOSTHIRDPARTY/FreeBSD/sys/libkern/crc32.c" ] + sources += FREEBSD_SYS_LIBKERN_SRC_FILES public_configs = [ ":public" ] } diff --git a/net/telnet/src/telnet_dev.c b/net/telnet/src/telnet_dev.c index 1f6d8b18..3a190aed 100644 --- a/net/telnet/src/telnet_dev.c +++ b/net/telnet/src/telnet_dev.c @@ -271,7 +271,7 @@ STATIC ssize_t TelnetWrite(struct file *file, const CHAR *buf, const size_t bufL if (telnetDev->clientFd != 0) { #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE /* DO NOT call blocking API in software timer task | 不要在软件定时器任务中调用阻塞 API */ - if (((LosTaskCB*)OsCurrTaskGet())->taskEntry == (TSK_ENTRY_FUNC)OsSwtmrTask) { + if (OsIsSwtmrTask(OsCurrTaskGet())) { TelnetUnlock(); return ret; } diff --git a/shell/full/src/cmds/hwi_shellcmd.c b/shell/full/src/cmds/hwi_shellcmd.c index 5b755504..d36aefbf 100644 --- a/shell/full/src/cmds/hwi_shellcmd.c +++ b/shell/full/src/cmds/hwi_shellcmd.c @@ -35,6 +35,7 @@ #include "los_cpup_pri.h" #endif #include "los_hwi_pri.h" +#include "los_sys_pri.h" #include "shcmd.h" diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index 432d9ebd..280d8878 100644 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -949,7 +949,6 @@ EXIT: int SysUserThreadDetach(unsigned int taskID) { unsigned int intSave; - LosTaskCB *taskCB = NULL; unsigned int ret; if (OS_TID_CHECK_INVALID(taskID)) { @@ -957,14 +956,13 @@ int SysUserThreadDetach(unsigned int taskID) } SCHEDULER_LOCK(intSave); - taskCB = OS_TCB_FROM_TID(taskID); - ret = OsUserTaskOperatePermissionsCheck(taskCB); + ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); + SCHEDULER_UNLOCK(intSave); if (ret != LOS_OK) { - SCHEDULER_UNLOCK(intSave); return ret; } - ret = OsTaskDeleteUnsafe(taskCB, OS_PRO_EXIT_OK, intSave); + ret = LOS_TaskDelete(taskID); if (ret != LOS_OK) { return ESRCH; } @@ -998,12 +996,13 @@ EXIT: void SysUserExitGroup(int status) { - OsTaskExitGroup((unsigned int)status); + (void)status; + OsProcessThreadGroupDestroy(); } -/// 系统调用线程退出 + void SysThreadExit(int status) { - OsTaskToExit(OsCurrTaskGet(), (unsigned int)status); + OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status); } /*! diff --git a/testsuites/unittest/net/netdb/config.gni b/testsuites/unittest/net/netdb/config.gni index 32a188fc..2c1702ad 100644 --- a/testsuites/unittest/net/netdb/config.gni +++ b/testsuites/unittest/net/netdb/config.gni @@ -49,7 +49,6 @@ netdb_sources_full = [ "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_010.cpp", "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_011.cpp", "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_012.cpp", - "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_014.cpp", "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_015.cpp", "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_016.cpp", "$TEST_UNITTEST_DIR/net/netdb/full/net_netdb_test_017.cpp", diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp index bb124c5c..2e295946 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_002.cpp @@ -35,6 +35,17 @@ static int AddrInfoTest(void) { // Prerequisite: correct DNS servers must be configured. + char host_file[] = "127.0.0.2 example.com\n", serv_file[] = "ftp 21/tcp\n"; + char *pathList[] = {"/etc/hosts", "/etc/services"}; + char *streamList[] = {host_file, serv_file}; + int streamLen[] = {sizeof(host_file), sizeof(serv_file)}; + const int file_number = 2; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct addrinfo *addr = NULL; int ret = getaddrinfo("example.com", "ftp", NULL, &addr); ICUNIT_ASSERT_EQUAL(ret, 0, ret); @@ -50,6 +61,7 @@ static int AddrInfoTest(void) const char *p = gai_strerror(EAI_AGAIN); ICUNIT_ASSERT_NOT_EQUAL(p, NULL, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp index aeea1cc3..95787450 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_004.cpp @@ -34,8 +34,19 @@ static int GetHostByAddrTest(void) { + char host_file[] = "127.0.0.1 localhost\n100.0.0.0 example.com example\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {host_file}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct in_addr ia; - int length = 4; + int length = 4; // the address length is 4; ia.s_addr = inet_addr("127.0.0.1"); struct hostent *addr = gethostbyaddr(&ia, sizeof ia, AF_INET); ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); @@ -43,19 +54,18 @@ static int GetHostByAddrTest(void) ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "localhost", -1); ICUNIT_ASSERT_EQUAL(addr->h_length, length, -1); - ia.s_addr = inet_addr("100.109.180.184"); + ia.s_addr = inet_addr("100.0.0.0"); addr = gethostbyaddr(&ia, sizeof ia, AF_INET); ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype); - ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "szvphisprb93341", -1); - ICUNIT_ASSERT_STRING_EQUAL(addr->h_aliases[0], "szvphisprb93341", -1); + ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "example.com", -1); errno = 0; ia.s_addr = inet_addr("127.0.0.0"); addr = gethostbyaddr(&ia, sizeof ia, AF_INET); ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno); - return ICUNIT_SUCCESS; +    RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp index b9932e81..9cc7c829 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_006.cpp @@ -34,6 +34,16 @@ static int GetHostByNameTest(void) { + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {host_file}; + int streamLen[] = {sizeof(host_file)}; + int flag = PrepareFileEnv(pathList, streamList, streamLen, 1); + if (flag != 0) { + RecoveryFileEnv(pathList, 1); + return -1; + } + struct hostent *addr = gethostbyname("localhost"); ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "localhost"), 0, -1); @@ -49,6 +59,7 @@ static int GetHostByNameTest(void) addr = gethostbyname("lo"); ICUNIT_ASSERT_EQUAL(addr, NULL, -1); + RecoveryFileEnv(pathList, 1); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp index 712e5b97..42ef5c50 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_007.cpp @@ -34,6 +34,17 @@ static int GetHostByNameRTest(void) { + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {static_cast(host_file)}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct hostent addr, *result = NULL; char buf[1024]; char buf1[1]; @@ -60,6 +71,7 @@ static int GetHostByNameRTest(void) ret = gethostbyname_r("lo", &addr, buf, sizeof buf, &result, &err); ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp index 6a9d44e6..7819b3b6 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_008.cpp @@ -34,6 +34,17 @@ static int GetHostByName2Test(void) { + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {static_cast(host_file)}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct hostent *addr = gethostbyname2("localhost", AF_INET); ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1); ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "localhost"), 0, -1); @@ -51,6 +62,7 @@ static int GetHostByName2Test(void) addr = gethostbyname2("localh", AF_INET); ICUNIT_ASSERT_EQUAL(addr, NULL, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp index c14bc9b7..7a9ab531 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_009.cpp @@ -33,6 +33,17 @@ static int GetHostByName2RTest(void) { + char host_file[] = "127.0.0.1 localhost\n"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {host_file}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct hostent addr, *result = NULL; char buf[1024]; char buf1[1]; @@ -59,6 +70,7 @@ static int GetHostByName2RTest(void) ret = gethostbyname2_r("lo", AF_INET, &addr, buf, sizeof buf, &result, &err); ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp index b6b7f191..32f7d434 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_011.cpp @@ -35,16 +35,29 @@ static int GetServByPortTest(void) { // refer to the `/etc/services' file. + char serv_file[] = "ssh 22/tcp\n"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + const int test_port_no = 22; // ssh port number is 22 struct servent *se1 = nullptr; - struct servent *se = getservbyport(htons(22), "tcp"); + struct servent *se = getservbyport(htons(test_port_no), "tcp"); ICUNIT_ASSERT_NOT_EQUAL(se, NULL, -1); ICUNIT_ASSERT_STRING_EQUAL(se->s_name, "ssh", -1); ICUNIT_ASSERT_STRING_EQUAL(se->s_proto, "tcp", -1); ICUNIT_ASSERT_STRING_EQUAL(se->s_aliases[0], "ssh", -1); - se1 = getservbyport(htons(22), "tp"); + se1 = getservbyport(htons(test_port_no), "tp"); ICUNIT_ASSERT_EQUAL(se1, nullptr, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp index 0e9ad90e..503948f9 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_012.cpp @@ -35,26 +35,42 @@ static int GetServByPortRTest(void) { // refer to the `/etc/services' file. + char serv_file[] = "ssh 22/tcp\n"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct servent se, *result = NULL; char buf[1024]; char buf1[2]; - int ret = getservbyport_r(htons(22), "udp", &se, buf, sizeof buf, &result); + const int test_port_no = 22; // ssh port number is 22 + int ret = getservbyport_r(htons(test_port_no), "tcp", &se, buf, sizeof buf, &result); ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1); ICUNIT_ASSERT_STRING_EQUAL(se.s_name, "ssh", -1); - ICUNIT_ASSERT_STRING_EQUAL(se.s_proto, "udp", -1); + ICUNIT_ASSERT_STRING_EQUAL(se.s_proto, "tcp", -1); ICUNIT_ASSERT_STRING_EQUAL(se.s_aliases[0], "ssh", -1); ICUNIT_ASSERT_STRING_EQUAL(result->s_name, "ssh", -1); - ICUNIT_ASSERT_STRING_EQUAL(result->s_proto, "udp", -1); + ICUNIT_ASSERT_STRING_EQUAL(result->s_proto, "tcp", -1); ICUNIT_ASSERT_STRING_EQUAL(result->s_aliases[0], "ssh", -1); - ret = getservbyport_r(htons(22), "udp", &se, buf1, sizeof buf1, &result); + ret = getservbyport_r(htons(test_port_no), "udp", &se, buf, sizeof buf, &result); + ICUNIT_ASSERT_EQUAL(ret, ENOENT, -1); + + ret = getservbyport_r(htons(test_port_no), "udp", &se, buf1, sizeof buf1, &result); ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret); - ret = getservbyport_r(htons(22), "ud", &se, buf, sizeof buf, &result); + ret = getservbyport_r(htons(test_port_no), "ud", &se, buf, sizeof buf, &result); ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_014.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_014.cpp deleted file mode 100644 index d4f0caaa..00000000 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_014.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "lt_net_netdb.h" -#include - -static int IfNameIndexTest(void) -{ - struct if_nameindex *idx = if_nameindex(); - ICUNIT_ASSERT_NOT_EQUAL(idx, NULL, -1); - - if_freenameindex(idx); - - return ICUNIT_SUCCESS; -} - -void NetNetDbTest014(void) -{ - TEST_ADD_CASE(__FUNCTION__, IfNameIndexTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION); -} diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp index 95e675b4..612b1575 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_015.cpp @@ -44,10 +44,6 @@ static int IfNameToIndexTest(void) ICUNIT_ASSERT_NOT_EQUAL(str, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(if_name, "lo", -1); - str = if_indextoname(3, if_name); - ICUNIT_ASSERT_EQUAL(str, nullptr, -1); - ICUNIT_ASSERT_EQUAL(errno, ENXIO, errno); - ret = if_nametoindex("eth1"); ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(errno, ENODEV, errno); diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp index 652db1ed..c9d2d67b 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_016.cpp @@ -32,6 +32,23 @@ static int GetServByNameTest(void) { + char serv_file[] = "echo 7/tcp\n" + "echo 7/udp\n" + "discard 9/tcp sink null\n" + "discard 9/udp sink null\n" + "systat 11/tcp users\n" + "ssh 22/tcp\n"; + + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct servent *se1 = nullptr; struct servent *se2 = nullptr; @@ -53,6 +70,7 @@ static int GetServByNameTest(void) se2 = getservbyname("systat", "udp"); ICUNIT_ASSERT_EQUAL(se2, nullptr, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp index 81908c55..a3469ff6 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_017.cpp @@ -32,6 +32,17 @@ static int GetServByNameRTest(void) { + char serv_file[] = "ssh 22/tcp\n"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct servent se; struct servent *result = NULL; char buf1[1024] = { 0 }; @@ -58,6 +69,7 @@ static int GetServByNameRTest(void) ret = getservbyname_r("sh", "tcp", &se, buf1, sizeof buf1, &result); ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp index 3f816dc8..415fd086 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_018.cpp @@ -32,6 +32,28 @@ static int GetServEntTest(void) { + char serv_file[] = "tcpmux 1/tcp # TCP port service multiplexer\n" + "echo 7/tcp\n" + "echo 7/udp\n" + "discard 9/tcp sink null\n" + "ssh 100000/tcp\n" + "ssh /tcp\n" + "ssh 22/"; + char *pathList[] = {"/etc/services"}; + char *streamList[] = {static_cast(serv_file)}; + int streamLen[] = {sizeof(serv_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + + /* tcpmux,echo,discard port number is 1,7,9 */ + const int tcpmux_port_no = 1; + const int echo_port_no = 7; + const int discard_port_no = 9; + struct servent *se1 = nullptr; struct servent *se2 = nullptr; struct servent *se3 = nullptr; @@ -40,7 +62,7 @@ static int GetServEntTest(void) ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "tcpmux", -1); ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1); - ICUNIT_ASSERT_EQUAL(se1->s_port, ntohs(1), -1); + ICUNIT_ASSERT_EQUAL(se1->s_port, ntohs(tcpmux_port_no), -1); endservent(); se2 = getservent(); @@ -60,20 +82,28 @@ static int GetServEntTest(void) ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "echo", -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "tcp", -1); - ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(7), -1); + ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(echo_port_no), -1); se3 = getservent(); ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "echo", -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "udp", -1); - ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(7), -1); + ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(echo_port_no), -1); se3 = getservent(); ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "discard", -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "tcp", -1); - ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(9), -1); + ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(discard_port_no), -1); ICUNIT_ASSERT_STRING_EQUAL(se3->s_aliases[0], "sink", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->s_aliases[1], "null", -1); + ICUNIT_ASSERT_EQUAL(se3->s_aliases[2], nullptr, -1); + + se3 = getservent(); + ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + endservent(); + + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp index 53c9b08a..70ad889a 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_019.cpp @@ -29,21 +29,37 @@ */ #include "lt_net_netdb.h" +#include static int GetHostEntTest(void) { + char host_file[] = "127.0.0.1 localhost #localhost\n" + "::1 ip6-localhost\n" + "10.0.0.0 example example.com example.cn\n" + "10.0.0.0\n" + "10.0.0 example.com"; + char *pathList[] = {"/etc/hosts"}; + char *streamList[] = {static_cast(host_file)}; + int streamLen[] = {sizeof(host_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct hostent *se1 = nullptr; struct hostent *se2 = nullptr; struct hostent *se3 = nullptr; - int type = 2; - int length1 = 4; - int length2 = 16; + char addr[INET6_ADDRSTRLEN]; se1 = gethostent(); ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, "localhost", -1); - ICUNIT_ASSERT_EQUAL(se1->h_addrtype, type, -1); - ICUNIT_ASSERT_EQUAL(se1->h_length, length1, -1); + ICUNIT_ASSERT_EQUAL(se1->h_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->h_length, INADDRSZ, -1); + ICUNIT_ASSERT_STRING_EQUAL("127.0.0.1", inet_ntop(AF_INET, se1->h_addr_list[0], addr, INET_ADDRSTRLEN), -1); + ICUNIT_ASSERT_EQUAL(se1->h_aliases[0], nullptr, -1); endhostent(); se2 = gethostent(); @@ -62,15 +78,24 @@ static int GetHostEntTest(void) se3 = gethostent(); ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); ICUNIT_ASSERT_EQUAL(se3->h_addrtype, AF_INET6, -1); - ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "localhost", -1); - ICUNIT_ASSERT_EQUAL(se3->h_length, length2, -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "ip6-localhost", -1); + ICUNIT_ASSERT_EQUAL(se3->h_length, IN6ADDRSZ, -1); + ICUNIT_ASSERT_STRING_EQUAL("::1", inet_ntop(AF_INET6, se3->h_addr_list[0], addr, INET6_ADDRSTRLEN), -1); se3 = gethostent(); ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1); ICUNIT_ASSERT_EQUAL(se3->h_addrtype, AF_INET, -1); - ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "szvphisprb93341", -1); - ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[0], "szvphisprb93341.huawei.com", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "example", -1); + ICUNIT_ASSERT_STRING_EQUAL("10.0.0.0", inet_ntop(AF_INET, se3->h_addr_list[0], addr, INET_ADDRSTRLEN), -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[0], "example.com", -1); + ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[1], "example.cn", -1); + ICUNIT_ASSERT_EQUAL(se3->h_aliases[2], nullptr, -1); + + se3 = gethostent(); + ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + endhostent(); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp index a08a22f0..5cad29c6 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp @@ -32,6 +32,20 @@ static int GetNetEntTest(void) { + char network_file[] = "# symbolic names for networks, see networks(5) for more information\n" + "link-local 169.254.0.0\n" + "example 192.168.1.0 network example-network\n" + "test1"; + char *pathList[] = {"/etc/networks"}; + char *streamList[] = {static_cast(network_file)}; + int streamLen[] = {sizeof(network_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct netent *se1 = nullptr; struct netent *se2 = nullptr; struct netent *se3 = nullptr; @@ -39,8 +53,9 @@ static int GetNetEntTest(void) se1 = getnetent(); ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1); - ICUNIT_ASSERT_EQUAL(se1->n_addrtype, 2, -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1); + ICUNIT_ASSERT_EQUAL(se1->n_aliases[0], nullptr, -1); endnetent(); se2 = getnetent(); @@ -56,6 +71,20 @@ static int GetNetEntTest(void) ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se3->n_addrtype, -1); ICUNIT_ASSERT_EQUAL(se1->n_net, se3->n_net, -1); + se1 = getnetent(); + ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "example", -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); + ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("192.168.1.0"), -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[0], "network", -1); + ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[1], "example-network", -1); + ICUNIT_ASSERT_EQUAL(se1->n_aliases[2], nullptr, -1); + + se1 = getnetent(); + ICUNIT_ASSERT_EQUAL(se1, nullptr, -1); + endnetent(); + + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp index 0e4254b3..9b784d51 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_021.cpp @@ -32,6 +32,18 @@ static int GetNetBynametTest(void) { + char network_file[] = "# symbolic names for networks, see networks(5) for more information\n" + "link-local 169.254.0.0\n"; + char *pathList[] = {"/etc/networks"}; + char *streamList[] = {static_cast(network_file)}; + int streamLen[] = {sizeof(network_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct netent *se1 = nullptr; struct netent *se2 = nullptr; struct netent *se3 = nullptr; @@ -39,7 +51,7 @@ static int GetNetBynametTest(void) se1 = getnetbyname("link-local"); ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1); - ICUNIT_ASSERT_EQUAL(se1->n_addrtype, 2, -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1); se2 = getnetbyname("link"); @@ -48,6 +60,7 @@ static int GetNetBynametTest(void) se3 = getnetbyname("hs"); ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp b/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp index 3bf0f9b1..b551318e 100644 --- a/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp +++ b/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp @@ -32,6 +32,18 @@ static int GetNetByAddrtTest(void) { + char network_file[] = "# symbolic names for networks, see networks(5) for more information\n" + "link-local 169.254.0.0\n"; + char *pathList[] = {"/etc/networks"}; + char *streamList[] = {static_cast(network_file)}; + int streamLen[] = {sizeof(network_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct netent *se1 = nullptr; struct netent *se2 = nullptr; struct netent *se3 = nullptr; @@ -39,7 +51,7 @@ static int GetNetByAddrtTest(void) se1 = getnetbyaddr(inet_network("169.254.0.0"), AF_INET); ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1); ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1); - ICUNIT_ASSERT_EQUAL(se1->n_addrtype, 2, -1); + ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1); ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1); se2 = getnetbyaddr(inet_network("169.254.0.1"), AF_INET); @@ -48,6 +60,7 @@ static int GetNetByAddrtTest(void) se3 = getnetbyaddr(inet_network("169.254.0.1"), AF_INET6); ICUNIT_ASSERT_EQUAL(se3, nullptr, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/netdb/lt_net_netdb.h b/testsuites/unittest/net/netdb/lt_net_netdb.h index d60a83cc..1ef994ee 100644 --- a/testsuites/unittest/net/netdb/lt_net_netdb.h +++ b/testsuites/unittest/net/netdb/lt_net_netdb.h @@ -52,7 +52,6 @@ void NetNetDbTest010(void); void NetNetDbTest011(void); void NetNetDbTest012(void); void NetNetDbTest013(void); -void NetNetDbTest014(void); void NetNetDbTest015(void); void NetNetDbTest016(void); void NetNetDbTest017(void); diff --git a/testsuites/unittest/net/netdb/net_netdb_test.cpp b/testsuites/unittest/net/netdb/net_netdb_test.cpp index 84761e3f..aa0e2dea 100644 --- a/testsuites/unittest/net/netdb/net_netdb_test.cpp +++ b/testsuites/unittest/net/netdb/net_netdb_test.cpp @@ -72,5 +72,206 @@ HWTEST_F(NetDbTest, NetNetDbTest013, TestSize.Level0) NetNetDbTest013(); } +#endif + +#if defined(LOSCFG_USER_TEST_FULL) +/* * + * @tc.name: NetNetDbTest018 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest018, TestSize.Level0) +{ + NetNetDbTest018(); +} + +/* * + * @tc.name: NetNetDbTest002 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest002, TestSize.Level0) +{ + NetNetDbTest002(); +} + +/* * + * @tc.name: NetNetDbTest003 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest003, TestSize.Level0) +{ + NetNetDbTest003(); +} + +/* * + * @tc.name: NetNetDbTest004 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest004, TestSize.Level0) +{ + NetNetDbTest004(); +} + +/* * + * @tc.name: NetNetDbTest006 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest006, TestSize.Level0) +{ + NetNetDbTest006(); +} + +/* * + * @tc.name: NetNetDbTest007 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest007, TestSize.Level0) +{ + NetNetDbTest007(); +} + +/* * + * @tc.name: NetNetDbTest008 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest008, TestSize.Level0) +{ + NetNetDbTest008(); +} + +/* * + * @tc.name: NetNetDbTest009 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest009, TestSize.Level0) +{ + NetNetDbTest009(); +} + +/* * + * @tc.name: NetNetDbTest010 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest010, TestSize.Level0) +{ + NetNetDbTest010(); +} + +/* * + * @tc.name: NetNetDbTest011 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest011, TestSize.Level0) +{ + NetNetDbTest011(); +} + +/* * + * @tc.name: NetNetDbTest012 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest012, TestSize.Level0) +{ + NetNetDbTest012(); +} + +/* * + * @tc.name: NetNetDbTest015 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest015, TestSize.Level0) +{ + NetNetDbTest015(); +} + +/* * + * @tc.name: NetNetDbTest016 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest016, TestSize.Level0) +{ + NetNetDbTest016(); +} + +/* * + * @tc.name: NetNetDbTest017 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest017, TestSize.Level0) +{ + NetNetDbTest017(); +} + +/* * + * @tc.name: NetNetDbTest019 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest019, TestSize.Level0) +{ + NetNetDbTest019(); +} + +/* * + * @tc.name: NetNetDbTest020 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest020, TestSize.Level0) +{ + NetNetDbTest020(); +} + +/* * + * @tc.name: NetNetDbTest021 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest021, TestSize.Level0) +{ + NetNetDbTest021(); +} + +/* * + * @tc.name: NetNetDbTest022 + * @tc.desc: function for NetDbTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(NetDbTest, NetNetDbTest022, TestSize.Level0) +{ + NetNetDbTest022(); +} + #endif } diff --git a/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp b/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp index e8cb672a..ea7b2ed7 100644 --- a/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp +++ b/testsuites/unittest/net/resolv/full/net_resolv_test_004.cpp @@ -34,6 +34,17 @@ static int EtherHosttonTest(void) { // suppose "0:0:0:0:0:0 localhost" in `/etc/ethers' file. + char ether_file[] = "0:0:0:0:0:0 localhost"; + char *pathList[] = {"/etc/ethers"}; + char *streamList[] = {static_cast(ether_file)}; + int streamLen[] = {sizeof(ether_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct ether_addr addr, *eaddr = &addr; int ret = ether_hostton("localhost", eaddr); @@ -45,6 +56,7 @@ static int EtherHosttonTest(void) ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[4], 0x00, eaddr->ether_addr_octet[4]); ICUNIT_ASSERT_EQUAL(eaddr->ether_addr_octet[5], 0x00, eaddr->ether_addr_octet[5]); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp b/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp index baf77fbe..2fe4a303 100644 --- a/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp +++ b/testsuites/unittest/net/resolv/full/net_resolv_test_008.cpp @@ -35,6 +35,17 @@ static int EtherNtohostTest(void) { // suppose "0:0:0:0:0:0 localhost" in `/etc/ethers' file. + char ether_file[] = "0:0:0:0:0:0 localhost"; + char *pathList[] = {"/etc/ethers"}; + char *streamList[] = {static_cast(ether_file)}; + int streamLen[] = {sizeof(ether_file)}; + const int file_number = 1; + int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number); + if (flag != 0) { + RecoveryFileEnv(pathList, file_number); + return -1; + } + struct ether_addr addr = {{0,0,0,0,0,0}}, *eaddr = &addr; char buf[100]; int ret = ether_ntohost(buf, eaddr); @@ -42,6 +53,7 @@ static int EtherNtohostTest(void) ICUNIT_ASSERT_EQUAL(ret, 0, -1); ICUNIT_ASSERT_EQUAL(strcmp("localhost", buf), 0, -1); + RecoveryFileEnv(pathList, file_number); return ICUNIT_SUCCESS; } diff --git a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp b/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp index be10618b..c973ca66 100644 --- a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp +++ b/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp @@ -55,38 +55,65 @@ static int ProcessTest001(void) return 0; } -static int Testcase(void) +static int Child(void) { - int ret; - int status; - int pid; int count = TEST_COUNT; - - int temp = GetCpuCount(); - if (temp <= 1) { - return 0; - } + int status = 0; while (count > 0) { - ret = fork(); + int ret = fork(); if (ret == 0) { ret = ProcessTest001(); - exit(10); // 10, exit args + exit(ret); } else if (ret > 0) { - pid = ret; + int pid = ret; ret = wait(&status); status = WEXITSTATUS(status); - ICUNIT_ASSERT_EQUAL(ret, pid, ret); - ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, assert that function Result is equal to this. + if (ret != pid) { + printf("wait child %d failed, is %u!\n", pid, ret); + exit(__LINE__); + } + if (status != 255) { // 255, assert that function Result is equal to this. + printf("wait child status is 255, but is %d, child is error line :%d \n", status, status); + exit(__LINE__); + } + } else { + printf("fork failed!\n"); + exit(__LINE__); } - ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. count--; } return 0; } +static int Testcase(void) +{ + int ret; + int status; + int pid; + + int temp = GetCpuCount(); + if (temp <= 1) { + return 0; + } + + ret = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + if (ret == 0) { + exit(Child()); + } else if (ret > 0) { + pid = ret; + ret = waitpid(pid, &status, NULL); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 0, status); + } + + return 0; +} + void ItTestProcess010(void) { TEST_ADD_CASE("IT_POSIX_PROCESS_010", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); diff --git a/tools/build/liteos.ld b/tools/build/liteos.ld index 3fbe7691..a5455696 100644 --- a/tools/build/liteos.ld +++ b/tools/build/liteos.ld @@ -142,7 +142,7 @@ SECTIONS __user_init_bss = .;//将当前位置给__user_init_bss KEEP(libuserinit.O (.user.bss)) . = ALIGN(0x1000); - __user_init_end = .;/ + __user_init_end = .; } > user_ram AT > ram __user_init_size = __user_init_end - __user_init_entry; diff --git a/zzz/git/push.sh b/zzz/git/push.sh index bd84a3d9..f422a726 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m ' 详细注解 liteipc 注册服务过程 +git commit -m ' 同步官方源码,对调度,任务模块有很大的调整 百图画鸿蒙 + 百文说内核 + 百万注源码 => 挖透鸿蒙内核源码 鸿蒙研究站 | http://weharmonyos.com (国内) | https://weharmony.github.io (国外) -- GitLab