SlideShare a Scribd company logo
1 of 24
Download to read offline
Rust - Synchronization and Concurrency
Safe synchronization abstractions and their implementation

Corey (Rust) Richardson

February 17, 2014
What is Rust?

Rust is a systems language, aimed at replacing C++, with the
following design goals, in roughly descending order of importance:
Zero-cost abstraction
Easy, safe concurrency and parallelism
Memory safety (no data races)
Type safety (no willy-nilly casting)
Simplicity
Compilation speed
Concurrency model

”Tasks” as unit of computation
No observable shared memory
No race conditions! †
No race conditions?

How can we avoid race conditions?
A type system which enables safe sharing of data
Careful design of concurrency abstractions
Hello World

fn main() {
println("Hello, world!");
}
UnsafeArc

Unsafe data structure. Provides atomic reference counting of a
type. Ensures memory does not leak.
pub struct UnsafeArc<T> {
priv data: *mut ArcData<T>
}
struct ArcData<T> {
count: AtomicUint,
data: T
}
UnsafeArc cont.
fn new_inner<T>(data: T, initial_count: uint) -> *mut ArcData<T>
let data = box ArcData {
count: AtomicUint::new(initial_count),
data: data
}
cast::transmute(data)
}
impl<T: Send> UnsafeArc<T> {
pub fn new(data: T) -> UnsafeArc<T> {
unsafe { UnsafeArc { data: new_inner(data, 1) } }
}
pub fn new2(data: T) -> (UnsafeArc<T>, UnsafeArc<T>) {
unsafe {
let ptr = new_inner(data, 2);
(UnsafeArc { data: ptr }, UnsafeArc { data: ptr })
}
}
UnsafeArc cont.
pub fn get(&self) -> *mut T {
unsafe {
// problems?
assert!((*self.data).count.load(Relaxed) > 0);
return &mut (*self.data).data as *mut T;
}
}
pub fn get_immut(&self) -> *T {
unsafe {
// problems?
assert!((*self.data).count.load(Relaxed) > 0);
return &(*self.data).data as *T;
}
}
pub fn is_owned(&self) -> bool {
unsafe {
// problems?
(*self.data).count.load(Relaxed) == 1
}
}
}
UnsafeArc cloning

impl<T: Send> Clone for UnsafeArc<T> {
fn clone(&self) -> UnsafeArc<T> {
unsafe {
let old_count =
(*self.data).count
.fetch_add(1, Acquire);
//
^~~~~~~ Why?
assert!(old_count >= 1);
return UnsafeArc { data: self.data };
}
}
}
Adding Safety
Arc: wraps UnsafeArc, provides read-only access.
pub struct Arc<T> { priv x: UnsafeArc<T> }
impl<T: Freeze + Send> Arc<T> {
pub fn new(data: T) -> Arc<T> {
Arc { x: UnsafeArc::new(data) }
}
pub fn get<’a>(&’a self) -> &’a T {
unsafe { &*self.x.get_immut() }
}
}
Mutexes?
pub struct Mutex { priv sem: Sem<~[WaitQueue]> }
impl Mutex {
pub fn new() -> Mutex { Mutex::new_with_condvars(1) }
pub fn new_with_condvars(num: uint) -> Mutex {
Mutex { sem: Sem::new_and_signal(1, num) }
}
pub fn lock<U>(&self, blk: || -> U) -> U {
// magic?
(&self.sem).access(blk)
}
pub fn lock_cond<U>(&self,
blk: |c: &Condvar| -> U) -> U {
(&self.sem).access_cond(blk)
}
}
Mutexes!

Mutexes in Rust are implemented on top of semaphores, using 100
No ‘unlock’ operation? Closures!
Wait Queues

Wait queues provide an ordering when waiting on a lock.
// Each waiting task receives on one of these.
type WaitEnd = Port<()>;
type SignalEnd = Chan<()>;
// A doubly-ended queue of waiting tasks.
struct WaitQueue {
head: Port<SignalEnd>,
tail: Chan<SignalEnd>
}
Channels and Ports

Message passing. Provides a way to send ‘Send‘ data to another
task. Very efficient, single-reader, single-writer.
impl <T: Send> Chan<T> {
fn send(&self, data: T) { ... }
fn try_send(&self, data: T) -> bool { ... }
}
impl <T: Send> Port<T> {
fn recv(&self) -> T { ... }
fn try_recv(&self) -> TryRecvResult<T> { ... }
}
Wait Queue Implementation
Given Ports and Chans, how can we express wait queues?
impl WaitQueue {
fn signal(&self) -> bool {
match self.head.try_recv() {
comm::Data(ch) => {
// Send a wakeup signal. If the waiter
// was killed, its port will
// have closed. Keep trying until we
// get a live task.
if ch.try_send(()) {
true
} else {
self.signal()
}
}
_ => false
}
}
Wait Queue Impl Cont.
fn broadcast(&self) -> uint {
let mut count = 0;
loop {
match self.head.try_recv() {
comm::Data(ch) => {
if ch.try_send(()) {
count += 1;
}
}
_ => break
}
}
count
}
Wait Queue Impl End

fn wait_end(&self) -> WaitEnd {
let (wait_end, signal_end) = Chan::new();
assert!(self.tail.try_send(signal_end));
wait_end
}
}
Raw Semaphores
We have a way to express order and waiting, now to build some
actual *synchronization*.
struct Sem<Q>(UnsafeArc<SemInner<Q>>);
struct SemInner<Q> {
lock: LowLevelMutex,
count: int,
waiters:
WaitQueue,
// Can be either unit or another waitqueue.
// Some sems shouldn’t come with
// a condition variable attached, others should.
blocked:
Q
}
Semaphore Implementation
impl<Q: Send> Sem<Q> {
pub fn access<U>(&self, blk: || -> U) -> U {
(|| {
self.acquire();
blk()
}).finally(|| {
self.release();
})
}
unsafe fn with(&self, f: |&mut SemInner<Q>|) {
let Sem(ref arc) = *self;
let state = arc.get();
let _g = (*state).lock.lock();
// unlock????
f(cast::transmute(state));
}
Acquiring a semaphore (P)

pub fn acquire(&self) {
unsafe {
let mut waiter_nobe = None;
self.with(|state| {
state.count -= 1;
if state.count < 0 {
// Create waiter nobe, enqueue ourself,
// outer scope we need to block.
waiter_nobe = Some(state.waiters.wait_e
}
});
// Need to wait outside the exclusive.
if waiter_nobe.is_some() {
let _ = waiter_nobe.unwrap().recv();
}
}
}
Releasing a Semaphore (V)

pub fn release(&self) {
unsafe {
self.with(|state| {
state.count += 1;
if state.count <= 0 {
state.waiters.signal();
}
})
}
}
}
Filling in the last pieces

impl Sem<~[WaitQueue]> {
fn new_and_signal(count: int, num_condvars: uint) -> Se
let mut queues = ~[];
for _ in range(0, num_condvars) { queues.push(WaitQ
Sem::new(count, queues)
}
}
And more?

On top of these primitives, as we have seen in class, every other
synchronization primitive can be constructed. In particular, we also
provide starvation-free Reader-Writer locks, Barriers, and
Copy-on-Write Arcs.
Thank You

Thanks for your time!

More Related Content

What's hot

Ns2: Introduction - Part I
Ns2: Introduction - Part INs2: Introduction - Part I
Ns2: Introduction - Part IAjit Nayak
 
Next Generation Indexes For Big Data Engineering (ODSC East 2018)
Next Generation Indexes For Big Data Engineering (ODSC East 2018)Next Generation Indexes For Big Data Engineering (ODSC East 2018)
Next Generation Indexes For Big Data Engineering (ODSC East 2018)Daniel Lemire
 
Ns2: OTCL - PArt II
Ns2: OTCL - PArt IINs2: OTCL - PArt II
Ns2: OTCL - PArt IIAjit Nayak
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Yandex
 
The Ring programming language version 1.5.3 book - Part 23 of 184
The Ring programming language version 1.5.3 book - Part 23 of 184The Ring programming language version 1.5.3 book - Part 23 of 184
The Ring programming language version 1.5.3 book - Part 23 of 184Mahmoud Samir Fayed
 
Engineering fast indexes
Engineering fast indexesEngineering fast indexes
Engineering fast indexesDaniel Lemire
 
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"OdessaJS Conf
 
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"OdessaJS Conf
 
The Ring programming language version 1.4.1 book - Part 7 of 31
The Ring programming language version 1.4.1 book - Part 7 of 31The Ring programming language version 1.4.1 book - Part 7 of 31
The Ring programming language version 1.4.1 book - Part 7 of 31Mahmoud Samir Fayed
 
Generating and Analyzing Events
Generating and Analyzing EventsGenerating and Analyzing Events
Generating and Analyzing Eventsztellman
 
The Ring programming language version 1.8 book - Part 28 of 202
The Ring programming language version 1.8 book - Part 28 of 202The Ring programming language version 1.8 book - Part 28 of 202
The Ring programming language version 1.8 book - Part 28 of 202Mahmoud Samir Fayed
 
Леонид Шевцов «Clojure в деле»
Леонид Шевцов «Clojure в деле»Леонид Шевцов «Clojure в деле»
Леонид Шевцов «Clojure в деле»DataArt
 
Exploring Parallel Merging In GPU Based Systems Using CUDA C.
Exploring Parallel Merging In GPU Based Systems Using CUDA C.Exploring Parallel Merging In GPU Based Systems Using CUDA C.
Exploring Parallel Merging In GPU Based Systems Using CUDA C.Rakib Hossain
 
The Ring programming language version 1.4.1 book - Part 6 of 31
The Ring programming language version 1.4.1 book - Part 6 of 31The Ring programming language version 1.4.1 book - Part 6 of 31
The Ring programming language version 1.4.1 book - Part 6 of 31Mahmoud Samir Fayed
 
bpftrace - Tracing Summit 2018
bpftrace - Tracing Summit 2018bpftrace - Tracing Summit 2018
bpftrace - Tracing Summit 2018AlastairRobertson9
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrencyjgrahamc
 
PHP Cheat Sheet
PHP Cheat SheetPHP Cheat Sheet
PHP Cheat SheetGlowTouch
 

What's hot (20)

Ns2: Introduction - Part I
Ns2: Introduction - Part INs2: Introduction - Part I
Ns2: Introduction - Part I
 
Next Generation Indexes For Big Data Engineering (ODSC East 2018)
Next Generation Indexes For Big Data Engineering (ODSC East 2018)Next Generation Indexes For Big Data Engineering (ODSC East 2018)
Next Generation Indexes For Big Data Engineering (ODSC East 2018)
 
Ns2: OTCL - PArt II
Ns2: OTCL - PArt IINs2: OTCL - PArt II
Ns2: OTCL - PArt II
 
Operating System Engineering
Operating System EngineeringOperating System Engineering
Operating System Engineering
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
 
The Ring programming language version 1.5.3 book - Part 23 of 184
The Ring programming language version 1.5.3 book - Part 23 of 184The Ring programming language version 1.5.3 book - Part 23 of 184
The Ring programming language version 1.5.3 book - Part 23 of 184
 
Engineering fast indexes
Engineering fast indexesEngineering fast indexes
Engineering fast indexes
 
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
 
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
 
The Ring programming language version 1.4.1 book - Part 7 of 31
The Ring programming language version 1.4.1 book - Part 7 of 31The Ring programming language version 1.4.1 book - Part 7 of 31
The Ring programming language version 1.4.1 book - Part 7 of 31
 
Generating and Analyzing Events
Generating and Analyzing EventsGenerating and Analyzing Events
Generating and Analyzing Events
 
The Ring programming language version 1.8 book - Part 28 of 202
The Ring programming language version 1.8 book - Part 28 of 202The Ring programming language version 1.8 book - Part 28 of 202
The Ring programming language version 1.8 book - Part 28 of 202
 
Леонид Шевцов «Clojure в деле»
Леонид Шевцов «Clojure в деле»Леонид Шевцов «Clojure в деле»
Леонид Шевцов «Clojure в деле»
 
Tracing and awk in ns2
Tracing and awk in ns2Tracing and awk in ns2
Tracing and awk in ns2
 
Exploring Parallel Merging In GPU Based Systems Using CUDA C.
Exploring Parallel Merging In GPU Based Systems Using CUDA C.Exploring Parallel Merging In GPU Based Systems Using CUDA C.
Exploring Parallel Merging In GPU Based Systems Using CUDA C.
 
The Ring programming language version 1.4.1 book - Part 6 of 31
The Ring programming language version 1.4.1 book - Part 6 of 31The Ring programming language version 1.4.1 book - Part 6 of 31
The Ring programming language version 1.4.1 book - Part 6 of 31
 
Concurrency
ConcurrencyConcurrency
Concurrency
 
bpftrace - Tracing Summit 2018
bpftrace - Tracing Summit 2018bpftrace - Tracing Summit 2018
bpftrace - Tracing Summit 2018
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 
PHP Cheat Sheet
PHP Cheat SheetPHP Cheat Sheet
PHP Cheat Sheet
 

Similar to Rust Synchronization Primitives

C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0Yaser Zhian
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3Srikanth
 
C aptitude questions
C aptitude questionsC aptitude questions
C aptitude questionsSrikanth
 
.Net 4.0 Threading and Parallel Programming
.Net 4.0 Threading and Parallel Programming.Net 4.0 Threading and Parallel Programming
.Net 4.0 Threading and Parallel ProgrammingAlex Moore
 
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
rrxv6 Build a Riscv xv6 Kernel in Rust.pdfrrxv6 Build a Riscv xv6 Kernel in Rust.pdf
rrxv6 Build a Riscv xv6 Kernel in Rust.pdfYodalee
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Siouxnikomatsakis
 
Parallel R in snow (english after 2nd slide)
Parallel R in snow (english after 2nd slide)Parallel R in snow (english after 2nd slide)
Parallel R in snow (english after 2nd slide)Cdiscount
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовYandex
 
Sync with async
Sync with  asyncSync with  async
Sync with asyncprabathsl
 
Introduction to Apache Flink
Introduction to Apache FlinkIntroduction to Apache Flink
Introduction to Apache Flinkmxmxm
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
Functional programming in Swift
Functional programming in SwiftFunctional programming in Swift
Functional programming in SwiftJohn Pham
 
Seastar @ NYCC++UG
Seastar @ NYCC++UGSeastar @ NYCC++UG
Seastar @ NYCC++UGAvi Kivity
 
Parallel Computing with R
Parallel Computing with RParallel Computing with R
Parallel Computing with RAbhirup Mallik
 

Similar to Rust Synchronization Primitives (20)

Clojure basics
Clojure basicsClojure basics
Clojure basics
 
Async await
Async awaitAsync await
Async await
 
Rust_Threads.pdf
Rust_Threads.pdfRust_Threads.pdf
Rust_Threads.pdf
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0
 
分散式系統
分散式系統分散式系統
分散式系統
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3
 
C aptitude questions
C aptitude questionsC aptitude questions
C aptitude questions
 
.Net 4.0 Threading and Parallel Programming
.Net 4.0 Threading and Parallel Programming.Net 4.0 Threading and Parallel Programming
.Net 4.0 Threading and Parallel Programming
 
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
rrxv6 Build a Riscv xv6 Kernel in Rust.pdfrrxv6 Build a Riscv xv6 Kernel in Rust.pdf
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Sioux
 
Parallel R in snow (english after 2nd slide)
Parallel R in snow (english after 2nd slide)Parallel R in snow (english after 2nd slide)
Parallel R in snow (english after 2nd slide)
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 
Sync with async
Sync with  asyncSync with  async
Sync with async
 
Introduction to Apache Flink
Introduction to Apache FlinkIntroduction to Apache Flink
Introduction to Apache Flink
 
Rust With async / .await
Rust With async / .awaitRust With async / .await
Rust With async / .await
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
Functional programming in Swift
Functional programming in SwiftFunctional programming in Swift
Functional programming in Swift
 
Seastar @ NYCC++UG
Seastar @ NYCC++UGSeastar @ NYCC++UG
Seastar @ NYCC++UG
 
Os4
Os4Os4
Os4
 
Parallel Computing with R
Parallel Computing with RParallel Computing with R
Parallel Computing with R
 

Recently uploaded

The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 

Recently uploaded (20)

The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 

Rust Synchronization Primitives

  • 1. Rust - Synchronization and Concurrency Safe synchronization abstractions and their implementation Corey (Rust) Richardson February 17, 2014
  • 2. What is Rust? Rust is a systems language, aimed at replacing C++, with the following design goals, in roughly descending order of importance: Zero-cost abstraction Easy, safe concurrency and parallelism Memory safety (no data races) Type safety (no willy-nilly casting) Simplicity Compilation speed
  • 3. Concurrency model ”Tasks” as unit of computation No observable shared memory No race conditions! †
  • 4. No race conditions? How can we avoid race conditions? A type system which enables safe sharing of data Careful design of concurrency abstractions
  • 5. Hello World fn main() { println("Hello, world!"); }
  • 6. UnsafeArc Unsafe data structure. Provides atomic reference counting of a type. Ensures memory does not leak. pub struct UnsafeArc<T> { priv data: *mut ArcData<T> } struct ArcData<T> { count: AtomicUint, data: T }
  • 7. UnsafeArc cont. fn new_inner<T>(data: T, initial_count: uint) -> *mut ArcData<T> let data = box ArcData { count: AtomicUint::new(initial_count), data: data } cast::transmute(data) } impl<T: Send> UnsafeArc<T> { pub fn new(data: T) -> UnsafeArc<T> { unsafe { UnsafeArc { data: new_inner(data, 1) } } } pub fn new2(data: T) -> (UnsafeArc<T>, UnsafeArc<T>) { unsafe { let ptr = new_inner(data, 2); (UnsafeArc { data: ptr }, UnsafeArc { data: ptr }) } }
  • 8. UnsafeArc cont. pub fn get(&self) -> *mut T { unsafe { // problems? assert!((*self.data).count.load(Relaxed) > 0); return &mut (*self.data).data as *mut T; } } pub fn get_immut(&self) -> *T { unsafe { // problems? assert!((*self.data).count.load(Relaxed) > 0); return &(*self.data).data as *T; } } pub fn is_owned(&self) -> bool { unsafe { // problems? (*self.data).count.load(Relaxed) == 1 } } }
  • 9. UnsafeArc cloning impl<T: Send> Clone for UnsafeArc<T> { fn clone(&self) -> UnsafeArc<T> { unsafe { let old_count = (*self.data).count .fetch_add(1, Acquire); // ^~~~~~~ Why? assert!(old_count >= 1); return UnsafeArc { data: self.data }; } } }
  • 10. Adding Safety Arc: wraps UnsafeArc, provides read-only access. pub struct Arc<T> { priv x: UnsafeArc<T> } impl<T: Freeze + Send> Arc<T> { pub fn new(data: T) -> Arc<T> { Arc { x: UnsafeArc::new(data) } } pub fn get<’a>(&’a self) -> &’a T { unsafe { &*self.x.get_immut() } } }
  • 11. Mutexes? pub struct Mutex { priv sem: Sem<~[WaitQueue]> } impl Mutex { pub fn new() -> Mutex { Mutex::new_with_condvars(1) } pub fn new_with_condvars(num: uint) -> Mutex { Mutex { sem: Sem::new_and_signal(1, num) } } pub fn lock<U>(&self, blk: || -> U) -> U { // magic? (&self.sem).access(blk) } pub fn lock_cond<U>(&self, blk: |c: &Condvar| -> U) -> U { (&self.sem).access_cond(blk) } }
  • 12. Mutexes! Mutexes in Rust are implemented on top of semaphores, using 100 No ‘unlock’ operation? Closures!
  • 13. Wait Queues Wait queues provide an ordering when waiting on a lock. // Each waiting task receives on one of these. type WaitEnd = Port<()>; type SignalEnd = Chan<()>; // A doubly-ended queue of waiting tasks. struct WaitQueue { head: Port<SignalEnd>, tail: Chan<SignalEnd> }
  • 14. Channels and Ports Message passing. Provides a way to send ‘Send‘ data to another task. Very efficient, single-reader, single-writer. impl <T: Send> Chan<T> { fn send(&self, data: T) { ... } fn try_send(&self, data: T) -> bool { ... } } impl <T: Send> Port<T> { fn recv(&self) -> T { ... } fn try_recv(&self) -> TryRecvResult<T> { ... } }
  • 15. Wait Queue Implementation Given Ports and Chans, how can we express wait queues? impl WaitQueue { fn signal(&self) -> bool { match self.head.try_recv() { comm::Data(ch) => { // Send a wakeup signal. If the waiter // was killed, its port will // have closed. Keep trying until we // get a live task. if ch.try_send(()) { true } else { self.signal() } } _ => false } }
  • 16. Wait Queue Impl Cont. fn broadcast(&self) -> uint { let mut count = 0; loop { match self.head.try_recv() { comm::Data(ch) => { if ch.try_send(()) { count += 1; } } _ => break } } count }
  • 17. Wait Queue Impl End fn wait_end(&self) -> WaitEnd { let (wait_end, signal_end) = Chan::new(); assert!(self.tail.try_send(signal_end)); wait_end } }
  • 18. Raw Semaphores We have a way to express order and waiting, now to build some actual *synchronization*. struct Sem<Q>(UnsafeArc<SemInner<Q>>); struct SemInner<Q> { lock: LowLevelMutex, count: int, waiters: WaitQueue, // Can be either unit or another waitqueue. // Some sems shouldn’t come with // a condition variable attached, others should. blocked: Q }
  • 19. Semaphore Implementation impl<Q: Send> Sem<Q> { pub fn access<U>(&self, blk: || -> U) -> U { (|| { self.acquire(); blk() }).finally(|| { self.release(); }) } unsafe fn with(&self, f: |&mut SemInner<Q>|) { let Sem(ref arc) = *self; let state = arc.get(); let _g = (*state).lock.lock(); // unlock???? f(cast::transmute(state)); }
  • 20. Acquiring a semaphore (P) pub fn acquire(&self) { unsafe { let mut waiter_nobe = None; self.with(|state| { state.count -= 1; if state.count < 0 { // Create waiter nobe, enqueue ourself, // outer scope we need to block. waiter_nobe = Some(state.waiters.wait_e } }); // Need to wait outside the exclusive. if waiter_nobe.is_some() { let _ = waiter_nobe.unwrap().recv(); } } }
  • 21. Releasing a Semaphore (V) pub fn release(&self) { unsafe { self.with(|state| { state.count += 1; if state.count <= 0 { state.waiters.signal(); } }) } } }
  • 22. Filling in the last pieces impl Sem<~[WaitQueue]> { fn new_and_signal(count: int, num_condvars: uint) -> Se let mut queues = ~[]; for _ in range(0, num_condvars) { queues.push(WaitQ Sem::new(count, queues) } }
  • 23. And more? On top of these primitives, as we have seen in class, every other synchronization primitive can be constructed. In particular, we also provide starvation-free Reader-Writer locks, Barriers, and Copy-on-Write Arcs.
  • 24. Thank You Thanks for your time!