浏览代码

Merge branch 'master' into patch-add-file-mapping

MemoryShore 8 月之前
父节点
当前提交
d6a5341fe9

+ 4 - 3
kernel/Cargo.toml

@@ -37,6 +37,7 @@ bitmap = { path = "crates/bitmap" }
 driver_base_macros = { "path" = "crates/driver_base_macros" }
 # 一个no_std的hashmap、hashset
 elf = { version = "=0.7.2", default-features = false }
+fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
 hashbrown = "=0.13.2"
 ida = { path = "src/libs/ida" }
 intertrait = { path = "crates/intertrait" }
@@ -48,11 +49,11 @@ num-derive = "=0.3"
 num-traits = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
 smoltcp = { version = "=0.11.0", default-features = false, features = ["log", "alloc",  "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
 system_error = { path = "crates/system_error" }
-unified-init = { path = "crates/unified-init" }
-virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers", rev = "f91c807965" }
-fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
 uefi = { version = "=0.26.0", features = ["alloc"] }
 uefi-raw = "=0.5.0"
+unified-init = { path = "crates/unified-init" }
+virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers", rev = "f91c807965" }
+wait_queue_macros = { path = "crates/wait_queue_macros" }
 paste = "=1.0.14"
 slabmalloc = { path = "crates/rust-slabmalloc" }
 log = "0.4.21"

+ 7 - 0
kernel/crates/wait_queue_macros/Cargo.toml

@@ -0,0 +1,7 @@
+[package]
+name = "wait_queue_macros"
+version = "0.1.0"
+edition = "2021"
+authors = ["longjin <longjin@dragonos.org>"]
+
+[dependencies]

+ 60 - 0
kernel/crates/wait_queue_macros/src/lib.rs

@@ -0,0 +1,60 @@
+#![no_std]
+
+/// Wait for a condition to become true.
+///
+/// This macro will wait for a condition to become true.
+///
+/// ## Parameters
+///
+/// - `$wq`: The wait queue to wait on.
+/// - `$condition`: The condition to wait for. (you can pass a function or a boolean expression)
+/// - `$cmd`: The command to execute while waiting.
+#[macro_export]
+macro_rules! wq_wait_event_interruptible {
+    ($wq:expr, $condition: expr, $cmd: expr) => {{
+        let mut retval = Ok(());
+        if !$condition {
+            retval = wait_queue_macros::_wq_wait_event_interruptible!($wq, $condition, $cmd);
+        }
+
+        retval
+    }};
+}
+
+#[macro_export]
+#[allow(clippy::crate_in_macro_def)]
+macro_rules! _wq_wait_event_interruptible {
+    ($wq:expr, $condition: expr, $cmd: expr) => {{
+        wait_queue_macros::__wq_wait_event!($wq, $condition, true, Ok(()), {
+            $cmd;
+            crate::sched::schedule(SchedMode::SM_NONE)
+        })
+    }};
+}
+
+#[macro_export]
+macro_rules! __wq_wait_event(
+    ($wq:expr, $condition: expr, $interruptible: expr, $ret: expr, $cmd:expr) => {{
+        let mut retval = $ret;
+        let mut exec_finish_wait = true;
+        loop {
+            let x = $wq.prepare_to_wait_event($interruptible);
+            if $condition {
+                break;
+            }
+
+            if $interruptible && !x.is_ok() {
+                retval = x;
+                exec_finish_wait = false;
+                break;
+            }
+
+            $cmd;
+        }
+        if exec_finish_wait {
+            $wq.finish_wait();
+        }
+
+        retval
+    }};
+);

+ 6 - 6
kernel/src/arch/x86_64/interrupt/mod.rs

@@ -132,6 +132,12 @@ pub struct TrapFrame {
     pub ss: ::core::ffi::c_ulong,
 }
 
+impl Default for TrapFrame {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl TrapFrame {
     pub fn new() -> Self {
         Self {
@@ -172,9 +178,3 @@ impl TrapFrame {
         return (self.cs & 0x3) != 0;
     }
 }
-
-impl Default for TrapFrame {
-    fn default() -> Self {
-        Self::new()
-    }
-}

+ 45 - 6
kernel/src/filesystem/eventfd.rs

@@ -3,11 +3,13 @@ use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata};
 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 use crate::libs::wait_queue::WaitQueue;
-use crate::net::event_poll::EPollEventType;
+use crate::net::event_poll::{EPollEventType, EPollItem, EventPoll, KernelIoctlData};
 use crate::process::ProcessManager;
 use crate::syscall::Syscall;
+use alloc::collections::LinkedList;
 use alloc::string::String;
 use alloc::sync::Arc;
+use alloc::sync::Weak;
 use alloc::vec::Vec;
 use core::any::Any;
 use ida::IdAllocator;
@@ -19,14 +21,14 @@ bitflags! {
     pub struct EventFdFlags: u32{
         /// Provide semaphore-like semantics for reads from the new
         /// file descriptor.
-        const EFD_SEMAPHORE = 1;
+        const EFD_SEMAPHORE = 0o1;
         /// Set the close-on-exec (FD_CLOEXEC) flag on the new file
         /// descriptor
-        const EFD_CLOEXEC = 2;
+        const EFD_CLOEXEC = 0o2000000;
         /// Set the O_NONBLOCK file status flag on the open file
         /// description (see open(2)) referred to by the new file
         /// descriptor
-        const EFD_NONBLOCK = 4;
+        const EFD_NONBLOCK = 0o0004000;
     }
 }
 
@@ -48,6 +50,7 @@ impl EventFd {
 pub struct EventFdInode {
     eventfd: SpinLock<EventFd>,
     wait_queue: WaitQueue,
+    epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
 }
 
 impl EventFdInode {
@@ -55,8 +58,23 @@ impl EventFdInode {
         EventFdInode {
             eventfd: SpinLock::new(eventfd),
             wait_queue: WaitQueue::default(),
+            epitems: SpinLock::new(LinkedList::new()),
         }
     }
+    pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
+        let is_remove = !self
+            .epitems
+            .lock_irqsave()
+            .extract_if(|x| x.epoll().ptr_eq(epoll))
+            .collect::<Vec<_>>()
+            .is_empty();
+
+        if is_remove {
+            return Ok(());
+        }
+
+        Err(SystemError::ENOENT)
+    }
 }
 
 impl IndexNode for EventFdInode {
@@ -85,7 +103,7 @@ impl IndexNode for EventFdInode {
         _offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: SpinLockGuard<FilePrivateData>,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if len < 8 {
             return Err(SystemError::EINVAL);
@@ -115,6 +133,11 @@ impl IndexNode for EventFdInode {
         }
         let val_bytes = val.to_ne_bytes();
         buf[..8].copy_from_slice(&val_bytes);
+
+        let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32);
+        // 唤醒epoll中等待的进程
+        EventPoll::wakeup_epoll(&self.epitems, pollflag)?;
+
         return Ok(8);
     }
 
@@ -131,7 +154,7 @@ impl IndexNode for EventFdInode {
         _offset: usize,
         len: usize,
         buf: &[u8],
-        _data: SpinLockGuard<FilePrivateData>,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if len < 8 {
             return Err(SystemError::EINVAL);
@@ -157,6 +180,10 @@ impl IndexNode for EventFdInode {
         let mut eventfd = self.eventfd.lock();
         eventfd.count += val;
         self.wait_queue.wakeup_all(None);
+
+        let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32);
+        // 唤醒epoll中等待的进程
+        EventPoll::wakeup_epoll(&self.epitems, pollflag)?;
         return Ok(8);
     }
 
@@ -187,6 +214,18 @@ impl IndexNode for EventFdInode {
     fn resize(&self, _len: usize) -> Result<(), SystemError> {
         Ok(())
     }
+    fn kernel_ioctl(
+        &self,
+        arg: Arc<dyn KernelIoctlData>,
+        _data: &FilePrivateData,
+    ) -> Result<usize, SystemError> {
+        let epitem = arg
+            .arc_any()
+            .downcast::<EPollItem>()
+            .map_err(|_| SystemError::EFAULT)?;
+        self.epitems.lock().push_back(epitem);
+        Ok(0)
+    }
     fn fs(&self) -> Arc<dyn FileSystem> {
         panic!("EventFd does not have a filesystem")
     }

+ 46 - 10
kernel/src/filesystem/vfs/file.rs

@@ -9,6 +9,8 @@ use log::error;
 use system_error::SystemError;
 use xarray::XArray;
 
+use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData};
+use crate::filesystem::eventfd::EventFdInode;
 use crate::{
     arch::MMArch,
     driver::{
@@ -26,8 +28,6 @@ use crate::{
     process::{cred::Cred, ProcessManager},
 };
 
-use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData};
-
 /// 文件私有信息的枚举类型
 #[derive(Debug, Clone)]
 #[allow(dead_code)]
@@ -299,7 +299,14 @@ impl File {
 
         let len = self
             .inode
-            .read_at(offset, len, buf, self.private_data.lock())?;
+            .read_at(offset, len, buf, self.private_data.lock())
+            .map_err(|e| {
+                if e == SystemError::ERESTARTSYS {
+                    SystemError::EINTR
+                } else {
+                    e
+                }
+            })?;
 
         if update_offset {
             self.offset
@@ -324,11 +331,24 @@ impl File {
 
         // 如果文件指针已经超过了文件大小,则需要扩展文件大小
         if offset > self.inode.metadata()?.size as usize {
-            self.inode.resize(offset)?;
+            self.inode.resize(offset).map_err(|e| {
+                if e == SystemError::ERESTARTSYS {
+                    SystemError::EINTR
+                } else {
+                    e
+                }
+            })?;
         }
         let len = self
             .inode
-            .write_at(offset, len, buf, self.private_data.lock())?;
+            .write_at(offset, len, buf, self.private_data.lock())
+            .map_err(|e| {
+                if e == SystemError::ERESTARTSYS {
+                    SystemError::EINTR
+                } else {
+                    e
+                }
+            })?;
 
         if update_offset {
             self.offset
@@ -576,9 +596,19 @@ impl File {
                 let inode = self.inode.downcast_ref::<SocketInode>().unwrap();
                 let mut socket = inode.inner();
 
-                return socket.remove_epoll(epoll);
+                socket.remove_epoll(epoll)
+            }
+            FileType::Pipe => {
+                let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap();
+                inode.inner().lock().remove_epoll(epoll)
+            }
+            _ => {
+                let inode = self
+                    .inode
+                    .downcast_ref::<EventFdInode>()
+                    .ok_or(SystemError::ENOSYS)?;
+                inode.remove_epoll(epoll)
             }
-            _ => return Err(SystemError::ENOSYS),
         }
     }
 
@@ -608,7 +638,11 @@ pub struct FileDescriptorVec {
     /// 当前进程打开的文件描述符
     fds: Vec<Option<Arc<File>>>,
 }
-
+impl Default for FileDescriptorVec {
+    fn default() -> Self {
+        Self::new()
+    }
+}
 impl FileDescriptorVec {
     pub const PROCESS_MAX_FD: usize = 1024;
 
@@ -706,13 +740,15 @@ impl FileDescriptorVec {
     /// ## 参数
     ///
     /// - `fd` 文件描述符序号
-    pub fn drop_fd(&mut self, fd: i32) -> Result<(), SystemError> {
+    pub fn drop_fd(&mut self, fd: i32) -> Result<Arc<File>, SystemError> {
         self.get_file_by_fd(fd).ok_or(SystemError::EBADF)?;
 
         // 把文件描述符数组对应位置设置为空
+        let file = self.fds[fd as usize].take().unwrap();
         self.fds[fd as usize].take().unwrap();
 
-        return Ok(());
+        assert!(Arc::strong_count(&file) == 1);
+        return Ok(file);
     }
 
     #[allow(dead_code)]

+ 3 - 2
kernel/src/filesystem/vfs/syscall.rs

@@ -522,8 +522,9 @@ impl Syscall {
     pub fn close(fd: usize) -> Result<usize, SystemError> {
         let binding = ProcessManager::current_pcb().fd_table();
         let mut fd_table_guard = binding.write();
-
-        fd_table_guard.drop_fd(fd as i32).map(|_| 0)
+        let _file = fd_table_guard.drop_fd(fd as i32)?;
+        drop(fd_table_guard);
+        Ok(0)
     }
 
     /// @brief 发送命令到文件描述符对应的设备,

+ 41 - 16
kernel/src/ipc/pipe.rs

@@ -1,6 +1,4 @@
 use crate::{
-    arch::CurrentIrqArch,
-    exception::InterruptArch,
     filesystem::vfs::{
         core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
         FileType, IndexNode, Metadata,
@@ -11,13 +9,14 @@ use crate::{
     },
     net::event_poll::{EPollEventType, EPollItem, EventPoll},
     process::ProcessState,
-    sched::{schedule, SchedMode},
+    sched::SchedMode,
     time::PosixTimeSpec,
 };
 
 use alloc::{
     collections::LinkedList,
     sync::{Arc, Weak},
+    vec::Vec,
 };
 use system_error::SystemError;
 
@@ -104,6 +103,25 @@ impl InnerPipeInode {
         self.epitems.lock().push_back(epitem);
         Ok(())
     }
+
+    fn buf_full(&self) -> bool {
+        return self.valid_cnt as usize == PIPE_BUFF_SIZE;
+    }
+
+    pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
+        let is_remove = !self
+            .epitems
+            .lock_irqsave()
+            .extract_if(|x| x.epoll().ptr_eq(epoll))
+            .collect::<Vec<_>>()
+            .is_empty();
+
+        if is_remove {
+            return Ok(());
+        }
+
+        Err(SystemError::ENOENT)
+    }
 }
 
 impl LockedPipeInode {
@@ -150,6 +168,16 @@ impl LockedPipeInode {
     pub fn inner(&self) -> &SpinLock<InnerPipeInode> {
         &self.inner
     }
+
+    fn readable(&self) -> bool {
+        let inode = self.inner.lock();
+        return inode.valid_cnt > 0 || inode.writer == 0;
+    }
+
+    fn writeable(&self) -> bool {
+        let inode = self.inner.lock();
+        return !inode.buf_full() || inode.reader == 0;
+    }
 }
 
 impl IndexNode for LockedPipeInode {
@@ -173,6 +201,7 @@ impl IndexNode for LockedPipeInode {
         if buf.len() < len {
             return Err(SystemError::EINVAL);
         }
+        // log::debug!("pipe mode: {:?}", mode);
         // 加锁
         let mut inode = self.inner.lock();
 
@@ -193,14 +222,12 @@ impl IndexNode for LockedPipeInode {
             }
 
             // 否则在读等待队列中睡眠,并释放锁
-            unsafe {
-                let irq_guard = CurrentIrqArch::save_and_disable_irq();
-
-                drop(inode);
-                self.read_wait_queue.sleep_without_schedule();
-                drop(irq_guard);
+            drop(inode);
+            let r = wq_wait_event_interruptible!(self.read_wait_queue, self.readable(), {});
+            if r.is_err() {
+                return Err(SystemError::ERESTARTSYS);
             }
-            schedule(SchedMode::SM_NONE);
+
             inode = self.inner.lock();
         }
 
@@ -351,13 +378,11 @@ impl IndexNode for LockedPipeInode {
             }
 
             // 解锁并睡眠
-            unsafe {
-                let irq_guard = CurrentIrqArch::save_and_disable_irq();
-                drop(inode);
-                self.write_wait_queue.sleep_without_schedule();
-                drop(irq_guard);
+            drop(inode);
+            let r = wq_wait_event_interruptible!(self.write_wait_queue, self.writeable(), {});
+            if r.is_err() {
+                return Err(SystemError::ERESTARTSYS);
             }
-            schedule(SchedMode::SM_NONE);
             inode = self.inner.lock();
         }
 

+ 29 - 0
kernel/src/ipc/signal.rs

@@ -16,6 +16,35 @@ use super::signal_types::{
 };
 
 impl Signal {
+    pub fn signal_pending_state(
+        interruptible: bool,
+        task_wake_kill: bool,
+        pcb: &Arc<ProcessControlBlock>,
+    ) -> bool {
+        if !interruptible && !task_wake_kill {
+            return false;
+        }
+
+        if !pcb.has_pending_signal() {
+            return false;
+        }
+
+        return interruptible || Self::fatal_signal_pending(pcb);
+    }
+
+    /// 判断当前进程是否收到了SIGKILL信号
+    pub fn fatal_signal_pending(pcb: &Arc<ProcessControlBlock>) -> bool {
+        let guard = pcb.sig_info_irqsave();
+        if guard
+            .sig_pending()
+            .signal()
+            .contains(Signal::SIGKILL.into())
+        {
+            return true;
+        }
+
+        return false;
+    }
     /// 向目标进程发送信号
     ///
     /// ## 参数

+ 6 - 0
kernel/src/ipc/signal_types.rs

@@ -81,6 +81,12 @@ impl SignalStruct {
     }
 }
 
+impl Default for SignalStruct {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl Deref for SignalStruct {
     type Target = InnerSignalStruct;
 

+ 3 - 0
kernel/src/lib.rs

@@ -12,6 +12,7 @@
 #![feature(c_void_variant)]
 #![feature(extract_if)]
 #![feature(fn_align)]
+#![feature(linked_list_retain)]
 #![feature(naked_functions)]
 #![feature(new_uninit)]
 #![feature(ptr_internals)]
@@ -83,6 +84,8 @@ extern crate x86;
 extern crate klog_types;
 extern crate uefi;
 extern crate uefi_raw;
+#[macro_use]
+extern crate wait_queue_macros;
 
 use crate::mm::allocator::kernel_allocator::KernelAllocator;
 

+ 31 - 2
kernel/src/libs/wait_queue.rs

@@ -3,9 +3,10 @@ use core::intrinsics::unlikely;
 
 use alloc::{collections::LinkedList, sync::Arc, vec::Vec};
 use log::{error, warn};
+use system_error::SystemError;
 
 use crate::{
-    arch::CurrentIrqArch,
+    arch::{ipc::signal::Signal, CurrentIrqArch},
     exception::InterruptArch,
     process::{ProcessControlBlock, ProcessManager, ProcessState},
     sched::{schedule, SchedMode},
@@ -32,6 +33,34 @@ impl WaitQueue {
         WaitQueue(SpinLock::new(InnerWaitQueue::INIT))
     }
 
+    pub fn prepare_to_wait_event(&self, interruptible: bool) -> Result<(), SystemError> {
+        let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
+        let pcb = ProcessManager::current_pcb();
+        if Signal::signal_pending_state(interruptible, false, &pcb) {
+            return Err(SystemError::ERESTARTSYS);
+        } else {
+            ProcessManager::mark_sleep(interruptible).unwrap_or_else(|e| {
+                panic!("sleep error: {:?}", e);
+            });
+            guard.wait_list.push_back(ProcessManager::current_pcb());
+            drop(guard);
+        }
+        Ok(())
+    }
+
+    pub fn finish_wait(&self) {
+        let pcb = ProcessManager::current_pcb();
+        let mut writer = pcb.sched_info().inner_lock_write_irqsave();
+        let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
+
+        writer.set_state(ProcessState::Runnable);
+        writer.set_wakeup();
+
+        guard.wait_list.retain(|x| !Arc::ptr_eq(x, &pcb));
+        drop(guard);
+        drop(writer);
+    }
+
     /// @brief 让当前进程在等待队列上进行等待,并且,允许被信号打断
     pub fn sleep(&self) {
         before_sleep_check(0);
@@ -50,7 +79,7 @@ impl WaitQueue {
         F: FnOnce(),
     {
         before_sleep_check(0);
-        let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
+        let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
         ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
             panic!("sleep error: {:?}", e);

+ 6 - 0
kernel/src/process/kthread.rs

@@ -80,6 +80,12 @@ impl KernelThreadPcbPrivate {
     }
 }
 
+impl Default for KernelThreadPcbPrivate {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 /// 内核线程的闭包,参数必须与闭包的参数一致,返回值必须是i32
 ///
 /// 元组的第一个元素是闭包,第二个元素是闭包的参数对象

+ 8 - 0
kernel/src/process/mod.rs

@@ -975,6 +975,14 @@ impl ProcessControlBlock {
         return None;
     }
 
+    /// 判断当前进程是否有未处理的信号
+    pub fn has_pending_signal(&self) -> bool {
+        let sig_info = self.sig_info_irqsave();
+        let has_pending = sig_info.sig_pending().has_pending();
+        drop(sig_info);
+        return has_pending;
+    }
+
     pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> {
         self.sig_struct.lock_irqsave()
     }

+ 5 - 0
kernel/src/sched/fair.rs

@@ -1373,6 +1373,11 @@ impl CfsRunQueue {
     }
 }
 
+impl Default for CfsRunQueue {
+    fn default() -> Self {
+        Self::new()
+    }
+}
 pub struct CompletelyFairScheduler;
 
 impl CompletelyFairScheduler {

+ 3 - 0
user/apps/test_tokio/.gitignore

@@ -0,0 +1,3 @@
+/target
+Cargo.lock
+/install/

+ 13 - 0
user/apps/test_tokio/Cargo.toml

@@ -0,0 +1,13 @@
+[package]
+name = "test_tokio"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+tokio = { version = "1.25", features = [
+    "macros",
+    "rt",
+    "rt-multi-thread",
+    "net",
+    "signal",
+] }

+ 56 - 0
user/apps/test_tokio/Makefile

@@ -0,0 +1,56 @@
+TOOLCHAIN="+nightly-2024-07-23-x86_64-unknown-linux-gnu"
+RUSTFLAGS+=""
+
+ifdef DADK_CURRENT_BUILD_DIR
+# 如果是在dadk中编译,那么安装到dadk的安装目录中
+	INSTALL_DIR = $(DADK_CURRENT_BUILD_DIR)
+else
+# 如果是在本地编译,那么安装到当前目录下的install目录中
+	INSTALL_DIR = ./install
+endif
+
+ifeq ($(ARCH), x86_64)
+	export RUST_TARGET=x86_64-unknown-linux-musl
+else ifeq ($(ARCH), riscv64)
+	export RUST_TARGET=riscv64gc-unknown-linux-gnu
+else 
+# 默认为x86_86,用于本地编译
+	export RUST_TARGET=x86_64-unknown-linux-musl
+endif
+
+run:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET)
+
+build:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET)
+
+clean:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET)
+
+test:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET)
+
+doc:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) doc --target $(RUST_TARGET)
+
+fmt:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt
+
+fmt-check:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt --check
+
+run-release:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET) --release
+
+build-release:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) --release
+
+clean-release:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET) --release
+
+test-release:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET) --release
+
+.PHONY: install
+install:
+	RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path . --no-track --root $(INSTALL_DIR) --force

+ 17 - 0
user/apps/test_tokio/src/main.rs

@@ -0,0 +1,17 @@
+use tokio::signal;
+
+async fn say_world() {
+    println!("world");
+}
+
+#[tokio::main(flavor = "current_thread")]
+async fn main() {
+    // Calling `say_world()` does not execute the body of `say_world()`.
+    let op = say_world();
+
+    // This println! comes first
+    println!("hello");
+
+    // Calling `.await` on `op` starts executing `say_world`.
+    op.await;
+}

+ 23 - 0
user/dadk/config/test_tokio-0.1.0.dadk

@@ -0,0 +1,23 @@
+{
+  "name": "test_tokio",
+  "version": "0.1.0",
+  "description": "测试tokio",
+  "task_type": {
+    "BuildFromSource": {
+      "Local": {
+        "path": "apps/test_tokio"
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "make install"
+  },
+  "clean": {
+    "clean_command": "make clean"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "target_arch": ["x86_64"]
+}