|
112 | 112 | //! println!("live threads: {}", old_thread_count + 1);
|
113 | 113 | //! ```
|
114 | 114 |
|
115 |
| -// ignore-tidy-undocumented-unsafe |
116 |
| - |
117 | 115 | #![stable(feature = "rust1", since = "1.0.0")]
|
118 | 116 | #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
|
119 | 117 | #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
|
@@ -355,6 +353,7 @@ impl AtomicBool {
|
355 | 353 | #[inline]
|
356 | 354 | #[stable(feature = "atomic_access", since = "1.15.0")]
|
357 | 355 | pub fn get_mut(&mut self) -> &mut bool {
|
| 356 | + // SAFETY: the mutable reference guarantees unique ownership |
358 | 357 | unsafe { &mut *(self.v.get() as *mut bool) }
|
359 | 358 | }
|
360 | 359 |
|
@@ -405,6 +404,7 @@ impl AtomicBool {
|
405 | 404 | #[inline]
|
406 | 405 | #[stable(feature = "rust1", since = "1.0.0")]
|
407 | 406 | pub fn load(&self, order: Ordering) -> bool {
|
| 407 | + // SAFETY: data races are prevented by atomic intrinsics |
408 | 408 | unsafe { atomic_load(self.v.get(), order) != 0 }
|
409 | 409 | }
|
410 | 410 |
|
@@ -437,6 +437,7 @@ impl AtomicBool {
|
437 | 437 | #[inline]
|
438 | 438 | #[stable(feature = "rust1", since = "1.0.0")]
|
439 | 439 | pub fn store(&self, val: bool, order: Ordering) {
|
| 440 | + // SAFETY: data races are prevented by atomic intrinsics |
440 | 441 | unsafe {
|
441 | 442 | atomic_store(self.v.get(), val as u8, order);
|
442 | 443 | }
|
@@ -468,6 +469,7 @@ impl AtomicBool {
|
468 | 469 | #[stable(feature = "rust1", since = "1.0.0")]
|
469 | 470 | #[cfg(target_has_atomic = "8")]
|
470 | 471 | pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
| 472 | + // SAFETY: data races are prevented by atomic intrinsics |
471 | 473 | unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
|
472 | 474 | }
|
473 | 475 |
|
@@ -562,6 +564,7 @@ impl AtomicBool {
|
562 | 564 | success: Ordering,
|
563 | 565 | failure: Ordering)
|
564 | 566 | -> Result<bool, bool> {
|
| 567 | + // SAFETY: data races are prevented by atomic intrinsics |
565 | 568 | match unsafe {
|
566 | 569 | atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
|
567 | 570 | } {
|
@@ -618,6 +621,7 @@ impl AtomicBool {
|
618 | 621 | success: Ordering,
|
619 | 622 | failure: Ordering)
|
620 | 623 | -> Result<bool, bool> {
|
| 624 | + // SAFETY: data races are prevented by atomic intrinsics |
621 | 625 | match unsafe {
|
622 | 626 | atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
|
623 | 627 | } {
|
@@ -664,6 +668,7 @@ impl AtomicBool {
|
664 | 668 | #[stable(feature = "rust1", since = "1.0.0")]
|
665 | 669 | #[cfg(target_has_atomic = "8")]
|
666 | 670 | pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
| 671 | + // SAFETY: data races are prevented by atomic intrinsics |
667 | 672 | unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
|
668 | 673 | }
|
669 | 674 |
|
@@ -759,6 +764,7 @@ impl AtomicBool {
|
759 | 764 | #[stable(feature = "rust1", since = "1.0.0")]
|
760 | 765 | #[cfg(target_has_atomic = "8")]
|
761 | 766 | pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
| 767 | + // SAFETY: data races are prevented by atomic intrinsics |
762 | 768 | unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
|
763 | 769 | }
|
764 | 770 |
|
@@ -800,6 +806,7 @@ impl AtomicBool {
|
800 | 806 | #[stable(feature = "rust1", since = "1.0.0")]
|
801 | 807 | #[cfg(target_has_atomic = "8")]
|
802 | 808 | pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
| 809 | + // SAFETY: data races are prevented by atomic intrinsics |
803 | 810 | unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
|
804 | 811 | }
|
805 | 812 | }
|
@@ -839,6 +846,7 @@ impl<T> AtomicPtr<T> {
|
839 | 846 | #[inline]
|
840 | 847 | #[stable(feature = "atomic_access", since = "1.15.0")]
|
841 | 848 | pub fn get_mut(&mut self) -> &mut *mut T {
|
| 849 | + // SAFETY: the mutable reference guarantees unique ownership |
842 | 850 | unsafe { &mut *self.p.get() }
|
843 | 851 | }
|
844 | 852 |
|
@@ -890,6 +898,7 @@ impl<T> AtomicPtr<T> {
|
890 | 898 | #[inline]
|
891 | 899 | #[stable(feature = "rust1", since = "1.0.0")]
|
892 | 900 | pub fn load(&self, order: Ordering) -> *mut T {
|
| 901 | + // SAFETY: data races are prevented by atomic intrinsics |
893 | 902 | unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T }
|
894 | 903 | }
|
895 | 904 |
|
@@ -924,6 +933,7 @@ impl<T> AtomicPtr<T> {
|
924 | 933 | #[inline]
|
925 | 934 | #[stable(feature = "rust1", since = "1.0.0")]
|
926 | 935 | pub fn store(&self, ptr: *mut T, order: Ordering) {
|
| 936 | + // SAFETY: data races are prevented by atomic intrinsics |
927 | 937 | unsafe {
|
928 | 938 | atomic_store(self.p.get() as *mut usize, ptr as usize, order);
|
929 | 939 | }
|
@@ -957,6 +967,7 @@ impl<T> AtomicPtr<T> {
|
957 | 967 | #[stable(feature = "rust1", since = "1.0.0")]
|
958 | 968 | #[cfg(target_has_atomic = "ptr")]
|
959 | 969 | pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
|
| 970 | + // SAFETY: data races are prevented by atomic intrinsics |
960 | 971 | unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
|
961 | 972 | }
|
962 | 973 |
|
@@ -1040,6 +1051,7 @@ impl<T> AtomicPtr<T> {
|
1040 | 1051 | success: Ordering,
|
1041 | 1052 | failure: Ordering)
|
1042 | 1053 | -> Result<*mut T, *mut T> {
|
| 1054 | + // SAFETY: data races are prevented by atomic intrinsics |
1043 | 1055 | unsafe {
|
1044 | 1056 | let res = atomic_compare_exchange(self.p.get() as *mut usize,
|
1045 | 1057 | current as usize,
|
@@ -1100,6 +1112,7 @@ impl<T> AtomicPtr<T> {
|
1100 | 1112 | success: Ordering,
|
1101 | 1113 | failure: Ordering)
|
1102 | 1114 | -> Result<*mut T, *mut T> {
|
| 1115 | + // SAFETY: data races are prevented by atomic intrinsics |
1103 | 1116 | unsafe {
|
1104 | 1117 | let res = atomic_compare_exchange_weak(self.p.get() as *mut usize,
|
1105 | 1118 | current as usize,
|
@@ -1245,6 +1258,7 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
|
1245 | 1258 | #[inline]
|
1246 | 1259 | #[$stable_access]
|
1247 | 1260 | pub fn get_mut(&mut self) -> &mut $int_type {
|
| 1261 | + // SAFETY: the mutable reference guarantees unique ownership |
1248 | 1262 | unsafe { &mut *self.v.get() }
|
1249 | 1263 | }
|
1250 | 1264 | }
|
@@ -1299,6 +1313,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 5);
|
1299 | 1313 | #[inline]
|
1300 | 1314 | #[$stable]
|
1301 | 1315 | pub fn load(&self, order: Ordering) -> $int_type {
|
| 1316 | + // SAFETY: data races are prevented by atomic intrinsics |
1302 | 1317 | unsafe { atomic_load(self.v.get(), order) }
|
1303 | 1318 | }
|
1304 | 1319 | }
|
@@ -1333,6 +1348,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
|
1333 | 1348 | #[inline]
|
1334 | 1349 | #[$stable]
|
1335 | 1350 | pub fn store(&self, val: $int_type, order: Ordering) {
|
| 1351 | + // SAFETY: data races are prevented by atomic intrinsics |
1336 | 1352 | unsafe { atomic_store(self.v.get(), val, order); }
|
1337 | 1353 | }
|
1338 | 1354 | }
|
@@ -1363,6 +1379,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
|
1363 | 1379 | #[$stable]
|
1364 | 1380 | #[$cfg_cas]
|
1365 | 1381 | pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1382 | + // SAFETY: data races are prevented by atomic intrinsics |
1366 | 1383 | unsafe { atomic_swap(self.v.get(), val, order) }
|
1367 | 1384 | }
|
1368 | 1385 | }
|
@@ -1465,6 +1482,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
|
1465 | 1482 | new: $int_type,
|
1466 | 1483 | success: Ordering,
|
1467 | 1484 | failure: Ordering) -> Result<$int_type, $int_type> {
|
| 1485 | + // SAFETY: data races are prevented by atomic intrinsics |
1468 | 1486 | unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
|
1469 | 1487 | }
|
1470 | 1488 | }
|
@@ -1517,6 +1535,7 @@ loop {
|
1517 | 1535 | new: $int_type,
|
1518 | 1536 | success: Ordering,
|
1519 | 1537 | failure: Ordering) -> Result<$int_type, $int_type> {
|
| 1538 | + // SAFETY: data races are prevented by atomic intrinsics |
1520 | 1539 | unsafe {
|
1521 | 1540 | atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
|
1522 | 1541 | }
|
@@ -1551,6 +1570,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10);
|
1551 | 1570 | #[$stable]
|
1552 | 1571 | #[$cfg_cas]
|
1553 | 1572 | pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1573 | + // SAFETY: data races are prevented by atomic intrinsics |
1554 | 1574 | unsafe { atomic_add(self.v.get(), val, order) }
|
1555 | 1575 | }
|
1556 | 1576 | }
|
@@ -1583,6 +1603,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10);
|
1583 | 1603 | #[$stable]
|
1584 | 1604 | #[$cfg_cas]
|
1585 | 1605 | pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1606 | + // SAFETY: data races are prevented by atomic intrinsics |
1586 | 1607 | unsafe { atomic_sub(self.v.get(), val, order) }
|
1587 | 1608 | }
|
1588 | 1609 | }
|
@@ -1618,6 +1639,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
|
1618 | 1639 | #[$stable]
|
1619 | 1640 | #[$cfg_cas]
|
1620 | 1641 | pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1642 | + // SAFETY: data races are prevented by atomic intrinsics |
1621 | 1643 | unsafe { atomic_and(self.v.get(), val, order) }
|
1622 | 1644 | }
|
1623 | 1645 | }
|
@@ -1654,6 +1676,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
|
1654 | 1676 | #[$stable_nand]
|
1655 | 1677 | #[$cfg_cas]
|
1656 | 1678 | pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1679 | + // SAFETY: data races are prevented by atomic intrinsics |
1657 | 1680 | unsafe { atomic_nand(self.v.get(), val, order) }
|
1658 | 1681 | }
|
1659 | 1682 | }
|
@@ -1689,6 +1712,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
|
1689 | 1712 | #[$stable]
|
1690 | 1713 | #[$cfg_cas]
|
1691 | 1714 | pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1715 | + // SAFETY: data races are prevented by atomic intrinsics |
1692 | 1716 | unsafe { atomic_or(self.v.get(), val, order) }
|
1693 | 1717 | }
|
1694 | 1718 | }
|
@@ -1724,6 +1748,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
|
1724 | 1748 | #[$stable]
|
1725 | 1749 | #[$cfg_cas]
|
1726 | 1750 | pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1751 | + // SAFETY: data races are prevented by atomic intrinsics |
1727 | 1752 | unsafe { atomic_xor(self.v.get(), val, order) }
|
1728 | 1753 | }
|
1729 | 1754 | }
|
@@ -1835,6 +1860,7 @@ assert!(max_foo == 42);
|
1835 | 1860 | issue = "48655")]
|
1836 | 1861 | #[$cfg_cas]
|
1837 | 1862 | pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1863 | + // SAFETY: data races are prevented by atomic intrinsics |
1838 | 1864 | unsafe { $max_fn(self.v.get(), val, order) }
|
1839 | 1865 | }
|
1840 | 1866 | }
|
@@ -1887,6 +1913,7 @@ assert_eq!(min_foo, 12);
|
1887 | 1913 | issue = "48655")]
|
1888 | 1914 | #[$cfg_cas]
|
1889 | 1915 | pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
|
| 1916 | + // SAFETY: data races are prevented by atomic intrinsics |
1890 | 1917 | unsafe { $min_fn(self.v.get(), val, order) }
|
1891 | 1918 | }
|
1892 | 1919 | }
|
@@ -2429,7 +2456,9 @@ pub fn fence(order: Ordering) {
|
2429 | 2456 | // to conventionally implement fences at
|
2430 | 2457 | // https://github.com/WebAssembly/tool-conventions/issues/59. We should
|
2431 | 2458 | // follow that discussion and implement a solution when one comes about!
|
| 2459 | + |
2432 | 2460 | #[cfg(not(target_arch = "wasm32"))]
|
| 2461 | + // SAFETY: using an atomic fence is safe |
2433 | 2462 | unsafe {
|
2434 | 2463 | match order {
|
2435 | 2464 | Acquire => intrinsics::atomic_fence_acq(),
|
@@ -2518,6 +2547,7 @@ pub fn fence(order: Ordering) {
|
2518 | 2547 | #[inline]
|
2519 | 2548 | #[stable(feature = "compiler_fences", since = "1.21.0")]
|
2520 | 2549 | pub fn compiler_fence(order: Ordering) {
|
| 2550 | + // SAFETY: doesn't compile to machine code |
2521 | 2551 | unsafe {
|
2522 | 2552 | match order {
|
2523 | 2553 | Acquire => intrinsics::atomic_singlethreadfence_acq(),
|
|
0 commit comments