Verified Commit ca1f1301 authored by Katharina Fey's avatar Katharina Fey 🏴
Browse files

Big slide dump

parent ecd62676
use std::{thread, time::Instant, sync::{Arc, Barrier}};
fn sync(b: Arc<Barrier>, i1: Instant) {
println!("Synchronised: {:?}!", i1.elapsed());
}
fn main() {
let b = Arc::new(Barrier::new(2)); // Number of threads to block
let i1 = Instant::now();
let t1 = { let b = Arc::clone(&b); thread::spawn(move || sync(b, i1.clone())) };
let t2 = { let b = Arc::clone(&b); thread::spawn(move || sync(b, i1.clone())) };
t1.join().and(t2.join()).unwrap()
}
use std::{thread, sync::mpsc::channel};
fn main() {
let (tx, rx) = channel(); // Returns (Sender<T>, Receiver<T>)
let t1 = thread::spawn(move || {
let msg = rx.recv().unwrap();
println!("Received message: {}", msg);
});
let t2 = thread::spawn(move || tx.send("Hi over there".to_owned()));
t1.join().and(t2.join()).unwrap();
}
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [
"cfg-if",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "rayon-example"
version = "0.1.0"
dependencies = [
"rayon",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[package]
name = "rayon-example"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rayon = "1.0"
\ No newline at end of file
use rayon::prelude::*;
fn sum_of_squares(input: &[u64]) -> u64 {
input.par_iter() // <-- just change that!
.map(|&i| i * i)
.sum()
}
fn main() {
let buf: Vec<u64> = (0..).into_iter().take(100_000_000_0).collect();
sum_of_squares(buf.as_slice());
}
fn increment(i: &mut u64) {
*i += 1;
println!("Counter={}", i);
}
fn main() {
let mut counter = 0;
let t1 = std::thread::spawn(|| increment(&mut counter));
let t2 = std::thread::spawn(|| increment(&mut counter));
t1.join().and(t2.join()).unwrap();
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="800"
height="600"
viewBox="0 0 211.66684 158.75005"
version="1.1"
id="svg5"
inkscape:export-filename="/home/Documents/talks/data-concurrency/imgs/concurrency1.png"
inkscape:export-xdpi="200.064"
inkscape:export-ydpi="200.064"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="concurrency.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="false"
width="1365px"
inkscape:zoom="1.4142136"
inkscape:cx="322.44069"
inkscape:cy="350.72496"
inkscape:window-width="1274"
inkscape:window-height="1316"
inkscape:window-x="0"
inkscape:window-y="96"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:snap-to-guides="true"
inkscape:snap-midpoints="false"
inkscape:snap-nodes="true"
inkscape:snap-bbox="false"
inkscape:snap-global="true">
<inkscape:grid
type="xygrid"
id="grid13689" />
</sodipodi:namedview>
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2Mend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true">
<path
transform="scale(-0.6)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:context-stroke;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
id="path17890" />
</marker>
<marker
style="overflow:visible"
id="Arrow2Lend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend"
inkscape:isstock="true">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:context-stroke;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
id="path17884" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g63719"
transform="translate(11.715818,-22.822352)">
<g
id="g2605"
transform="translate(0.98250155,8.5405272)">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.33806;stroke-linecap:square"
id="rect846"
width="47.113678"
height="22.474455"
x="17.723106"
y="31.939463" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="25.357422"
y="47.066051"
id="text2324"><tspan
sodipodi:role="line"
id="tspan2322"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="25.357422"
y="47.066051">Server</tspan></text>
</g>
</g>
<g
id="g53797"
transform="matrix(-1,0,0,1,175.37026,-2.0195649)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="m 51.922842,24.396305 h 35.83278"
id="path17861"
sodipodi:nodetypes="cc" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="76.771751"
y="145.99718"
id="text22694"><tspan
sodipodi:role="line"
id="tspan22692"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie';fill:#ffffff;stroke-width:0.264583"
x="76.771751"
y="145.99718">Concurrency</tspan></text>
<g
id="g2689"
transform="matrix(-1,0,0,1,175.37026,11.037022)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="m 51.922842,24.396305 h 35.83278"
id="path2687"
sodipodi:nodetypes="cc" />
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie';letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
x="125.0984"
y="26.255934"
id="text10969"><tspan
sodipodi:role="line"
id="tspan10967"
style="fill:#ffffff;stroke-width:0.264583"
x="125.0984"
y="26.255934">A</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie';letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
x="124.88676"
y="39.312519"
id="text14933"><tspan
sodipodi:role="line"
id="tspan14931"
style="fill:#ffffff;stroke-width:0.264583"
x="124.88676"
y="39.312519">B</tspan></text>
<path
style="fill:#ffffff;stroke:#666666;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 19.754388,56.882729 H 191.9124"
id="path18296" />
<g
id="g31296">
<g
id="g26688"
transform="translate(0.01739236)">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.00134;stroke-linecap:square"
id="rect22799"
width="69.027306"
height="12.497171"
x="27.856098"
y="65.696159" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="59.723927"
y="75.834106"
id="text22803"><tspan
sodipodi:role="line"
id="tspan22801"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="59.723927"
y="75.834106">A</tspan></text>
</g>
<g
id="g26693"
transform="translate(1.0073034)">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.00134;stroke-linecap:square"
id="rect24401"
width="69.027306"
height="12.497171"
x="114.78339"
y="65.696159" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="146.65121"
y="75.834106"
id="text24405"><tspan
sodipodi:role="line"
id="tspan24403"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="146.65121"
y="75.834106">B</tspan></text>
</g>
<g
id="g24411"
transform="translate(34.390222,58.676203)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path24409"
sodipodi:nodetypes="cc" />
</g>
<g
id="g26679"
transform="translate(-53.526986,58.676203)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path26677"
sodipodi:nodetypes="cc" />
</g>
<g
id="g26683"
transform="translate(122.30742,58.676203)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path26681"
sodipodi:nodetypes="cc" />
</g>
</g>
<g
id="g31328"
transform="translate(0,5.53379)">
<g
id="g28855"
transform="translate(-0.25374757,45.464335)">
<g
id="g28982">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.00134;stroke-linecap:square"
id="rect28849"
width="25.610987"
height="12.497169"
x="27.856098"
y="65.696159" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="38.015766"
y="75.834106"
id="text28853"><tspan
sodipodi:role="line"
id="tspan28851"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="38.015766"
y="75.834106">A</tspan></text>
</g>
</g>
<g
id="g28867"
transform="translate(-9.5683853,104.14056)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path28865"
sodipodi:nodetypes="cc" />
</g>
<g
id="g28871"
transform="translate(-53.526986,104.14056)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path28869"
sodipodi:nodetypes="cc" />
</g>
<g
id="g28875"
transform="translate(122.30742,104.14056)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path28873"
sodipodi:nodetypes="cc" />
</g>
<g
id="g28992"
transform="translate(43.704851,45.464335)">
<g
id="g28990">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.00134;stroke-linecap:square"
id="rect28984"
width="25.610987"
height="12.497169"
x="27.856098"
y="65.696159" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="38.015766"
y="75.834106"
id="text28988"><tspan
sodipodi:role="line"
id="tspan28986"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="38.015766"
y="75.834106">B</tspan></text>
</g>
</g>
<g
id="g30152"
transform="translate(87.663445,45.464335)">
<g
id="g30150">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.00134;stroke-linecap:square"
id="rect30144"
width="25.610987"
height="12.497169"
x="27.856098"
y="65.696159" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="38.015766"
y="75.834106"
id="text30148"><tspan
sodipodi:role="line"
id="tspan30146"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="38.015766"
y="75.834106">A</tspan></text>
</g>
</g>
<g
id="g30156"
transform="translate(78.348816,104.14056)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path30154"
sodipodi:nodetypes="cc" />
</g>
<g
id="g30160"
transform="translate(34.390223,104.14056)">
<path
style="fill:#999999;stroke:#666666;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend);paint-order:normal"
d="M 66.052774,13.278707 H 76.98582"
id="path30158"
sodipodi:nodetypes="cc" />
</g>
<g
id="g30170"
transform="translate(131.62204,45.464335)">
<g
id="g30168">
<rect
style="fill:#666666;stroke:#666666;stroke-width:1.00134;stroke-linecap:square"
id="rect30162"
width="25.610987"
height="12.497169"
x="27.856098"
y="65.696159" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="38.015766"
y="75.834106"
id="text30166"><tspan
sodipodi:role="line"
id="tspan30164"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie Bold';fill:#ffffff;stroke-width:0.264583"
x="38.015766"
y="75.834106">B</tspan></text>
</g>
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="71.490707"
y="95.051964"
id="text30174"><tspan
sodipodi:role="line"
id="tspan30172"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Iosevka Kookie';-inkscape-font-specification:'Iosevka Kookie';fill:#ffffff;stroke-width:0.264583"
x="71.490707"
y="95.051964">Synchronicity</tspan></text>
</g>
</svg>
imgs/concurrency1.png

19.2 KB | W: | H:

imgs/concurrency1.png

52.1 KB | W: | H:

imgs/concurrency1.png
imgs/concurrency1.png
imgs/concurrency1.png
imgs/concurrency1.png
  • 2-up
  • Swipe
  • Onion skin
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->