From af428db01f986d1352d7f13016f1a0f58fc1bc8d Mon Sep 17 00:00:00 2001
From: Ayush Singh <ayushdevel1325@gmail.com>
Date: Sun, 11 Feb 2024 21:49:51 +0530
Subject: [PATCH] Implement sys/thread for UEFI

Since UEFI has no concept of threads, most of this module can be
ignored. However, implementing parts that make sense.

- Implement sleep
- Implement available_parallelism

Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
---
 library/std/src/sys/pal/uefi/mod.rs    |  1 -
 library/std/src/sys/pal/uefi/thread.rs | 60 ++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 library/std/src/sys/pal/uefi/thread.rs

diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index efa4ed67c50ca..5a96b8f1c3a07 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -31,7 +31,6 @@ pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
 pub mod stdio;
-#[path = "../unsupported/thread.rs"]
 pub mod thread;
 #[path = "../unsupported/thread_local_key.rs"]
 pub mod thread_local_key;
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
new file mode 100644
index 0000000000000..ddfc3af2f5011
--- /dev/null
+++ b/library/std/src/sys/pal/uefi/thread.rs
@@ -0,0 +1,60 @@
+use super::unsupported;
+use crate::ffi::CStr;
+use crate::io;
+use crate::num::NonZeroUsize;
+use crate::ptr::NonNull;
+use crate::time::Duration;
+
+pub struct Thread(!);
+
+pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
+
+impl Thread {
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
+        unsupported()
+    }
+
+    pub fn yield_now() {
+        // do nothing
+    }
+
+    pub fn set_name(_name: &CStr) {
+        // nope
+    }
+
+    pub fn sleep(dur: Duration) {
+        let boot_services: NonNull<r_efi::efi::BootServices> =
+            crate::os::uefi::env::boot_services().expect("can't sleep").cast();
+        let mut dur_ms = dur.as_micros();
+        // ceil up to the nearest microsecond
+        if dur.subsec_nanos() % 1000 > 0 {
+            dur_ms += 1;
+        }
+
+        while dur_ms > 0 {
+            let ms = crate::cmp::min(dur_ms, usize::MAX as u128);
+            let _ = unsafe { ((*boot_services.as_ptr()).stall)(ms as usize) };
+            dur_ms -= ms;
+        }
+    }
+
+    pub fn join(self) {
+        self.0
+    }
+}
+
+pub fn available_parallelism() -> io::Result<NonZeroUsize> {
+    // UEFI is single threaded
+    Ok(NonZeroUsize::new(1).unwrap())
+}
+
+pub mod guard {
+    pub type Guard = !;
+    pub unsafe fn current() -> Option<Guard> {
+        None
+    }
+    pub unsafe fn init() -> Option<Guard> {
+        None
+    }
+}