From fc2fd18c368f1c11decfc2c15b9e18b3841e26fe Mon Sep 17 00:00:00 2001
From: WangRunji <wangrunji0408@163.com>
Date: Sat, 22 Sep 2018 17:29:20 +0800
Subject: [PATCH] Add docs for thread::spawn()

---
 crate/process/src/thread.rs | 40 +++++++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/crate/process/src/thread.rs b/crate/process/src/thread.rs
index 8786cc8..818a28a 100644
--- a/crate/process/src/thread.rs
+++ b/crate/process/src/thread.rs
@@ -73,34 +73,61 @@ impl<S: ThreadSupport> ThreadMod<S> {
     }
 
     /// Spawns a new thread, returning a JoinHandle for it.
+    ///
+    /// `F`: Type of the function `f`
+    /// `T`: Type of the return value of `f`
     pub fn spawn<F, T>(f: F) -> JoinHandle<S, T>
         where
             F: Send + 'static + FnOnce() -> T,
             T: Send + 'static,
     {
         info!("spawn:");
+
+        // 注意到下面的问题:
+        // Processor只能从入口地址entry+参数arg创建新线程
+        // 而我们现在需要让它执行一个未知类型的(闭包)函数f
+
+        // 首先把函数本体(代码数据)置于堆空间中
         let f = Box::into_raw(Box::new(f));
-        let pid = S::processor().add(Context::new_kernel(kernel_thread_entry::<S, F, T>, f as usize));
-        return JoinHandle {
-            thread: Thread { pid, mark: PhantomData },
-            mark: PhantomData,
-        };
 
+        // 定义一个静态函数作为新线程的入口点
+        // 其参数是函数f在堆上的指针
+        // 这样我们就把函数f传到了一个静态函数内部
+        //
+        // 注意到它具有泛型参数,因此对每一次spawn调用,
+        // 由于F类型是独特的,因此都会生成一个新的kernel_thread_entry
         extern fn kernel_thread_entry<S, F, T>(f: usize) -> !
             where
                 S: ThreadSupport,
                 F: Send + 'static + FnOnce() -> T,
                 T: Send + 'static,
         {
+            // 在静态函数内部:
+            // 根据传进来的指针,恢复f
             let f = unsafe { Box::from_raw(f as *mut F) };
+            // 调用f,并将其返回值也放在堆上
             let ret = Box::new(f());
-//            unsafe { LocalKey::<usize>::get_map() }.clear();
+            // 清理本地线程存储
+            //   unsafe { LocalKey::<usize>::get_map() }.clear();
+            // 让Processor退出当前线程
+            // 把f返回值在堆上的指针,以线程返回码的形式传递出去
             let mut processor = S::processor();
             let pid = processor.current_pid();
             processor.exit(pid, Box::into_raw(ret) as usize);
             processor.schedule();
+            // 再也不会被调度回来了
             unreachable!()
         }
+
+        // 在Processor中创建新的线程
+        let pid = S::processor().add(Context::new_kernel(kernel_thread_entry::<S, F, T>, f as usize));
+
+        // 接下来看看`JoinHandle::join()`的实现
+        // 了解是如何获取f返回值的
+        return JoinHandle {
+            thread: Thread { pid, mark: PhantomData },
+            mark: PhantomData,
+        };
     }
 
     /// Cooperatively gives up a timeslice to the OS scheduler.
@@ -155,6 +182,7 @@ impl<S: ThreadSupport, T> JoinHandle<S, T> {
         let mut processor = S::processor();
         match processor.current_wait_for(self.thread.pid) {
             WaitResult::Ok(_, exit_code) => unsafe {
+                // Find return value on the heap from the exit code.
                 Ok(*Box::from_raw(exit_code as *mut T))
             }
             WaitResult::NotExist => Err(()),