#lock #locking #shared-data #concurent

nightly spinlocks

Lock primitive based on spinning protecting shared data for concurrent access

1 unstable release

Uses old Rust 2015

0.0.1 Mar 9, 2015

#31 in #shared-data

MIT license

19KB
350 lines

spinlock-rs

A spinlock implementation in rust

documentation

Build

Run cargo build

Usage

The library implements a Reader/Writer lock. When locking a spin lock for shared Read access, you will get a reference to the protected data, and while locking for an exclusive Write access, you will get a mutable reference.

extern crate spinlock;
use spinlock::SpinLock;

fn main() {
	let spin = SpinLock::new(0);

	// Write access
	{
		let mut data = spin.write().unwrap();
		*data += 1;
	}
	// Read access
	{
		let data = spin.read().unwrap();
		println!("{}", *data);
	}
}

Please note that the spinlock doesn't deal itself with reference counting. You might want to use Arc<SpinLock<T>> to share the lock between threads.

Credits

The implementation is derived from the spinlock implementation written by Matt Dillon for DragonFlyBSD


lib.rs:

A reader/writer spin lock implementation. A spin lock is a particular kind of lock which will not put the thread to sleep when it tries to acquire a lock already hold by another thread or codepath. Instead, the thread will spin on the lock, which means it will loop trying to acquire it again and again.

Timeouts

This implementation has a timeout. Spinlock are fast but should only be used to protect short critical sections and a lock holder should only hold the lock for a very short period of time to avoid wasting CPU cycles. If a thread tries to acquire a lock for more than MAX_WAIT nanoseconds, it will panic.

Optimistic

The implementation is Optimistic. The acquire codepath assumes that the lock operation will succeed and doesn't try to minimize the cost of the initial acquire operation. If the access is contested, the implementation then tries to minimize the pressure on the CPU cache until it it can actually acquire the lock. After SPIN_COUNT retries, the acquire path will call thread::yield_now() between each retry to allow for other threads to run and drop the lock.

Favor exclusive access

If a thread is spinning in an contested exclusive access attempt, no new shared access will be granted. This is designed to avoid Reader DOSing the Writers.

Poisonning

If an exclusive holder panics while holding the lock, it might void the coherency rules. Indeed, the protected data might be in a state in which it is not supposed to be. To prevent this, if an exclusive holder panics, the lock is poisonned and no other access to the lock will be granted.

Dependencies

~735KB
~13K SLoC