如何实现AtomicU32,一个原子32位整数类型?

时间:2015-10-08 09:40:34

标签: rust atomic

模块std::sync::atomic不包含固定大小的整数原子类型。在我的64位应用程序中,我需要创建一个原子32位整数的向量。有解决方法吗?我可以自己实现像AtomicU32(或AtomicI32)这样的东西吗?

2 个答案:

答案 0 :(得分:3)

std::intrinsics模块包含通用的内部原子函数。这意味着您基本上可以复制粘贴the implementation for AtomicUsize and/or AtomicIsize并将包装类型从usize / isize更改为u32 / i32

但是,这些内在函数是不稳定的,因此您需要使用每晚Rust编译器才能使其工作。如果您不接受,请考虑submitting an RFC将这些类型添加到标准库中。如果使用每晚Rust编译器对你来说没问题,那么包含这些类型的publish a crate可能会很有趣。这样做的好处是可以收集有关这些类型有用的统计数据。 (家属仍然需要使用夜间编译器,因此效果可能会被低估。)

答案 1 :(得分:2)

我认为你不能实现除指针大小整数之外的其他大小。 AtomicBool is actually padded in Rust to pointer size

LLVM states

  

常见的体系结构有一些方法可以表示至少一个指针大小的无锁cmpxchg;这样的操作可用于实现所有其他原子操作,这些操作可以在IR中表示,直到该大小。

因此,你永远不会用较小的整数来节省空间。

另一方面,如果你只是想要很好的访问并且不关心内存,你可以实现包装器:

use std::sync::atomic::{AtomicIsize, Ordering};

struct AtomicI32(AtomicIsize);
impl AtomicI32 {
    fn new(v: i32) -> AtomicI32 {
        AtomicI32(AtomicIsize::new(v as isize))
    }
    fn load(&self, order: Ordering) -> i32 {
        self.0.load(order) as i32
    }
    fn store(&self, val: i32, order: Ordering) {
        self.0.store(val as isize, order)
    }
    fn swap(&self, val: i32, order: Ordering) -> i32 {
        self.0.swap(val as isize, order) as i32
    }
    fn compare_and_swap(&self, current: i32, new: i32, order: Ordering) -> i32 {
        self.0.compare_and_swap(current as isize, new as isize, order) as i32
    }
    fn fetch_add(&self, val: i32, order: Ordering) -> i32 {
        self.0.fetch_add(val as isize, order) as i32
    }
    fn fetch_sub(&self, val: i32, order: Ordering) -> i32 {
        self.0.fetch_sub(val as isize, order) as i32
    }
    fn fetch_and(&self, val: i32, order: Ordering) -> i32 {
        self.0.fetch_and(val as isize, order) as i32
    }
    fn fetch_or(&self, val: i32, order: Ordering) -> i32 {
        self.0.fetch_or(val as isize, order) as i32
    }
    fn fetch_xor(&self, val: i32, order: Ordering) -> i32 {
        self.0.fetch_xor(val as isize, order) as i32
    }
}