Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rust: low-level programming without the segfaults

Rust: low-level programming without the segfaults

Presented at OSCON 2013.

2e36436c692b2e5fbc172e9fb7563171?s=128

dherman

July 25, 2013
Tweet

More Decks by dherman

Other Decks in Programming

Transcript

  1. None
  2. None
  3. None
  4. The price of performance shouldn’t have to be crashes and

    exploits.
  5. • Safe unions and pointers • Explicit memory layout &

    stack allocation • Optional garbage collection • Mutability control & race-free concurrency Rust: perf + safety
  6. ALGEBRAIC DATA TYPES

  7. enum Color { Red, Green, Blue }

  8. enum Tree { Empty, Leaf(int), Node(~Tree, ~Tree) }

  9. tag tag int tag ~Tree ~Tree Empty Leaf(int) Node(~Tree, ~Tree)

  10. struct Tree { enum TreeTag tag; union { int leaf;

    Pair node; } data; }; enum TreeTag { Empty, Leaf, Node }; struct Pair { Tree *left, *right; };
  11. PATTERN MATCHING

  12. match tree { Empty => 0, Leaf(_) => 1, Node(~ref

    left, ~ref right) => f(left) + f(right) }
  13. enum Option<T> { None, Some(T) }

  14. None
  15. fn double(p: ~int) -> int { *p * 2 }

  16. fn double(p: Option<~int>) -> int { match p { None

    => 0, Some(~n) => n * 2 } }
  17. OWNERSHIP

  18. void *realloc(void *, ...); void free(void *); Owned pointers

  19. void *realloc(void *, ...); void free(void *); template<class K, class

    V> class Hashtable { vector<Bucket<K,V>> buckets; ... }; Owned pointers
  20. memcpy(void *dest, const void *src, uintptr_t count); Temporary pointers

  21. memcpy(void *dest, const void *src, uintptr_t count); template<class K, class

    V> class Hashtable { ... V& find(K& key); }; Temporary pointers
  22. the right to free memory What is ownership?

  23. struct Hashtable<K,V> { buckets: ~[Option<Bucket<K,V>>] } struct Bucket<K,V> { key:

    K, value: V }
  24. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... }
  25. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... } heap allocate
  26. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... } heap allocate stack allocate
  27. { let b = ~[]; let table = Hashtable {

    buckets: b }; ... } heap allocate stack allocate move
  28. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); }
  29. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate
  30. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate move
  31. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate free p move
  32. fn move_from() { let x: ~int = ~22; move_to(x); }

    fn move_to(p: ~int) { printfln!(“%d”, *p); } heap allocate free p move printfln!(“%d”, *x); // error
  33. BORROWING

  34. fn f() { let x: ~int = ~22; borrow(x); printfln!(“%d”,

    *x); } fn borrow(x: &int) { printfln!(“borrowing: %d”, *x); }
  35. fn f() { let x: int = 22; borrow(&x); printfln!(“%d”,

    *x); } fn borrow(x: &int) { printfln!(“borrowing: %d”, *x); }
  36. let w = ~22; { let x = &w; let

    y = &*x; } ‘a ‘b ‘c ‘d Lifetimes
  37. fn find<‘a,K,V>(tbl: &’a Hashtable<K,V>, key: &K) -> Option<&’a V> {

    ... }
  38. fn find<‘a,K,V>(tbl: &’a Hashtable<K,V>, key: &K) -> Option<&’a V> {

    ... } pointer with lifetime ‘a to table
  39. fn find<‘a,K,V>(tbl: &’a Hashtable<K,V>, key: &K) -> Option<&’a V> {

    ... } pointer with lifetime ‘a to table pointer with lifetime ‘a to value
  40. template<class K, class V> class Hashtable<K,V> V& Hashtable<K,V>::find(K& key); unsafe!

  41. CONCURRENCY

  42. Heap

  43. Heap

  44. let (port, chan) = stream(); do spawn { let p

    = ~Point { x: 1.0, y: 2.0 }; chan.send(p); } let p = port.recv(); printfln!(p.to_str());
  45. • Pluggable I/O • Optional scheduler • Data race-free shared

    data structures • Potential for race-free fork-join parallelism • Working on SIMD and GPU libs There’s more
  46. UNSAFE

  47. unsafe { transmute::<&str,&[u8]>(“L”) == &[76, 0] } unsafe fn f(...)

    { ... }
  48. unsafe { transmute::<&str,&[u8]>(“L”) == &[76, 0] } unsafe fn f(...)

    { ... } ☢
  49. 1. Don’t use unsafe code. 2. If you absolutely must

    break Rule 1, • get out of unsafe code ASAP, and • always provide a safe interface at the boundaries. The rules
  50. Low-level programming… without the segfaults.

  51. Thank you.

  52. Image credits Sean Martell http://blog.seanmartell.com Ben Clinch http://www.flickr.com/photos/benclinch/3048906022/ juicyrai http://www.flickr.com/photos/wink/180979062/

    Rama, Wikimedia Commons http://en.wikipedia.org/wiki/File:Sir_Tony_Hoare_IMG_5125.jpg Jared Zimmerman http://www.flickr.com/photos/spoinknet/7932382540/ CCAC North Library http://www.flickr.com/photos/ccacnorthlib/3553821699/ Mike Hayes http://www.flickr.com/photos/rotties/449650275/