diff options
| author | Tomoaki Kawada <kawada@kmckk.co.jp> | 2022-12-01 16:41:16 +0900 |
|---|---|---|
| committer | Tomoaki Kawada <kawada@kmckk.co.jp> | 2022-12-12 14:22:45 +0900 |
| commit | 304c6dcaed94ce573755123a7979dd8f2bde7b02 (patch) | |
| tree | 293cff2cf87b184e4a924d373681ee2b6cf8ede5 | |
| parent | ae7633f434011fe1829b9b235a20d91634479eb5 (diff) | |
| download | rust-304c6dcaed94ce573755123a7979dd8f2bde7b02.tar.gz rust-304c6dcaed94ce573755123a7979dd8f2bde7b02.zip | |
kmc-solid: Synchronize the first update of `ThreadInner::lifecycle` with the second one on detach
The first update (swap RMW operation) must happen-before the second update so that the latter can release `ThreadInner` safely.
| -rw-r--r-- | library/std/src/sys/itron/thread.rs | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/library/std/src/sys/itron/thread.rs b/library/std/src/sys/itron/thread.rs index c2b36680872..68eebef1b20 100644 --- a/library/std/src/sys/itron/thread.rs +++ b/library/std/src/sys/itron/thread.rs @@ -119,7 +119,7 @@ impl Thread { let old_lifecycle = inner .lifecycle - .swap(LIFECYCLE_EXITED_OR_FINISHED_OR_JOIN_FINALIZE, Ordering::Release); + .swap(LIFECYCLE_EXITED_OR_FINISHED_OR_JOIN_FINALIZE, Ordering::AcqRel); match old_lifecycle { LIFECYCLE_DETACHED => { @@ -129,9 +129,9 @@ impl Thread { // In this case, `*p_inner`'s ownership has been moved to // us, and we are responsible for dropping it. The acquire - // ordering is not necessary because the parent thread made - // no memory access needing synchronization since the call - // to `acre_tsk`. + // ordering ensures that the swap operation that wrote + // `LIFECYCLE_DETACHED` happens-before `Box::from_raw( + // p_inner)`. // Safety: See above. let _ = unsafe { Box::from_raw(p_inner) }; @@ -267,15 +267,15 @@ impl Drop for Thread { let inner = unsafe { self.p_inner.as_ref() }; // Detach the thread. - match inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::Acquire) { + match inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::AcqRel) { LIFECYCLE_INIT => { // [INIT → DETACHED] // When the time comes, the child will figure out that no // one will ever join it. // The ownership of `*p_inner` is moved to the child thread. - // However, the release ordering is not necessary because we - // made no memory access needing synchronization since the call - // to `acre_tsk`. + // The release ordering ensures that the above swap operation on + // `lifecycle` happens-before the child thread's + // `Box::from_raw(p_inner)`. } LIFECYCLE_FINISHED => { // [FINISHED → JOINED] |
