about summary refs log tree commit diff
path: root/library/std
diff options
context:
space:
mode:
Diffstat (limited to 'library/std')
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/panicking.rs18
-rw-r--r--library/std/src/sys/cloudabi/abi/cloudabi.rs133
-rw-r--r--library/std/src/sys/cloudabi/mod.rs2
-rw-r--r--library/std/src/sys/cloudabi/mutex.rs4
-rw-r--r--library/std/src/sys/hermit/fs.rs4
-rw-r--r--library/std/src/sys/hermit/mod.rs1
-rw-r--r--library/std/src/sys/hermit/mutex.rs190
-rw-r--r--library/std/src/sys/hermit/process.rs149
-rw-r--r--library/std/src/sys/mod.rs1
11 files changed, 276 insertions, 229 deletions
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 47b59d4a677..5925aa87a3f 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -42,7 +42,7 @@ dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] }
 fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies]
-hermit-abi = { version = "0.1.15", features = ['rustc-dep-of-std'] }
+hermit-abi = { version = "0.1.17", features = ['rustc-dep-of-std'] }
 
 [target.wasm32-wasi.dependencies]
 wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 30e7a7f3c3b..3da0ebdd498 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -259,6 +259,7 @@
 #![feature(exhaustive_patterns)]
 #![feature(extend_one)]
 #![feature(external_doc)]
+#![feature(fmt_as_str)]
 #![feature(fn_traits)]
 #![feature(format_args_nl)]
 #![feature(gen_future)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 8dceb12de87..221ae809e23 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -478,10 +478,26 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
         }
     }
 
+    struct StrPanicPayload(&'static str);
+
+    unsafe impl BoxMeUp for StrPanicPayload {
+        fn take_box(&mut self) -> *mut (dyn Any + Send) {
+            Box::into_raw(Box::new(self.0))
+        }
+
+        fn get(&mut self) -> &(dyn Any + Send) {
+            &self.0
+        }
+    }
+
     let loc = info.location().unwrap(); // The current implementation always returns Some
     let msg = info.message().unwrap(); // The current implementation always returns Some
     crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
-        rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
+        if let Some(msg) = msg.as_str() {
+            rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc);
+        } else {
+            rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
+        }
     })
 }
 
diff --git a/library/std/src/sys/cloudabi/abi/cloudabi.rs b/library/std/src/sys/cloudabi/abi/cloudabi.rs
index b02faf1830c..5c4e3fd85c4 100644
--- a/library/std/src/sys/cloudabi/abi/cloudabi.rs
+++ b/library/std/src/sys/cloudabi/abi/cloudabi.rs
@@ -1910,7 +1910,7 @@ extern "C" {
 /// The resolution of the clock.
 #[inline]
 pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> errno {
-    cloudabi_sys_clock_res_get(clock_id_, resolution_)
+    unsafe { cloudabi_sys_clock_res_get(clock_id_, resolution_) }
 }
 
 /// Obtains the time value of a clock.
@@ -1934,7 +1934,7 @@ pub unsafe fn clock_time_get(
     precision_: timestamp,
     time_: *mut timestamp,
 ) -> errno {
-    cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
+    unsafe { cloudabi_sys_clock_time_get(clock_id_, precision_, time_) }
 }
 
 /// Wakes up threads waiting on a userspace condition variable.
@@ -1961,7 +1961,7 @@ pub unsafe fn clock_time_get(
 /// threads, all threads are woken up.
 #[inline]
 pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno {
-    cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_)
+    unsafe { cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_) }
 }
 
 /// Closes a file descriptor.
@@ -1972,7 +1972,7 @@ pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: n
 /// The file descriptor that needs to be closed.
 #[inline]
 pub unsafe fn fd_close(fd_: fd) -> errno {
-    cloudabi_sys_fd_close(fd_)
+    unsafe { cloudabi_sys_fd_close(fd_) }
 }
 
 /// Creates a file descriptor.
@@ -1990,7 +1990,7 @@ pub unsafe fn fd_close(fd_: fd) -> errno {
 /// The file descriptor that has been created.
 #[inline]
 pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno {
-    cloudabi_sys_fd_create1(type_, fd_)
+    unsafe { cloudabi_sys_fd_create1(type_, fd_) }
 }
 
 /// Creates a pair of file descriptors.
@@ -2013,7 +2013,8 @@ pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno {
 /// The second file descriptor of the pair.
 #[inline]
 pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno {
-    cloudabi_sys_fd_create2(type_, fd1_, fd2_)
+    // SAFETY: the caller must uphold the safety contract for `cloudabi_sys_fd_create2`.
+    unsafe { cloudabi_sys_fd_create2(type_, fd1_, fd2_) }
 }
 
 /// Synchronizes the data of a file to disk.
@@ -2025,7 +2026,9 @@ pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno
 /// needs to be synchronized to disk.
 #[inline]
 pub unsafe fn fd_datasync(fd_: fd) -> errno {
-    cloudabi_sys_fd_datasync(fd_)
+    // SAFETY: the caller must guarantee that `fd` is valid
+    // for synchronization.
+    unsafe { cloudabi_sys_fd_datasync(fd_) }
 }
 
 /// Duplicates a file descriptor.
@@ -2040,7 +2043,7 @@ pub unsafe fn fd_datasync(fd_: fd) -> errno {
 /// The new file descriptor.
 #[inline]
 pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno {
-    cloudabi_sys_fd_dup(from_, fd_)
+    unsafe { cloudabi_sys_fd_dup(from_, fd_) }
 }
 
 /// Reads from a file descriptor, without using and updating the
@@ -2064,7 +2067,7 @@ pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno {
 /// The number of bytes read.
 #[inline]
 pub unsafe fn fd_pread(fd_: fd, iovs_: &[iovec], offset_: filesize, nread_: &mut usize) -> errno {
-    cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_)
+    unsafe { cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_) }
 }
 
 /// Writes to a file descriptor, without using and updating the
@@ -2093,7 +2096,7 @@ pub unsafe fn fd_pwrite(
     offset_: filesize,
     nwritten_: &mut usize,
 ) -> errno {
-    cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_)
+    unsafe { cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_) }
 }
 
 /// Reads from a file descriptor.
@@ -2112,7 +2115,7 @@ pub unsafe fn fd_pwrite(
 /// The number of bytes read.
 #[inline]
 pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: &mut usize) -> errno {
-    cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_)
+    unsafe { cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_) }
 }
 
 /// Atomically replaces a file descriptor by a copy of another
@@ -2138,7 +2141,7 @@ pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: &mut usize) -> errno {
 /// overwritten.
 #[inline]
 pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno {
-    cloudabi_sys_fd_replace(from_, to_)
+    unsafe { cloudabi_sys_fd_replace(from_, to_) }
 }
 
 /// Moves the offset of the file descriptor.
@@ -2166,7 +2169,7 @@ pub unsafe fn fd_seek(
     whence_: whence,
     newoffset_: &mut filesize,
 ) -> errno {
-    cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_)
+    unsafe { cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_) }
 }
 
 /// Gets attributes of a file descriptor.
@@ -2182,7 +2185,7 @@ pub unsafe fn fd_seek(
 /// attributes are stored.
 #[inline]
 pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
-    cloudabi_sys_fd_stat_get(fd_, buf_)
+    unsafe { cloudabi_sys_fd_stat_get(fd_, buf_) }
 }
 
 /// Adjusts attributes of a file descriptor.
@@ -2202,7 +2205,7 @@ pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
 /// be adjusted.
 #[inline]
 pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno {
-    cloudabi_sys_fd_stat_put(fd_, buf_, flags_)
+    unsafe { cloudabi_sys_fd_stat_put(fd_, buf_, flags_) }
 }
 
 /// Synchronizes the data and metadata of a file to disk.
@@ -2214,7 +2217,7 @@ pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> err
 /// and metadata needs to be synchronized to disk.
 #[inline]
 pub unsafe fn fd_sync(fd_: fd) -> errno {
-    cloudabi_sys_fd_sync(fd_)
+    unsafe { cloudabi_sys_fd_sync(fd_) }
 }
 
 /// Writes to a file descriptor.
@@ -2233,7 +2236,7 @@ pub unsafe fn fd_sync(fd_: fd) -> errno {
 /// The number of bytes written.
 #[inline]
 pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: &mut usize) -> errno {
-    cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_)
+    unsafe { cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_) }
 }
 
 /// Provides file advisory information on a file descriptor.
@@ -2256,7 +2259,7 @@ pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: &mut usize) -> errn
 /// The advice.
 #[inline]
 pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno {
-    cloudabi_sys_file_advise(fd_, offset_, len_, advice_)
+    unsafe { cloudabi_sys_file_advise(fd_, offset_, len_, advice_) }
 }
 
 /// Forces the allocation of space in a file.
@@ -2275,7 +2278,7 @@ pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: a
 /// The length of the area that is allocated.
 #[inline]
 pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno {
-    cloudabi_sys_file_allocate(fd_, offset_, len_)
+    unsafe { cloudabi_sys_file_allocate(fd_, offset_, len_) }
 }
 
 /// Creates a file of a specified type.
@@ -2296,7 +2299,7 @@ pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno
 ///     Creates a directory.
 #[inline]
 pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
-    cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)
+    unsafe { cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)}
 }
 
 /// Creates a hard link.
@@ -2320,7 +2323,7 @@ pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
 /// should be created.
 #[inline]
 pub unsafe fn file_link(fd1_: lookup, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
-    cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
+    unsafe { cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len()) }
 }
 
 /// Opens a file.
@@ -2362,7 +2365,7 @@ pub unsafe fn file_open(
     fds_: *const fdstat,
     fd_: &mut fd,
 ) -> errno {
-    cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_)
+    unsafe { cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_) }
 }
 
 /// Reads directory entries from a directory.
@@ -2402,7 +2405,7 @@ pub unsafe fn file_readdir(
     cookie_: dircookie,
     bufused_: &mut usize,
 ) -> errno {
-    cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_)
+    unsafe { cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_) }
 }
 
 /// Reads the contents of a symbolic link.
@@ -2425,14 +2428,16 @@ pub unsafe fn file_readdir(
 /// The number of bytes placed in the buffer.
 #[inline]
 pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: &mut usize) -> errno {
-    cloudabi_sys_file_readlink(
-        fd_,
-        path_.as_ptr(),
-        path_.len(),
-        buf_.as_mut_ptr(),
-        buf_.len(),
-        bufused_,
-    )
+    unsafe {
+        cloudabi_sys_file_readlink(
+            fd_,
+            path_.as_ptr(),
+            path_.len(),
+            buf_.as_mut_ptr(),
+            buf_.len(),
+            bufused_,
+        )
+    }
 }
 
 /// Renames a file.
@@ -2456,14 +2461,16 @@ pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: &m
 /// be renamed.
 #[inline]
 pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
-    cloudabi_sys_file_rename(
-        fd1_,
-        path1_.as_ptr(),
-        path1_.len(),
-        fd2_,
-        path2_.as_ptr(),
-        path2_.len(),
-    )
+    unsafe {
+        cloudabi_sys_file_rename(
+            fd1_,
+            path1_.as_ptr(),
+            path1_.len(),
+            fd2_,
+            path2_.as_ptr(),
+            path2_.len(),
+        )
+    }
 }
 
 /// Gets attributes of a file by file descriptor.
@@ -2479,7 +2486,7 @@ pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> e
 /// stored.
 #[inline]
 pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
-    cloudabi_sys_file_stat_fget(fd_, buf_)
+    unsafe { cloudabi_sys_file_stat_fget(fd_, buf_) }
 }
 
 /// Adjusts attributes of a file by file descriptor.
@@ -2499,7 +2506,7 @@ pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
 /// be adjusted.
 #[inline]
 pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno {
-    cloudabi_sys_file_stat_fput(fd_, buf_, flags_)
+    unsafe { cloudabi_sys_file_stat_fput(fd_, buf_, flags_) }
 }
 
 /// Gets attributes of a file by path.
@@ -2520,7 +2527,7 @@ pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) ->
 /// stored.
 #[inline]
 pub unsafe fn file_stat_get(fd_: lookup, path_: &[u8], buf_: *mut filestat) -> errno {
-    cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_)
+    unsafe { cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_) }
 }
 
 /// Adjusts attributes of a file by path.
@@ -2550,7 +2557,7 @@ pub unsafe fn file_stat_put(
     buf_: *const filestat,
     flags_: fsflags,
 ) -> errno {
-    cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_)
+    unsafe { cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_) }
 }
 
 /// Creates a symbolic link.
@@ -2569,7 +2576,7 @@ pub unsafe fn file_stat_put(
 /// link should be created.
 #[inline]
 pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
-    cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len())
+    unsafe { cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len()) }
 }
 
 /// Unlinks a file, or removes a directory.
@@ -2591,7 +2598,7 @@ pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
 ///     Otherwise, unlink a file.
 #[inline]
 pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
-    cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_)
+    unsafe { cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_) }
 }
 
 /// Unlocks a write-locked userspace lock.
@@ -2618,7 +2625,7 @@ pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
 /// shared memory.
 #[inline]
 pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
-    cloudabi_sys_lock_unlock(lock_, scope_)
+    unsafe { cloudabi_sys_lock_unlock(lock_, scope_) }
 }
 
 /// Provides memory advisory information on a region of memory.
@@ -2633,7 +2640,7 @@ pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
 /// The advice.
 #[inline]
 pub unsafe fn mem_advise(mapping_: &mut [u8], advice_: advice) -> errno {
-    cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_)
+    unsafe { cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_) }
 }
 
 /// Creates a memory mapping, making the contents of a file
@@ -2682,7 +2689,7 @@ pub unsafe fn mem_map(
     off_: filesize,
     mem_: &mut *mut (),
 ) -> errno {
-    cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_)
+    unsafe { cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_) }
 }
 
 /// Changes the protection of a memory mapping.
@@ -2696,7 +2703,7 @@ pub unsafe fn mem_map(
 /// New protection options.
 #[inline]
 pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
-    cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_)
+    unsafe { cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_) }
 }
 
 /// Synchronizes a region of memory with its physical storage.
@@ -2710,7 +2717,7 @@ pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
 /// The method of synchronization.
 #[inline]
 pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
-    cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_)
+    unsafe { cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_) }
 }
 
 /// Unmaps a region of memory.
@@ -2721,7 +2728,7 @@ pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
 /// The pages that needs to be unmapped.
 #[inline]
 pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
-    cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len())
+    unsafe { cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len()) }
 }
 
 /// Concurrently polls for the occurrence of a set of events.
@@ -2746,7 +2753,7 @@ pub unsafe fn poll(
     nsubscriptions_: usize,
     nevents_: *mut usize,
 ) -> errno {
-    cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
+    unsafe { cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_) }
 }
 
 /// Replaces the process by a new executable.
@@ -2784,7 +2791,7 @@ pub unsafe fn poll(
 /// execution.
 #[inline]
 pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
-    cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len())
+    unsafe { cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len()) }
 }
 
 /// Terminates the process normally.
@@ -2797,7 +2804,7 @@ pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
 /// through [`event.union.proc_terminate.exitcode`](struct.event_proc_terminate.html#structfield.exitcode).
 #[inline]
 pub unsafe fn proc_exit(rval_: exitcode) -> ! {
-    cloudabi_sys_proc_exit(rval_)
+    unsafe { cloudabi_sys_proc_exit(rval_) }
 }
 
 /// Forks the process of the calling thread.
@@ -2822,7 +2829,7 @@ pub unsafe fn proc_exit(rval_: exitcode) -> ! {
 /// initial thread of the child process.
 #[inline]
 pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno {
-    cloudabi_sys_proc_fork(fd_, tid_)
+    unsafe { cloudabi_sys_proc_fork(fd_, tid_) }
 }
 
 /// Sends a signal to the process of the calling thread.
@@ -2837,7 +2844,7 @@ pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno {
 /// [`event.union.proc_terminate.signal`](struct.event_proc_terminate.html#structfield.signal).
 #[inline]
 pub unsafe fn proc_raise(sig_: signal) -> errno {
-    cloudabi_sys_proc_raise(sig_)
+    unsafe { cloudabi_sys_proc_raise(sig_) }
 }
 
 /// Obtains random data from the kernel random number generator.
@@ -2853,7 +2860,7 @@ pub unsafe fn proc_raise(sig_: signal) -> errno {
 /// data.
 #[inline]
 pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
-    cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len())
+    unsafe { cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len()) }
 }
 
 /// Receives a message on a socket.
@@ -2871,7 +2878,7 @@ pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
 /// Output parameters.
 #[inline]
 pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) -> errno {
-    cloudabi_sys_sock_recv(sock_, in_, out_)
+    unsafe { cloudabi_sys_sock_recv(sock_, in_, out_) }
 }
 
 /// Sends a message on a socket.
@@ -2888,7 +2895,7 @@ pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) ->
 /// Output parameters.
 #[inline]
 pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) -> errno {
-    cloudabi_sys_sock_send(sock_, in_, out_)
+    unsafe { cloudabi_sys_sock_send(sock_, in_, out_) }
 }
 
 /// Shuts down socket send and receive channels.
@@ -2903,7 +2910,7 @@ pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) ->
 /// down.
 #[inline]
 pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
-    cloudabi_sys_sock_shutdown(sock_, how_)
+    unsafe { cloudabi_sys_sock_shutdown(sock_, how_) }
 }
 
 /// Creates a new thread within the current process.
@@ -2917,7 +2924,7 @@ pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
 /// The thread ID of the new thread.
 #[inline]
 pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno {
-    cloudabi_sys_thread_create(attr_, tid_)
+    unsafe { cloudabi_sys_thread_create(attr_, tid_) }
 }
 
 /// Terminates the calling thread.
@@ -2937,11 +2944,11 @@ pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno {
 /// shared memory.
 #[inline]
 pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! {
-    cloudabi_sys_thread_exit(lock_, scope_)
+    unsafe { cloudabi_sys_thread_exit(lock_, scope_) }
 }
 
 /// Temporarily yields execution of the calling thread.
 #[inline]
 pub unsafe fn thread_yield() -> errno {
-    cloudabi_sys_thread_yield()
+    unsafe { cloudabi_sys_thread_yield() }
 }
diff --git a/library/std/src/sys/cloudabi/mod.rs b/library/std/src/sys/cloudabi/mod.rs
index f7dd2c8d00f..13f1bc8826e 100644
--- a/library/std/src/sys/cloudabi/mod.rs
+++ b/library/std/src/sys/cloudabi/mod.rs
@@ -1,3 +1,5 @@
+#![deny(unsafe_op_in_unsafe_fn)]
+
 use crate::io::ErrorKind;
 use crate::mem;
 
diff --git a/library/std/src/sys/cloudabi/mutex.rs b/library/std/src/sys/cloudabi/mutex.rs
index 1203d8de0c5..9dafcbc1fba 100644
--- a/library/std/src/sys/cloudabi/mutex.rs
+++ b/library/std/src/sys/cloudabi/mutex.rs
@@ -103,7 +103,9 @@ impl ReentrantMutex {
             };
             let mut event = MaybeUninit::<abi::event>::uninit();
             let mut nevents = MaybeUninit::<usize>::uninit();
-            let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
+            // SAFE: The caller must to ensure that `event` and `nevents` are initialized.
+            let ret =
+                unsafe { abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr()) };
             assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire mutex");
             let event = event.assume_init();
             assert_eq!(event.error, abi::errno::SUCCESS, "Failed to acquire mutex");
diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index 82ccab1462b..829d4c943f1 100644
--- a/library/std/src/sys/hermit/fs.rs
+++ b/library/std/src/sys/hermit/fs.rs
@@ -334,10 +334,6 @@ impl File {
     pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
         Err(Error::from_raw_os_error(22))
     }
-
-    pub fn diverge(&self) -> ! {
-        loop {}
-    }
 }
 
 impl DirBuilder {
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 8eaf07e52d6..af05310a8d3 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -31,6 +31,7 @@ pub mod net;
 pub mod os;
 pub mod path;
 pub mod pipe;
+#[path = "../unsupported/process.rs"]
 pub mod process;
 pub mod rwlock;
 pub mod stack_overflow;
diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index 3d4813209cb..f988a019cfe 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -1,44 +1,214 @@
+use crate::cell::UnsafeCell;
+use crate::collections::VecDeque;
 use crate::ffi::c_void;
+use crate::ops::{Deref, DerefMut, Drop};
 use crate::ptr;
+use crate::sync::atomic::{spin_loop_hint, AtomicUsize, Ordering};
 use crate::sys::hermit::abi;
 
+/// This type provides a lock based on busy waiting to realize mutual exclusion
+///
+/// # Description
+///
+/// This structure behaves a lot like a common mutex. There are some differences:
+///
+/// - By using busy waiting, it can be used outside the runtime.
+/// - It is a so called ticket lock and is completly fair.
+#[cfg_attr(target_arch = "x86_64", repr(align(128)))]
+#[cfg_attr(not(target_arch = "x86_64"), repr(align(64)))]
+struct Spinlock<T: ?Sized> {
+    queue: AtomicUsize,
+    dequeue: AtomicUsize,
+    data: UnsafeCell<T>,
+}
+
+unsafe impl<T: ?Sized + Send> Sync for Spinlock<T> {}
+unsafe impl<T: ?Sized + Send> Send for Spinlock<T> {}
+
+/// A guard to which the protected data can be accessed
+///
+/// When the guard falls out of scope it will release the lock.
+struct SpinlockGuard<'a, T: ?Sized + 'a> {
+    dequeue: &'a AtomicUsize,
+    data: &'a mut T,
+}
+
+impl<T> Spinlock<T> {
+    pub const fn new(user_data: T) -> Spinlock<T> {
+        Spinlock {
+            queue: AtomicUsize::new(0),
+            dequeue: AtomicUsize::new(1),
+            data: UnsafeCell::new(user_data),
+        }
+    }
+
+    #[inline]
+    fn obtain_lock(&self) {
+        let ticket = self.queue.fetch_add(1, Ordering::SeqCst) + 1;
+        while self.dequeue.load(Ordering::SeqCst) != ticket {
+            spin_loop_hint();
+        }
+    }
+
+    #[inline]
+    pub unsafe fn lock(&self) -> SpinlockGuard<'_, T> {
+        self.obtain_lock();
+        SpinlockGuard { dequeue: &self.dequeue, data: &mut *self.data.get() }
+    }
+}
+
+impl<T: ?Sized + Default> Default for Spinlock<T> {
+    fn default() -> Spinlock<T> {
+        Spinlock::new(Default::default())
+    }
+}
+
+impl<'a, T: ?Sized> Deref for SpinlockGuard<'a, T> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        &*self.data
+    }
+}
+
+impl<'a, T: ?Sized> DerefMut for SpinlockGuard<'a, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut *self.data
+    }
+}
+
+impl<'a, T: ?Sized> Drop for SpinlockGuard<'a, T> {
+    /// The dropping of the SpinlockGuard will release the lock it was created from.
+    fn drop(&mut self) {
+        self.dequeue.fetch_add(1, Ordering::SeqCst);
+    }
+}
+
+/// Realize a priority queue for tasks
+struct PriorityQueue {
+    queues: [Option<VecDeque<abi::Tid>>; abi::NO_PRIORITIES],
+    prio_bitmap: u64,
+}
+
+impl PriorityQueue {
+    pub const fn new() -> PriorityQueue {
+        PriorityQueue {
+            queues: [
+                None, None, None, None, None, None, None, None, None, None, None, None, None, None,
+                None, None, None, None, None, None, None, None, None, None, None, None, None, None,
+                None, None, None,
+            ],
+            prio_bitmap: 0,
+        }
+    }
+
+    /// Add a task id by its priority to the queue
+    pub fn push(&mut self, prio: abi::Priority, id: abi::Tid) {
+        let i: usize = prio.into().into();
+        self.prio_bitmap |= (1 << i) as u64;
+        if let Some(queue) = &mut self.queues[i] {
+            queue.push_back(id);
+        } else {
+            let mut queue = VecDeque::new();
+            queue.push_back(id);
+            self.queues[i] = Some(queue);
+        }
+    }
+
+    fn pop_from_queue(&mut self, queue_index: usize) -> Option<abi::Tid> {
+        if let Some(queue) = &mut self.queues[queue_index] {
+            let id = queue.pop_front();
+
+            if queue.is_empty() {
+                self.prio_bitmap &= !(1 << queue_index as u64);
+            }
+
+            id
+        } else {
+            None
+        }
+    }
+
+    /// Pop the task handle with the highest priority from the queue
+    pub fn pop(&mut self) -> Option<abi::Tid> {
+        for i in 0..abi::NO_PRIORITIES {
+            if self.prio_bitmap & (1 << i) != 0 {
+                return self.pop_from_queue(i);
+            }
+        }
+
+        None
+    }
+}
+
+struct MutexInner {
+    locked: bool,
+    blocked_task: PriorityQueue,
+}
+
+impl MutexInner {
+    pub const fn new() -> MutexInner {
+        MutexInner { locked: false, blocked_task: PriorityQueue::new() }
+    }
+}
+
 pub struct Mutex {
-    inner: *const c_void,
+    inner: Spinlock<MutexInner>,
 }
 
+pub type MovableMutex = Box<Mutex>;
+
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 
 impl Mutex {
     pub const fn new() -> Mutex {
-        Mutex { inner: ptr::null() }
+        Mutex { inner: Spinlock::new(MutexInner::new()) }
     }
 
     #[inline]
     pub unsafe fn init(&mut self) {
-        let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1);
+        self.inner = Spinlock::new(MutexInner::new());
     }
 
     #[inline]
     pub unsafe fn lock(&self) {
-        let _ = abi::sem_timedwait(self.inner, 0);
+        loop {
+            let mut guard = self.inner.lock();
+            if guard.locked == false {
+                guard.locked = true;
+                return;
+            } else {
+                let prio = abi::get_priority();
+                let id = abi::getpid();
+
+                guard.blocked_task.push(prio, id);
+                abi::block_current_task();
+                drop(guard);
+                abi::yield_now();
+            }
+        }
     }
 
     #[inline]
     pub unsafe fn unlock(&self) {
-        let _ = abi::sem_post(self.inner);
+        let mut guard = self.inner.lock();
+        guard.locked = false;
+        if let Some(tid) = guard.blocked_task.pop() {
+            abi::wakeup_task(tid);
+        }
     }
 
     #[inline]
     pub unsafe fn try_lock(&self) -> bool {
-        let result = abi::sem_trywait(self.inner);
-        result == 0
+        let mut guard = self.inner.lock();
+        if guard.locked == false {
+            guard.locked = true;
+        }
+        guard.locked
     }
 
     #[inline]
-    pub unsafe fn destroy(&self) {
-        let _ = abi::sem_destroy(self.inner);
-    }
+    pub unsafe fn destroy(&self) {}
 }
 
 pub struct ReentrantMutex {
diff --git a/library/std/src/sys/hermit/process.rs b/library/std/src/sys/hermit/process.rs
deleted file mode 100644
index 4702e5c5492..00000000000
--- a/library/std/src/sys/hermit/process.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-use crate::ffi::OsStr;
-use crate::fmt;
-use crate::io;
-use crate::sys::fs::File;
-use crate::sys::pipe::AnonPipe;
-use crate::sys::{unsupported, Void};
-use crate::sys_common::process::CommandEnv;
-
-pub use crate::ffi::OsString as EnvKey;
-
-////////////////////////////////////////////////////////////////////////////////
-// Command
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct Command {
-    env: CommandEnv,
-}
-
-// passed back to std::process with the pipes connected to the child, if any
-// were requested
-pub struct StdioPipes {
-    pub stdin: Option<AnonPipe>,
-    pub stdout: Option<AnonPipe>,
-    pub stderr: Option<AnonPipe>,
-}
-
-pub enum Stdio {
-    Inherit,
-    Null,
-    MakePipe,
-}
-
-impl Command {
-    pub fn new(_program: &OsStr) -> Command {
-        Command { env: Default::default() }
-    }
-
-    pub fn arg(&mut self, _arg: &OsStr) {}
-
-    pub fn env_mut(&mut self) -> &mut CommandEnv {
-        &mut self.env
-    }
-
-    pub fn cwd(&mut self, _dir: &OsStr) {}
-
-    pub fn stdin(&mut self, _stdin: Stdio) {}
-
-    pub fn stdout(&mut self, _stdout: Stdio) {}
-
-    pub fn stderr(&mut self, _stderr: Stdio) {}
-
-    pub fn spawn(
-        &mut self,
-        _default: Stdio,
-        _needs_stdin: bool,
-    ) -> io::Result<(Process, StdioPipes)> {
-        unsupported()
-    }
-}
-
-impl From<AnonPipe> for Stdio {
-    fn from(pipe: AnonPipe) -> Stdio {
-        pipe.diverge()
-    }
-}
-
-impl From<File> for Stdio {
-    fn from(file: File) -> Stdio {
-        file.diverge()
-    }
-}
-
-impl fmt::Debug for Command {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
-    }
-}
-
-pub struct ExitStatus(Void);
-
-impl ExitStatus {
-    pub fn success(&self) -> bool {
-        match self.0 {}
-    }
-
-    pub fn code(&self) -> Option<i32> {
-        match self.0 {}
-    }
-}
-
-impl Clone for ExitStatus {
-    fn clone(&self) -> ExitStatus {
-        match self.0 {}
-    }
-}
-
-impl Copy for ExitStatus {}
-
-impl PartialEq for ExitStatus {
-    fn eq(&self, _other: &ExitStatus) -> bool {
-        match self.0 {}
-    }
-}
-
-impl Eq for ExitStatus {}
-
-impl fmt::Debug for ExitStatus {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
-    }
-}
-
-impl fmt::Display for ExitStatus {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.0 {}
-    }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitCode(bool);
-
-impl ExitCode {
-    pub const SUCCESS: ExitCode = ExitCode(false);
-    pub const FAILURE: ExitCode = ExitCode(true);
-
-    pub fn as_i32(&self) -> i32 {
-        self.0 as i32
-    }
-}
-
-pub struct Process(Void);
-
-impl Process {
-    pub fn id(&self) -> u32 {
-        match self.0 {}
-    }
-
-    pub fn kill(&mut self) -> io::Result<()> {
-        match self.0 {}
-    }
-
-    pub fn wait(&mut self) -> io::Result<ExitStatus> {
-        match self.0 {}
-    }
-
-    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
-        match self.0 {}
-    }
-}
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 7b5fac922d0..b4628b64911 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -89,6 +89,7 @@ cfg_if::cfg_if! {
         #[stable(feature = "rust1", since = "1.0.0")]
         pub use self::ext as windows_ext;
     } else if #[cfg(any(target_os = "cloudabi",
+                        target_os = "hermit",
                         target_arch = "wasm32",
                         all(target_vendor = "fortanix", target_env = "sgx")))] {
         // On CloudABI and wasm right now the shim below doesn't compile, so