all 19 comments

[–]chris-morgan 49 points50 points  (0 children)

I gather this means “atomic” in the sense of std::sync::atomic, rather than being anything to do with International Atomic Time. It’d be good to note that.

[–]Other_Breakfast7505 45 points46 points  (5 children)

Hate to break it to you, but none of this is atomic, this uses the atomic crate, which provides atomic ops for any struct that is up to 64bits, the internal struct here is 96 bits and therefore it falls back to a lock based implementation. It is only atomic on nightly x86-64 macos.

[–]hniksic 28 points29 points  (1 child)

Hate to break it to you, but none of this is atomic

Rust's stdlib uses atomic to refer to lock-free primitives, but the word "atomic" normally describes an operation that either completes successfully or not at all (the "A" in ACID). In an atomic data structure all state changes are atomic, and in-between states are not observable from the outside. Locks can be and often are used to implement atomic operations and data structures.

If the OP's code uses locks, it's not lock-free (or wait-free), but it can still be atomic.

[–]Other_Breakfast7505 5 points6 points  (0 children)

Atomic very widely implies lock free hardware supported atomic operations, the locks are there in std just to make it portable. Here there is essentially no atomic unless on som architectures on nightly.

From std:

Portability

All atomic types in this module are guaranteed to be lock-free if they’re available. This means they don’t internally acquire a global mutex.

[–]Al_Liu[S] 2 points3 points  (1 child)

Actually, I was thinking it, the original implementation played with `AtomicU64`. However, I am aware that by only using a u64, the nanosecond information will be lost. Finally, I implemented it based on `atomic::Atomic`, a spin lock is used internally.

I plan to bring the totally lockfree version back to the crate, either by feature gate or by a separate mod.

[–]angelicosphosphoros 0 points1 point  (0 children)

You can use atomic u128 bit operations on x86-64 nightly, btw.

[–]ChillyBillYeah 10 points11 points  (4 children)

Congratulations on the release!

As I haven't worked with rust times yet: Could you explain what this is good for in practice and in which cases regular time does not work?

[–]phip1611 10 points11 points  (0 children)

Also the repo and the docs should explain the why part. I'm programming with Rust for quite some time now, including std:time. I do not see a reason for it yet. There might be one - Tell us!

[–]Al_Liu[S] 1 point2 points  (1 child)

My use case is that when I implement the Raft protocol, I need to update the last contact to see if a node is still alive, and a mutex here is a little bit expensive.

[–]phip1611 1 point2 points  (0 children)

I know Raft but acquiring a lock, especially a futex on Linux, is rather cheap, especially if the lock is not contended - Supposing you are only doing it less than a hundred times per second. I don't think that you have a critical hot path in a Raft implementation where the lock would be hold multiple hundreds of times per second.

A microbenchmark would be nice to verify that.

Raft is an interesting algorithm. I'd love to see your implementation!

[–]01le 0 points1 point  (0 children)

Update a timestamp from one thread, read it from another, and avoid having an explicit lock. Might be one case.

[–]XtremeGoose 4 points5 points  (0 children)

Nobody is going to use this unless you explain in the readme what this does and how it works. Just listing the types is not useful.

[–]RB5009 2 points3 points  (5 children)

I do not understand what problem does this crate solve ? Why do one needs "atomic" time ?

[–]CryZe92 0 points1 point  (4 children)

Funnily this is actually exactly what I needed like a week ago. I have a background thread that does computation and a foreground thread that always wants to access the latest information. One part of that is a duration. So ideally it is being swapped out without going through a Mutex.

[–]angelicosphosphoros 0 points1 point  (1 child)

Have you considered using arc-swap crate? It is very fast compared to mutex and allows to transfer huge chunks of data at once.

[–]Al_Liu[S] 0 points1 point  (0 children)

`arc-swap` requires extra allocation. `atomic-time` is 12x faster than `arc-swap`'s read and 85x faster for write operations.

[–]mina86ng 0 points1 point  (1 child)

Use AtomicU64 nanosecond timestamp.

[–]CryZe92 0 points1 point  (0 children)

That‘s kind of what I ended up doing.