From 16d65d04322de4a00327dfe26b4af6bd3e4187c8 Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Tue, 6 Oct 2020 11:39:59 +0200
Subject: [PATCH 01/13] revise Hermit's mutex interface to support the
 behaviour of StaticMutex

rust-lang/rust#77147 simplifies things by splitting this Mutex type
into two types matching the two use cases: StaticMutex and MovableMutex.
To support the behavior of StaticMutex, we move part of the mutex
implementation into libstd.
---
 library/std/src/sys/hermit/mutex.rs | 190 ++++++++++++++++++++++++++--
 1 file changed, 182 insertions(+), 8 deletions(-)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index 3d4813209cbc4..511a5100ac625 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -1,9 +1,161 @@
+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::{AtomicUsize, Ordering, spin_loop_hint};
 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 (https://en.wikipedia.org/wiki/Ticket_lock)
+///   and 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> {
+        SpinlockGuard { dequeue: &self.dequeue, data: &mut *self.data.get() }
+    }
+
+    #[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 handle 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>,
 }
 
 unsafe impl Send for Mutex {}
@@ -11,33 +163,55 @@ 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);
     }
 }
 

From 98fcc3fbc7b2f3420d393b8916746002d501401c Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Tue, 6 Oct 2020 11:42:57 +0200
Subject: [PATCH 02/13] using the latest version of libhermit-rs

---
 Cargo.lock             | 4 ++--
 library/std/Cargo.toml | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index ec4f3091d2da2..493c184313cb1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1328,9 +1328,9 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.15"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
+checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
 dependencies = [
  "compiler_builtins",
  "libc",
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index c08828bc0cde9..98d955efb2899 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 }

From d560b50d87c05ea5a8e6186c05a50ecd828eaaae Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Tue, 6 Oct 2020 12:12:15 +0200
Subject: [PATCH 03/13] revise code to pass the format check

---
 library/std/src/sys/hermit/mutex.rs | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index 511a5100ac625..bd9a9023396b4 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -3,7 +3,7 @@ use crate::collections::VecDeque;
 use crate::ffi::c_void;
 use crate::ops::{Deref, DerefMut, Drop};
 use crate::ptr;
-use crate::sync::atomic::{AtomicUsize, Ordering, spin_loop_hint};
+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
@@ -50,10 +50,7 @@ impl<T> Spinlock<T> {
     #[inline]
     pub unsafe fn lock(&self) -> SpinlockGuard<'_, T> {
         self.obtain_lock();
-        SpinlockGuard {
-            dequeue: &self.dequeue,
-            data: &mut *self.data.get(),
-        }
+        SpinlockGuard { dequeue: &self.dequeue, data: &mut *self.data.get() }
     }
 }
 
@@ -147,10 +144,7 @@ struct MutexInner {
 
 impl MutexInner {
     pub const fn new() -> MutexInner {
-        MutexInner {
-            locked: false,
-            blocked_task: PriorityQueue::new(),
-        }
+        MutexInner { locked: false, blocked_task: PriorityQueue::new() }
     }
 }
 
@@ -163,9 +157,7 @@ unsafe impl Sync for Mutex {}
 
 impl Mutex {
     pub const fn new() -> Mutex {
-        Mutex {
-            inner: Spinlock::new(MutexInner::new()),
-        }
+        Mutex { inner: Spinlock::new(MutexInner::new()) }
     }
 
     #[inline]
@@ -211,8 +203,7 @@ impl Mutex {
     }
 
     #[inline]
-    pub unsafe fn destroy(&self) {
-    }
+    pub unsafe fn destroy(&self) {}
 }
 
 pub struct ReentrantMutex {

From 986c1fc053828a051c9fd888cbf49393f276f4f5 Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Wed, 7 Oct 2020 10:39:22 +0200
Subject: [PATCH 04/13] revise comments and descriptions of the helper
 functions

---
 library/std/src/sys/hermit/mutex.rs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index bd9a9023396b4..1bf142ec683d5 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -13,8 +13,7 @@ use crate::sys::hermit::abi;
 /// 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 (https://en.wikipedia.org/wiki/Ticket_lock)
-///   and completly fair.
+/// - 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> {
@@ -98,7 +97,7 @@ impl PriorityQueue {
         }
     }
 
-    /// Add a task handle by its priority to the queue
+    /// 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;

From d6e955f3bfd0a47240879549dc2fb3284dfe08e4 Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Fri, 9 Oct 2020 06:42:19 +0200
Subject: [PATCH 05/13] fix typos in new method

---
 library/std/src/sys/hermit/mutex.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index 1bf142ec683d5..c3f88ada0f4bc 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -35,7 +35,11 @@ struct SpinlockGuard<'a, T: ?Sized + 'a> {
 
 impl<T> Spinlock<T> {
     pub const fn new(user_data: T) -> Spinlock<T> {
-        SpinlockGuard { dequeue: &self.dequeue, data: &mut *self.data.get() }
+        Spinlock {
+           queue: AtomicUsize::new(0),
+           dequeue: AtomicUsize::new(1),
+	   data: UnsafeCell::new(user_data),
+        }
     }
 
     #[inline]

From 530f5754664699dee29bde6cfa99aaf861499544 Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Fri, 9 Oct 2020 07:26:48 +0200
Subject: [PATCH 06/13] revise code to pass the format check

---
 library/std/src/sys/hermit/mutex.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index c3f88ada0f4bc..e9222f34b89b4 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -36,9 +36,9 @@ struct SpinlockGuard<'a, T: ?Sized + 'a> {
 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),
+            queue: AtomicUsize::new(0),
+            dequeue: AtomicUsize::new(1),
+            data: UnsafeCell::new(user_data),
         }
     }
 

From 8d8a290c691db7a8ee566edbd485a729eb41d4ba Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Fri, 9 Oct 2020 08:25:19 +0200
Subject: [PATCH 07/13] add hermit to the list of omit OS

---
 library/std/src/sys/mod.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 7b5fac922d08a..b4628b649117e 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

From 33fd08b61f57cde81bf01964b2fc4d2dca0e4d3f Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Mon, 12 Oct 2020 06:51:52 +0200
Subject: [PATCH 08/13] remove obsolete function diverge

---
 library/std/src/sys/hermit/fs.rs      |   4 -
 library/std/src/sys/hermit/process.rs | 149 --------------------------
 2 files changed, 153 deletions(-)
 delete mode 100644 library/std/src/sys/hermit/process.rs

diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index 82ccab1462ba8..829d4c943f11b 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/process.rs b/library/std/src/sys/hermit/process.rs
deleted file mode 100644
index 4702e5c549228..0000000000000
--- 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 {}
-    }
-}

From 30c3dadb4da44c950f79e9772b36bbaf2660bb0e Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Mon, 12 Oct 2020 06:53:06 +0200
Subject: [PATCH 09/13] reuse implementation of the system provider
 "unsupported"

---
 library/std/src/sys/hermit/mod.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 8eaf07e52d69a..af05310a8d3ab 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;

From 1741e5b8f581960a6e9cb9f0b8261b5f0c26e92d Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Mon, 12 Oct 2020 06:54:48 +0200
Subject: [PATCH 10/13] define required type 'MovableMutex'

---
 library/std/src/sys/hermit/mutex.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index e9222f34b89b4..e12c2f4e00c50 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -155,6 +155,8 @@ pub struct Mutex {
     inner: Spinlock<MutexInner>,
 }
 
+pub type MovableMutex = Mutex;
+
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 

From bc6b2ac449a0f6d9a8bd87788a0eae9516cb58ce Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Tue, 13 Oct 2020 12:06:48 +0200
Subject: [PATCH 11/13] move __rg_oom to the libos to avoid duplicated symbols

---
 library/alloc/src/alloc.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 4646d4a833525..850451bb29e12 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -372,7 +372,7 @@ pub fn handle_alloc_error(layout: Layout) -> ! {
     unsafe { oom_impl(layout) }
 }
 
-#[cfg(not(any(test, bootstrap)))]
+#[cfg(not(any(target_os="hermit", test, bootstrap)))]
 #[doc(hidden)]
 #[allow(unused_attributes)]
 #[unstable(feature = "alloc_internals", issue = "none")]

From 77d98316f489f4490459b3dcf12d14f45caf1286 Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Tue, 13 Oct 2020 12:22:18 +0200
Subject: [PATCH 12/13] minor changes to pass the format check

---
 library/alloc/src/alloc.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 850451bb29e12..1ea34be71dd3b 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -372,7 +372,7 @@ pub fn handle_alloc_error(layout: Layout) -> ! {
     unsafe { oom_impl(layout) }
 }
 
-#[cfg(not(any(target_os="hermit", test, bootstrap)))]
+#[cfg(not(any(target_os = "hermit", test, bootstrap)))]
 #[doc(hidden)]
 #[allow(unused_attributes)]
 #[unstable(feature = "alloc_internals", issue = "none")]

From bf268fe928eae8d85a868ccdbcc086ea033ae51c Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Tue, 13 Oct 2020 23:25:42 +0200
Subject: [PATCH 13/13] box mutex to get a movable mutex

the commit avoid an alignement issue in Mutex implementation
---
 library/std/src/sys/hermit/mutex.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index e12c2f4e00c50..f988a019cfedb 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -155,7 +155,7 @@ pub struct Mutex {
     inner: Spinlock<MutexInner>,
 }
 
-pub type MovableMutex = Mutex;
+pub type MovableMutex = Box<Mutex>;
 
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}