about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorThe rustc-josh-sync Cronjob Bot <github-actions@github.com>2025-08-18 04:22:24 +0000
committerThe rustc-josh-sync Cronjob Bot <github-actions@github.com>2025-08-18 04:22:24 +0000
commit5818cbdd441bba57d509d549807af42f004ed21b (patch)
treef79760d147848a6b9f97563a5a80dab46c7dd2d1 /library/std/src/sys
parenta3510c7199806c153f927f25e2bff2c095aa60df (diff)
parent425a9c0a0e365c0b8c6cfd00c2ded83a73bed9a0 (diff)
Merge ref '425a9c0a0e36' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh.

Upstream ref: 425a9c0a0e365c0b8c6cfd00c2ded83a73bed9a0
Filtered ref: 26b9fd24259f4fc5fd7634a99dd6dda2821fb2d0

This merge was created using https://github.com/rust-lang/josh-sync.
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/configure_builtins.rs22
-rw-r--r--library/std/src/sys/fs/windows.rs17
-rw-r--r--library/std/src/sys/io/io_slice/uefi.rs74
-rw-r--r--library/std/src/sys/io/mod.rs3
-rw-r--r--library/std/src/sys/mod.rs5
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs4
-rw-r--r--library/std/src/sys/pal/hermit/time.rs32
-rw-r--r--library/std/src/sys/pal/itron/thread.rs4
-rw-r--r--library/std/src/sys/pal/sgx/thread.rs6
-rw-r--r--library/std/src/sys/pal/sgx/time.rs15
-rw-r--r--library/std/src/sys/pal/solid/time.rs9
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs4
-rw-r--r--library/std/src/sys/pal/uefi/tests.rs176
-rw-r--r--library/std/src/sys/pal/uefi/thread.rs4
-rw-r--r--library/std/src/sys/pal/uefi/time.rs178
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs6
-rw-r--r--library/std/src/sys/pal/unix/thread.rs69
-rw-r--r--library/std/src/sys/pal/unix/time.rs30
-rw-r--r--library/std/src/sys/pal/unsupported/thread.rs4
-rw-r--r--library/std/src/sys/pal/unsupported/time.rs15
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs4
-rw-r--r--library/std/src/sys/pal/wasi/time.rs25
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs4
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt1
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs1
-rw-r--r--library/std/src/sys/pal/windows/stack_overflow.rs3
-rw-r--r--library/std/src/sys/pal/windows/thread.rs8
-rw-r--r--library/std/src/sys/pal/windows/time.rs30
-rw-r--r--library/std/src/sys/pal/xous/thread.rs4
-rw-r--r--library/std/src/sys/pal/xous/time.rs15
-rw-r--r--library/std/src/sys/process/windows.rs8
31 files changed, 681 insertions, 99 deletions
diff --git a/library/std/src/sys/configure_builtins.rs b/library/std/src/sys/configure_builtins.rs
new file mode 100644
index 00000000000..9d776b778dc
--- /dev/null
+++ b/library/std/src/sys/configure_builtins.rs
@@ -0,0 +1,22 @@
+/// Hook into .init_array to enable LSE atomic operations at startup, if
+/// supported.
+#[cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "compiler-builtins-c")))]
+#[used]
+#[unsafe(link_section = ".init_array.90")]
+static RUST_LSE_INIT: extern "C" fn() = {
+    extern "C" fn init_lse() {
+        use crate::arch;
+
+        // This is provided by compiler-builtins::aarch64_linux.
+        unsafe extern "C" {
+            fn __rust_enable_lse();
+        }
+
+        if arch::is_aarch64_feature_detected!("lse") {
+            unsafe {
+                __rust_enable_lse();
+            }
+        }
+    }
+    init_lse
+};
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index 9b674a25165..bb3e4bc30ca 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -80,7 +80,7 @@ pub struct OpenOptions {
     attributes: u32,
     share_mode: u32,
     security_qos_flags: u32,
-    security_attributes: *mut c::SECURITY_ATTRIBUTES,
+    inherit_handle: bool,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
@@ -203,7 +203,7 @@ impl OpenOptions {
             share_mode: c::FILE_SHARE_READ | c::FILE_SHARE_WRITE | c::FILE_SHARE_DELETE,
             attributes: 0,
             security_qos_flags: 0,
-            security_attributes: ptr::null_mut(),
+            inherit_handle: false,
         }
     }
 
@@ -243,8 +243,8 @@ impl OpenOptions {
         // receive is `SECURITY_ANONYMOUS = 0x0`, which we can't check for later on.
         self.security_qos_flags = flags | c::SECURITY_SQOS_PRESENT;
     }
-    pub fn security_attributes(&mut self, attrs: *mut c::SECURITY_ATTRIBUTES) {
-        self.security_attributes = attrs;
+    pub fn inherit_handle(&mut self, inherit: bool) {
+        self.inherit_handle = inherit;
     }
 
     fn get_access_mode(&self) -> io::Result<u32> {
@@ -307,12 +307,17 @@ impl File {
 
     fn open_native(path: &WCStr, opts: &OpenOptions) -> io::Result<File> {
         let creation = opts.get_creation_mode()?;
+        let sa = c::SECURITY_ATTRIBUTES {
+            nLength: size_of::<c::SECURITY_ATTRIBUTES>() as u32,
+            lpSecurityDescriptor: ptr::null_mut(),
+            bInheritHandle: opts.inherit_handle as c::BOOL,
+        };
         let handle = unsafe {
             c::CreateFileW(
                 path.as_ptr(),
                 opts.get_access_mode()?,
                 opts.share_mode,
-                opts.security_attributes,
+                if opts.inherit_handle { &sa } else { ptr::null() },
                 creation,
                 opts.get_flags_and_attributes(),
                 ptr::null_mut(),
@@ -1601,7 +1606,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> {
     };
     unsafe {
         let ptr = header.PathBuffer.as_mut_ptr();
-        ptr.copy_from(abs_path.as_ptr().cast::<MaybeUninit<u16>>(), abs_path.len());
+        ptr.copy_from(abs_path.as_ptr().cast_uninit(), abs_path.len());
 
         let mut ret = 0;
         cvt(c::DeviceIoControl(
diff --git a/library/std/src/sys/io/io_slice/uefi.rs b/library/std/src/sys/io/io_slice/uefi.rs
new file mode 100644
index 00000000000..909cfbea0b7
--- /dev/null
+++ b/library/std/src/sys/io/io_slice/uefi.rs
@@ -0,0 +1,74 @@
+//! A buffer type used with `Write::write_vectored` for UEFI Networking APIs. Vectored writing to
+//! File is not supported as of UEFI Spec 2.11.
+
+use crate::marker::PhantomData;
+use crate::slice;
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub struct IoSlice<'a> {
+    len: u32,
+    data: *const u8,
+    _p: PhantomData<&'a [u8]>,
+}
+
+impl<'a> IoSlice<'a> {
+    #[inline]
+    pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
+        let len = buf.len().try_into().unwrap();
+        Self { len, data: buf.as_ptr(), _p: PhantomData }
+    }
+
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.len = u32::try_from(n)
+            .ok()
+            .and_then(|n| self.len.checked_sub(n))
+            .expect("advancing IoSlice beyond its length");
+        unsafe { self.data = self.data.add(n) };
+    }
+
+    #[inline]
+    pub const fn as_slice(&self) -> &'a [u8] {
+        unsafe { slice::from_raw_parts(self.data, self.len as usize) }
+    }
+}
+
+#[repr(C)]
+pub struct IoSliceMut<'a> {
+    len: u32,
+    data: *mut u8,
+    _p: PhantomData<&'a mut [u8]>,
+}
+
+impl<'a> IoSliceMut<'a> {
+    #[inline]
+    pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
+        let len = buf.len().try_into().unwrap();
+        Self { len, data: buf.as_mut_ptr(), _p: PhantomData }
+    }
+
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.len = u32::try_from(n)
+            .ok()
+            .and_then(|n| self.len.checked_sub(n))
+            .expect("advancing IoSlice beyond its length");
+        unsafe { self.data = self.data.add(n) };
+    }
+
+    #[inline]
+    pub fn as_slice(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.data, self.len as usize) }
+    }
+
+    #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.data, self.len as usize) }
+    }
+
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.data, self.len as usize) }
+    }
+}
diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs
index 4d0365d42fd..ae75f4d97b4 100644
--- a/library/std/src/sys/io/mod.rs
+++ b/library/std/src/sys/io/mod.rs
@@ -11,6 +11,9 @@ mod io_slice {
         } else if #[cfg(target_os = "wasi")] {
             mod wasi;
             pub use wasi::*;
+        } else if #[cfg(target_os = "uefi")] {
+            mod uefi;
+            pub use uefi::*;
         } else {
             mod unsupported;
             pub use unsupported::*;
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index f9a02b522e5..8ec0a0e3302 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -1,5 +1,10 @@
 #![allow(unsafe_op_in_unsafe_fn)]
 
+/// The configure builtins provides runtime support compiler-builtin features
+/// which require dynamic intialization to work as expected, e.g. aarch64
+/// outline-atomics.
+mod configure_builtins;
+
 /// The PAL (platform abstraction layer) contains platform-specific abstractions
 /// for implementing the features in the other submodules, e.g. UNIX file
 /// descriptors.
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 95fe4f902d3..cc4734b6819 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -115,6 +115,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
 }
diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs
index f76a5f96c87..89a427ab88b 100644
--- a/library/std/src/sys/pal/hermit/time.rs
+++ b/library/std/src/sys/pal/hermit/time.rs
@@ -25,8 +25,15 @@ impl Timespec {
         Timespec { t: timespec { tv_sec, tv_nsec } }
     }
 
-    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        if self >= other {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        // FIXME: const PartialOrd
+        let mut cmp = self.t.tv_sec - other.t.tv_sec;
+        if cmp == 0 {
+            cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64;
+        }
+
+        if cmp >= 0 {
             Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                 Duration::new(
                     (self.t.tv_sec - other.t.tv_sec) as u64,
@@ -46,20 +53,22 @@ impl Timespec {
         }
     }
 
-    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
-        let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
-        if nsec >= NSEC_PER_SEC.try_into().unwrap() {
-            nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
+        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
+        if nsec >= NSEC_PER_SEC as u32 {
+            nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
         }
         Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
     }
 
-    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;
 
         // Similar to above, nanos can't overflow.
@@ -213,15 +222,18 @@ impl SystemTime {
         SystemTime(time)
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         self.0.sub_timespec(&other.0)
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add_duration(other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub_duration(other)?))
     }
 }
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs
index 0d28051fcc4..4e14cb3cbca 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/pal/itron/thread.rs
@@ -361,6 +361,10 @@ unsafe fn terminate_and_delete_current_task() -> ! {
     unsafe { crate::hint::unreachable_unchecked() };
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     super::unsupported()
 }
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index a236c362706..1f613badcd7 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -1,6 +1,6 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
 
-use super::abi::usercalls;
+use super::abi::{thread, usercalls};
 use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
@@ -149,6 +149,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    Some(thread::current().addr().get() as u64)
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
diff --git a/library/std/src/sys/pal/sgx/time.rs b/library/std/src/sys/pal/sgx/time.rs
index db4cf2804bf..603dae952ab 100644
--- a/library/std/src/sys/pal/sgx/time.rs
+++ b/library/std/src/sys/pal/sgx/time.rs
@@ -32,15 +32,22 @@ impl SystemTime {
         SystemTime(usercalls::insecure_time())
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/pal/solid/time.rs b/library/std/src/sys/pal/solid/time.rs
index c39d715c6a6..e35e60df1a0 100644
--- a/library/std/src/sys/pal/solid/time.rs
+++ b/library/std/src/sys/pal/solid/time.rs
@@ -39,7 +39,8 @@ impl SystemTime {
         Self(t)
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         if self.0 >= other.0 {
             Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64)))
         } else {
@@ -47,11 +48,13 @@ impl SystemTime {
         }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
     }
 }
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index a91d95626e7..1812d11e692 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -144,6 +144,10 @@ impl Drop for Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 // Note: Both `sched_getaffinity` and `sysconf` are available but not functional on
 // teeos, so this function always returns an Error!
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
diff --git a/library/std/src/sys/pal/uefi/tests.rs b/library/std/src/sys/pal/uefi/tests.rs
index 38658cc4e9a..56ca999cc7e 100644
--- a/library/std/src/sys/pal/uefi/tests.rs
+++ b/library/std/src/sys/pal/uefi/tests.rs
@@ -1,7 +1,13 @@
+//! These tests are not run automatically right now. Please run these tests manually by copying them
+//! to a separate project when modifying any related code.
+
 use super::alloc::*;
-use super::time::*;
+use super::time::system_time_internal::{from_uefi, to_uefi};
+use crate::io::{IoSlice, IoSliceMut};
 use crate::time::Duration;
 
+const SECS_IN_MINUTE: u64 = 60;
+
 #[test]
 fn align() {
     // UEFI ABI specifies that allocation alignment minimum is always 8. So this can be
@@ -23,19 +29,177 @@ fn align() {
 }
 
 #[test]
-fn epoch() {
-    let t = r_efi::system::Time {
-        year: 1970,
+fn systemtime_start() {
+    let t = r_efi::efi::Time {
+        year: 1900,
         month: 1,
         day: 1,
         hour: 0,
         minute: 0,
         second: 0,
         nanosecond: 0,
-        timezone: r_efi::efi::UNSPECIFIED_TIMEZONE,
+        timezone: -1440,
         daylight: 0,
+        pad2: 0,
+    };
+    assert_eq!(from_uefi(&t), Duration::new(0, 0));
+    assert_eq!(t, to_uefi(&from_uefi(&t), -1440, 0).unwrap());
+    assert!(to_uefi(&from_uefi(&t), 0, 0).is_none());
+}
+
+#[test]
+fn systemtime_utc_start() {
+    let t = r_efi::efi::Time {
+        year: 1900,
+        month: 1,
+        day: 1,
+        hour: 0,
+        minute: 0,
+        second: 0,
         pad1: 0,
+        nanosecond: 0,
+        timezone: 0,
+        daylight: 0,
         pad2: 0,
     };
-    assert_eq!(system_time_internal::uefi_time_to_duration(t), Duration::new(0, 0));
+    assert_eq!(from_uefi(&t), Duration::new(1440 * SECS_IN_MINUTE, 0));
+    assert_eq!(t, to_uefi(&from_uefi(&t), 0, 0).unwrap());
+    assert!(to_uefi(&from_uefi(&t), -1440, 0).is_some());
+}
+
+#[test]
+fn systemtime_end() {
+    let t = r_efi::efi::Time {
+        year: 9999,
+        month: 12,
+        day: 31,
+        hour: 23,
+        minute: 59,
+        second: 59,
+        pad1: 0,
+        nanosecond: 0,
+        timezone: 1440,
+        daylight: 0,
+        pad2: 0,
+    };
+    assert!(to_uefi(&from_uefi(&t), 1440, 0).is_some());
+    assert!(to_uefi(&from_uefi(&t), 1439, 0).is_none());
+}
+
+// UEFI IoSlice and IoSliceMut Tests
+//
+// Strictly speaking, vectored read/write types for UDP4, UDP6, TCP4, TCP6 are defined
+// separately in the UEFI Spec. However, they have the same signature. These tests just ensure
+// that `IoSlice` and `IoSliceMut` are compatible with the vectored types for all the
+// networking protocols.
+
+unsafe fn to_slice<T>(val: &T) -> &[u8] {
+    let len = size_of_val(val);
+    unsafe { crate::slice::from_raw_parts(crate::ptr::from_ref(val).cast(), len) }
+}
+
+#[test]
+fn io_slice_single() {
+    let mut data = [0, 1, 2, 3, 4];
+
+    let tcp4_frag = r_efi::protocols::tcp4::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let tcp6_frag = r_efi::protocols::tcp6::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let udp4_frag = r_efi::protocols::udp4::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let udp6_frag = r_efi::protocols::udp6::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let io_slice = IoSlice::new(&data);
+
+    unsafe {
+        assert_eq!(to_slice(&io_slice), to_slice(&tcp4_frag));
+        assert_eq!(to_slice(&io_slice), to_slice(&tcp6_frag));
+        assert_eq!(to_slice(&io_slice), to_slice(&udp4_frag));
+        assert_eq!(to_slice(&io_slice), to_slice(&udp6_frag));
+    }
+}
+
+#[test]
+fn io_slice_mut_single() {
+    let mut data = [0, 1, 2, 3, 4];
+
+    let tcp4_frag = r_efi::protocols::tcp4::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let tcp6_frag = r_efi::protocols::tcp6::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let udp4_frag = r_efi::protocols::udp4::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let udp6_frag = r_efi::protocols::udp6::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let io_slice_mut = IoSliceMut::new(&mut data);
+
+    unsafe {
+        assert_eq!(to_slice(&io_slice_mut), to_slice(&tcp4_frag));
+        assert_eq!(to_slice(&io_slice_mut), to_slice(&tcp6_frag));
+        assert_eq!(to_slice(&io_slice_mut), to_slice(&udp4_frag));
+        assert_eq!(to_slice(&io_slice_mut), to_slice(&udp6_frag));
+    }
+}
+
+#[test]
+fn io_slice_multi() {
+    let mut data = [0, 1, 2, 3, 4];
+
+    let tcp4_frag = r_efi::protocols::tcp4::FragmentData {
+        fragment_length: data.len().try_into().unwrap(),
+        fragment_buffer: data.as_mut_ptr().cast(),
+    };
+    let rhs =
+        [tcp4_frag.clone(), tcp4_frag.clone(), tcp4_frag.clone(), tcp4_frag.clone(), tcp4_frag];
+    let lhs = [
+        IoSlice::new(&data),
+        IoSlice::new(&data),
+        IoSlice::new(&data),
+        IoSlice::new(&data),
+        IoSlice::new(&data),
+    ];
+
+    unsafe {
+        assert_eq!(to_slice(&lhs), to_slice(&rhs));
+    }
+}
+
+#[test]
+fn io_slice_basic() {
+    let data = [0, 1, 2, 3, 4];
+    let mut io_slice = IoSlice::new(&data);
+
+    assert_eq!(data, io_slice.as_slice());
+    io_slice.advance(2);
+    assert_eq!(&data[2..], io_slice.as_slice());
+}
+
+#[test]
+fn io_slice_mut_basic() {
+    let data = [0, 1, 2, 3, 4];
+    let mut data_clone = [0, 1, 2, 3, 4];
+    let mut io_slice_mut = IoSliceMut::new(&mut data_clone);
+
+    assert_eq!(data, io_slice_mut.as_slice());
+    assert_eq!(data, io_slice_mut.as_mut_slice());
+
+    io_slice_mut.advance(2);
+    assert_eq!(&data[2..], io_slice_mut.into_slice());
 }
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
index 75c364362b2..47a48008c76 100644
--- a/library/std/src/sys/pal/uefi/thread.rs
+++ b/library/std/src/sys/pal/uefi/thread.rs
@@ -56,6 +56,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // UEFI is single threaded
     Ok(NonZero::new(1).unwrap())
diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs
index eeb2c35ffbb..df5611b2ddd 100644
--- a/library/std/src/sys/pal/uefi/time.rs
+++ b/library/std/src/sys/pal/uefi/time.rs
@@ -1,16 +1,42 @@
 use crate::time::Duration;
 
-const SECS_IN_MINUTE: u64 = 60;
-const SECS_IN_HOUR: u64 = SECS_IN_MINUTE * 60;
-const SECS_IN_DAY: u64 = SECS_IN_HOUR * 24;
-
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Instant(Duration);
 
+/// When a Timezone is specified, the stored Duration is in UTC. If timezone is unspecified, then
+/// the timezone is assumed to be in UTC.
+///
+/// UEFI SystemTime is stored as Duration from 1900-01-01-00:00:00 with timezone -1440 as anchor
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct SystemTime(Duration);
 
-pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
+pub const UNIX_EPOCH: SystemTime = SystemTime::from_uefi(r_efi::efi::Time {
+    year: 1970,
+    month: 1,
+    day: 1,
+    hour: 0,
+    minute: 0,
+    second: 0,
+    nanosecond: 0,
+    timezone: 0,
+    daylight: 0,
+    pad1: 0,
+    pad2: 0,
+});
+
+const MAX_UEFI_TIME: SystemTime = SystemTime::from_uefi(r_efi::efi::Time {
+    year: 9999,
+    month: 12,
+    day: 31,
+    hour: 23,
+    minute: 59,
+    second: 59,
+    nanosecond: 999_999_999,
+    timezone: 1440,
+    daylight: 0,
+    pad1: 0,
+    pad2: 0,
+});
 
 impl Instant {
     pub fn now() -> Instant {
@@ -40,20 +66,45 @@ impl Instant {
 }
 
 impl SystemTime {
+    pub(crate) const fn from_uefi(t: r_efi::efi::Time) -> Self {
+        Self(system_time_internal::from_uefi(&t))
+    }
+
+    #[expect(dead_code)]
+    pub(crate) const fn to_uefi(self, timezone: i16, daylight: u8) -> Option<r_efi::efi::Time> {
+        system_time_internal::to_uefi(&self.0, timezone, daylight)
+    }
+
     pub fn now() -> SystemTime {
         system_time_internal::now()
             .unwrap_or_else(|| panic!("time not implemented on this platform"))
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime(self.0.checked_add(*other)?))
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+        let temp = self.0.checked_add(*other)?;
+
+        // Check if can be represented in UEFI
+        // FIXME: const PartialOrd
+        let mut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs();
+        if cmp == 0 {
+            cmp = temp.subsec_nanos() as u64 - MAX_UEFI_TIME.0.subsec_nanos() as u64;
+        }
+
+        if cmp <= 0 { Some(SystemTime(temp)) } else { None }
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
@@ -66,51 +117,132 @@ pub(crate) mod system_time_internal {
     use crate::mem::MaybeUninit;
     use crate::ptr::NonNull;
 
+    const SECS_IN_MINUTE: u64 = 60;
+    const SECS_IN_HOUR: u64 = SECS_IN_MINUTE * 60;
+    const SECS_IN_DAY: u64 = SECS_IN_HOUR * 24;
+    const TIMEZONE_DELTA: u64 = 1440 * SECS_IN_MINUTE;
+
     pub fn now() -> Option<SystemTime> {
         let runtime_services: NonNull<RuntimeServices> = helpers::runtime_services()?;
         let mut t: MaybeUninit<Time> = MaybeUninit::uninit();
         let r = unsafe {
             ((*runtime_services.as_ptr()).get_time)(t.as_mut_ptr(), crate::ptr::null_mut())
         };
-
         if r.is_error() {
             return None;
         }
 
         let t = unsafe { t.assume_init() };
 
-        Some(SystemTime(uefi_time_to_duration(t)))
+        Some(SystemTime::from_uefi(t))
     }
 
-    // This algorithm is based on the one described in the post
-    // https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html
-    pub(crate) const fn uefi_time_to_duration(t: r_efi::system::Time) -> Duration {
-        assert!(t.month <= 12);
-        assert!(t.month != 0);
+    /// This algorithm is a modified form of the one described in the post
+    /// https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html
+    ///
+    /// The changes are to use 1900-01-01-00:00:00 with timezone -1440 as anchor instead of UNIX
+    /// epoch used in the original algorithm.
+    pub(crate) const fn from_uefi(t: &Time) -> Duration {
+        assert!(t.month <= 12 && t.month != 0);
+        assert!(t.year >= 1900 && t.year <= 9999);
+        assert!(t.day <= 31 && t.day != 0);
+
+        assert!(t.second < 60);
+        assert!(t.minute < 60);
+        assert!(t.hour < 24);
+        assert!(t.nanosecond < 1_000_000_000);
+
+        assert!(
+            (t.timezone <= 1440 && t.timezone >= -1440)
+                || t.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE
+        );
 
         const YEAR_BASE: u32 = 4800; /* Before min year, multiple of 400. */
 
-        // Calculate the number of days since 1/1/1970
+        // Calculate the number of days since 1/1/1900. This is the earliest supported date in UEFI
+        // time.
         // Use 1 March as the start
         let (m_adj, overflow): (u32, bool) = (t.month as u32).overflowing_sub(3);
         let (carry, adjust): (u32, u32) = if overflow { (1, 12) } else { (0, 0) };
         let y_adj: u32 = (t.year as u32) + YEAR_BASE - carry;
         let month_days: u32 = (m_adj.wrapping_add(adjust) * 62719 + 769) / 2048;
         let leap_days: u32 = y_adj / 4 - y_adj / 100 + y_adj / 400;
-        let days: u32 = y_adj * 365 + leap_days + month_days + (t.day as u32 - 1) - 2472632;
+        let days: u32 = y_adj * 365 + leap_days + month_days + (t.day as u32 - 1) - 2447065;
 
         let localtime_epoch: u64 = (days as u64) * SECS_IN_DAY
             + (t.second as u64)
             + (t.minute as u64) * SECS_IN_MINUTE
             + (t.hour as u64) * SECS_IN_HOUR;
 
-        let utc_epoch: u64 = if t.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE {
-            localtime_epoch
+        // Calculate the offset from 1/1/1900 at timezone -1440 min
+        let adjusted_localtime_epoc: u64 = localtime_epoch + TIMEZONE_DELTA;
+
+        let epoch: u64 = if t.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE {
+            adjusted_localtime_epoc
         } else {
-            (localtime_epoch as i64 + (t.timezone as i64) * SECS_IN_MINUTE as i64) as u64
+            adjusted_localtime_epoc
+                .checked_add_signed((t.timezone as i64) * SECS_IN_MINUTE as i64)
+                .unwrap()
         };
 
-        Duration::new(utc_epoch, t.nanosecond)
+        Duration::new(epoch, t.nanosecond)
+    }
+
+    /// This algorithm is a modifed version of the one described in the post:
+    /// https://howardhinnant.github.io/date_algorithms.html#clive_from_days
+    ///
+    /// The changes are to use 1900-01-01-00:00:00 with timezone -1440 as anchor instead of UNIX
+    /// epoch used in the original algorithm.
+    pub(crate) const fn to_uefi(dur: &Duration, timezone: i16, daylight: u8) -> Option<Time> {
+        // Check timzone validity
+        assert!(timezone <= 1440 && timezone >= -1440);
+
+        // FIXME(#126043): use checked_sub_signed once stablized
+        let secs =
+            dur.as_secs().checked_add_signed((-timezone as i64) * SECS_IN_MINUTE as i64).unwrap();
+
+        // Convert to seconds since 1900-01-01-00:00:00 in timezone.
+        let Some(secs) = secs.checked_sub(TIMEZONE_DELTA) else { return None };
+
+        let days = secs / SECS_IN_DAY;
+        let remaining_secs = secs % SECS_IN_DAY;
+
+        let z = days + 693901;
+        let era = z / 146097;
+        let doe = z - (era * 146097);
+        let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
+        let mut y = yoe + era * 400;
+        let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
+        let mp = (5 * doy + 2) / 153;
+        let d = doy - (153 * mp + 2) / 5 + 1;
+        let m = if mp < 10 { mp + 3 } else { mp - 9 };
+
+        if m <= 2 {
+            y += 1;
+        }
+
+        let hour = (remaining_secs / SECS_IN_HOUR) as u8;
+        let minute = ((remaining_secs % SECS_IN_HOUR) / SECS_IN_MINUTE) as u8;
+        let second = (remaining_secs % SECS_IN_MINUTE) as u8;
+
+        // Check Bounds
+        if y >= 1900 && y <= 9999 {
+            Some(Time {
+                year: y as u16,
+                month: m as u8,
+                day: d as u8,
+                hour,
+                minute,
+                second,
+                nanosecond: dur.subsec_nanos(),
+                timezone,
+                daylight,
+                pad1: 0,
+                pad2: 0,
+            })
+        } else {
+            None
+        }
     }
 }
 
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index d89100e6919..0d2100d66bc 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -119,7 +119,8 @@ mod imp {
                     && thread_info.guard_page_range.contains(&fault_addr)
                 {
                     let name = thread_info.thread_name.as_deref().unwrap_or("<unknown>");
-                    rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                    let tid = crate::thread::current_os_id();
+                    rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
                     rtabort!("stack overflow");
                 }
             })
@@ -696,7 +697,8 @@ mod imp {
             if code == c::EXCEPTION_STACK_OVERFLOW {
                 crate::thread::with_current_name(|name| {
                     let name = name.unwrap_or("<unknown>");
-                    rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                    let tid = crate::thread::current_os_id();
+                    rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
                 });
             }
             c::EXCEPTION_CONTINUE_SEARCH
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7f6440152d4..24b65c11fd2 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -77,7 +77,18 @@ impl Thread {
                     let page_size = os::page_size();
                     let stack_size =
                         (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
-                    assert_eq!(libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size), 0);
+
+                    // Some libc implementations, e.g. musl, place an upper bound
+                    // on the stack size, in which case we can only gracefully return
+                    // an error here.
+                    if libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size) != 0 {
+                        assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0);
+                        drop(Box::from_raw(data));
+                        return Err(io::const_error!(
+                            io::ErrorKind::InvalidInput,
+                            "invalid stack size"
+                        ));
+                    }
                 }
             };
         }
@@ -398,6 +409,62 @@ impl Drop for Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    // Most Unix platforms have a way to query an integer ID of the current thread, all with
+    // slightly different spellings.
+    //
+    // The OS thread ID is used rather than `pthread_self` so as to match what will be displayed
+    // for process inspection (debuggers, trace, `top`, etc.).
+    cfg_if::cfg_if! {
+        // Most platforms have a function returning a `pid_t` or int, which is an `i32`.
+        if #[cfg(any(target_os = "android", target_os = "linux"))] {
+            use crate::sys::weak::syscall;
+
+            // `libc::gettid` is only available on glibc 2.30+, but the syscall is available
+            // since Linux 2.4.11.
+            syscall!(fn gettid() -> libc::pid_t;);
+
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { gettid() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "nto")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { libc::gettid() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "openbsd")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { libc::getthrid() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "freebsd")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "netbsd")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::lwpid_t = unsafe { libc::_lwp_self() };
+            Some(id as u64)
+        } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
+            // On Illumos and Solaris, the `pthread_t` is the same as the OS thread ID.
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pthread_t = unsafe { libc::pthread_self() };
+            Some(id as u64)
+        } else if #[cfg(target_vendor = "apple")] {
+            // Apple allows querying arbitrary thread IDs, `thread=NULL` queries the current thread.
+            let mut id = 0u64;
+            // SAFETY: `thread_id` is a valid pointer, no other preconditions.
+            let status: libc::c_int = unsafe { libc::pthread_threadid_np(0, &mut id) };
+            if status == 0 {
+                Some(id)
+            } else {
+                None
+            }
+        } else {
+            // Other platforms don't have an OS thread ID or don't have a way to access it.
+            None
+        }
+    }
+}
+
 #[cfg(any(
     target_os = "linux",
     target_os = "nto",
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index bd7f74fea6a..328fe0bc960 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -38,15 +38,18 @@ impl SystemTime {
         SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         self.t.sub_timespec(&other.t)
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime { t: self.t.checked_add_duration(other)? })
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime { t: self.t.checked_sub_duration(other)? })
     }
 }
@@ -133,8 +136,15 @@ impl Timespec {
         Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap()
     }
 
-    pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        if self >= other {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        // FIXME: const PartialOrd
+        let mut cmp = self.tv_sec - other.tv_sec;
+        if cmp == 0 {
+            cmp = self.tv_nsec.as_inner() as i64 - other.tv_nsec.as_inner() as i64;
+        }
+
+        if cmp >= 0 {
             // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
             // to optimize it into a branchless form (see also #75545):
             //
@@ -169,7 +179,8 @@ impl Timespec {
         }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?;
 
         // Nano calculations can't overflow because nanos are <1B which fit
@@ -179,10 +190,11 @@ impl Timespec {
             nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
         }
-        Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
+        Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?;
 
         // Similar to above, nanos can't overflow.
@@ -191,7 +203,7 @@ impl Timespec {
             nsec += NSEC_PER_SEC as i32;
             secs = secs.checked_sub(1)?;
         }
-        Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
+        Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
     }
 
     #[allow(dead_code)]
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs
index 5a1e3fde986..34d9b5ec70c 100644
--- a/library/std/src/sys/pal/unsupported/thread.rs
+++ b/library/std/src/sys/pal/unsupported/thread.rs
@@ -39,6 +39,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
diff --git a/library/std/src/sys/pal/unsupported/time.rs b/library/std/src/sys/pal/unsupported/time.rs
index 6d67b538a96..0c387917044 100644
--- a/library/std/src/sys/pal/unsupported/time.rs
+++ b/library/std/src/sys/pal/unsupported/time.rs
@@ -31,15 +31,22 @@ impl SystemTime {
         panic!("time not implemented on this platform")
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index a46c74630c9..4755e2ef5da 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -194,6 +194,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     cfg_if::cfg_if! {
         if #[cfg(target_feature = "atomics")] {
diff --git a/library/std/src/sys/pal/wasi/time.rs b/library/std/src/sys/pal/wasi/time.rs
index 0d8d0b59ac1..892661b312b 100644
--- a/library/std/src/sys/pal/wasi/time.rs
+++ b/library/std/src/sys/pal/wasi/time.rs
@@ -43,23 +43,34 @@ impl SystemTime {
         SystemTime(current_time(wasi::CLOCKID_REALTIME))
     }
 
-    pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 
-    pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
-        self.0.as_nanos().try_into().ok()
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
+        // FIXME: const TryInto
+        let ns = self.0.as_nanos();
+        if ns <= u64::MAX as u128 { Some(ns as u64) } else { None }
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
index ebfabaafc79..42a7dbdf8b8 100644
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ b/library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -56,6 +56,10 @@ impl Thread {
     pub fn join(self) {}
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 827d96e73db..abc1c19827f 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2158,6 +2158,7 @@ GetCurrentDirectoryW
 GetCurrentProcess
 GetCurrentProcessId
 GetCurrentThread
+GetCurrentThreadId
 GetEnvironmentStringsW
 GetEnvironmentVariableW
 GetExitCodeProcess
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index b2e3aabc633..989a1246650 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -38,6 +38,7 @@ windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferle
 windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetCurrentThread() -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn GetCurrentThreadId() -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentStringsW() -> PWSTR);
 windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentVariableW(lpname : PCWSTR, lpbuffer : PWSTR, nsize : u32) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess : HANDLE, lpexitcode : *mut u32) -> BOOL);
diff --git a/library/std/src/sys/pal/windows/stack_overflow.rs b/library/std/src/sys/pal/windows/stack_overflow.rs
index 734cd30bed0..9a40551b985 100644
--- a/library/std/src/sys/pal/windows/stack_overflow.rs
+++ b/library/std/src/sys/pal/windows/stack_overflow.rs
@@ -20,7 +20,8 @@ unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POIN
         if code == c::EXCEPTION_STACK_OVERFLOW {
             thread::with_current_name(|name| {
                 let name = name.unwrap_or("<unknown>");
-                rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                let tid = thread::current_os_id();
+                rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
             });
         }
         c::EXCEPTION_CONTINUE_SEARCH
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index b45f76fb546..b0e38220a2d 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -127,6 +127,14 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    // SAFETY: FFI call with no preconditions.
+    let id: u32 = unsafe { c::GetCurrentThreadId() };
+
+    // A return value of 0 indicates failed lookup.
+    if id == 0 { None } else { Some(id.into()) }
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     let res = unsafe {
         let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed();
diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs
index 68126bd8d2f..a948c07e0a3 100644
--- a/library/std/src/sys/pal/windows/time.rs
+++ b/library/std/src/sys/pal/windows/time.rs
@@ -72,7 +72,8 @@ impl SystemTime {
         }
     }
 
-    fn from_intervals(intervals: i64) -> SystemTime {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn from_intervals(intervals: i64) -> SystemTime {
         SystemTime {
             t: c::FILETIME {
                 dwLowDateTime: intervals as u32,
@@ -81,11 +82,13 @@ impl SystemTime {
         }
     }
 
-    fn intervals(&self) -> i64 {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn intervals(&self) -> i64 {
         (self.t.dwLowDateTime as i64) | ((self.t.dwHighDateTime as i64) << 32)
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         let me = self.intervals();
         let other = other.intervals();
         if me >= other {
@@ -95,12 +98,14 @@ impl SystemTime {
         }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?;
         Some(SystemTime::from_intervals(intervals))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
         Some(SystemTime::from_intervals(intervals))
     }
@@ -150,15 +155,18 @@ impl Hash for SystemTime {
     }
 }
 
-fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
-    dur.as_secs()
+#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+const fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
+    // FIXME: const TryInto
+    let secs = dur
+        .as_secs()
         .checked_mul(INTERVALS_PER_SEC)?
-        .checked_add(dur.subsec_nanos() as u64 / 100)?
-        .try_into()
-        .ok()
+        .checked_add(dur.subsec_nanos() as u64 / 100)?;
+    if secs <= i64::MAX as u64 { Some(secs.cast_signed()) } else { None }
 }
 
-fn intervals2dur(intervals: u64) -> Duration {
+#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+const fn intervals2dur(intervals: u64) -> Duration {
     Duration::new(intervals / INTERVALS_PER_SEC, ((intervals % INTERVALS_PER_SEC) * 100) as u32)
 }
 
diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs
index f2404a62abf..92803c94c6e 100644
--- a/library/std/src/sys/pal/xous/thread.rs
+++ b/library/std/src/sys/pal/xous/thread.rs
@@ -145,6 +145,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // We're unicore right now.
     Ok(unsafe { NonZero::new_unchecked(1) })
diff --git a/library/std/src/sys/pal/xous/time.rs b/library/std/src/sys/pal/xous/time.rs
index ae8be81c0b7..d737416436e 100644
--- a/library/std/src/sys/pal/xous/time.rs
+++ b/library/std/src/sys/pal/xous/time.rs
@@ -43,15 +43,22 @@ impl SystemTime {
         SystemTime { 0: Duration::from_millis((upper as u64) << 32 | lower as u64) }
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs
index 1ee3fbd285f..f9e15b82475 100644
--- a/library/std/src/sys/process/windows.rs
+++ b/library/std/src/sys/process/windows.rs
@@ -623,16 +623,10 @@ impl Stdio {
             // permissions as well as the ability to be inherited to child
             // processes (as this is about to be inherited).
             Stdio::Null => {
-                let size = size_of::<c::SECURITY_ATTRIBUTES>();
-                let mut sa = c::SECURITY_ATTRIBUTES {
-                    nLength: size as u32,
-                    lpSecurityDescriptor: ptr::null_mut(),
-                    bInheritHandle: 1,
-                };
                 let mut opts = OpenOptions::new();
                 opts.read(stdio_id == c::STD_INPUT_HANDLE);
                 opts.write(stdio_id != c::STD_INPUT_HANDLE);
-                opts.security_attributes(&mut sa);
+                opts.inherit_handle(true);
                 File::open(Path::new(r"\\.\NUL"), &opts).map(|file| file.into_inner())
             }
         }