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

On Deny Capabilities for Safe, Fast Actors

On Deny Capabilities for Safe, Fast Actors

“Deny Capabilities for Safe, Fast Actors (2015)” by Sylvan Clebsch et al. lays out the core novel idea behind the Pony programming language: deny capabilities. Deny capabilities take object capabilities, turn them on their head and then apply them to variable aliases.

In this talk, Sean T. Allen (member of the Pony core team) explains Deny Capabilities and how Pony combines them with an actor-based model – to provide a programming environment that allows for data-race freedom and fearless concurrency.

Sean T Allen

January 08, 2020
Tweet

More Decks by Sean T Allen

Other Decks in Technology

Transcript

  1. On Deny Capabilities
    for Safe, Fast Actors
    1/39

    View Slide

  2. Sean T. Allen
    Member of the Pony core team
    @SeanTAllen
    www.seantallen.com
    2/39

    View Slide

  3. This is a talk about concurrency.
    3/39

    View Slide

  4. This is a talk about going fast.
    4/39

    View Slide

  5. This talk is about Pony and Deny Capabilities.
    5/39

    View Slide

  6. About the paper
    6/39

    View Slide

  7. Actor model
    7/39

    View Slide

  8. Actor model basics
    8/39

    View Slide

  9. Actor model basics
    Actors communicate with other actors via
    messaging
    8/39

    View Slide

  10. Actor model basics
    Actors communicate with other actors via
    messaging
    Actors process messages
    8/39

    View Slide

  11. Actor model basics
    Actors communicate with other actors via
    messaging
    Actors process messages
    Actors "protect resources"
    8/39

    View Slide

  12. Safe
    9/39

    View Slide

  13. Data race freedom
    10/39

    View Slide

  14. Data race
    Two memory accesses attempts where both:
    11/39

    View Slide

  15. Data race
    Two memory accesses attempts where both:
    Target the same location
    11/39

    View Slide

  16. Data race
    Two memory accesses attempts where both:
    Target the same location
    Are performed concurrently by two threads
    11/39

    View Slide

  17. Data race
    Two memory accesses attempts where both:
    Target the same location
    Are performed concurrently by two threads
    Are not reads
    11/39

    View Slide

  18. Data race
    Two memory accesses attempts where both:
    Target the same location
    Are performed concurrently by two threads
    Are not reads
    Are not synchronization operations
    11/39

    View Slide

  19. The actor model can help prevent data races
    12/39

    View Slide

  20. The actor model can help prevent data races
    All variables are "protected" by an actor - no
    global variables
    12/39

    View Slide

  21. The actor model can help prevent data races
    All variables are "protected" by an actor - no
    global variables
    Actors are processed sequentially 1 message a
    time by a single thread
    12/39

    View Slide

  22. The actor model can help prevent data races
    All variables are "protected" by an actor - no
    global variables
    Actors are processed sequentially 1 message a
    time by a single thread
    Actors are "synchronization operations"
    12/39

    View Slide

  23. The actor model can help prevent data races
    All variables are "protected" by an actor - no
    global variables
    Actors are processed sequentially 1 message a
    time by a single thread
    But sending data from one actor to another can cause problems...
    12/39

    View Slide

  24. Fast
    13/39

    View Slide

  25. How to go fast
    14/39

    View Slide

  26. How to go fast
    Avoid coordination
    14/39

    View Slide

  27. How to go fast
    Avoid coordination
    Avoid contention
    14/39

    View Slide

  28. How to go fast
    Avoid coordination
    Avoid contention
    Measure it
    14/39

    View Slide

  29. How actors can help with fast
    15/39

    View Slide

  30. How actors can help with fast
    make coordination explicit
    15/39

    View Slide

  31. How actors can help with fast
    make coordination explicit
    make contention explicit
    15/39

    View Slide

  32. How actors can hurt fast
    16/39

    View Slide

  33. How actors can hurt fast
    naive implementations can be very slow
    16/39

    View Slide

  34. How actors can hurt fast
    naive implementations can be very slow
    message queues are points of contention
    16/39

    View Slide

  35. How actors can hurt fast
    naive implementations can be very slow
    message queues are points of contention
    locks are usually faster than a large memory
    copy
    16/39

    View Slide

  36. Deny capabilities for safe, fast actors
    17/39

    View Slide

  37. Deny capabilities
    doing unsafe fast things safely
    18/39

    View Slide

  38. Deny capabilities
    statically con rm you aren't doing something
    unsafe
    19/39

    View Slide

  39. Alias control
    20/39

    View Slide

  40. What is an alias?
    21/39

    View Slide

  41. What is an alias?
    Aliases are "names" for things in memory
    21/39

    View Slide

  42. What is an alias?
    Aliases are "names" for things in memory
    Aliases allow you to access a thing at a location
    21/39

    View Slide

  43. Aliases in Pony
    22/39

    View Slide

  44. Aliases in Pony
    When you assign a value to a variable or a eld.
    22/39

    View Slide

  45. Aliases in Pony
    When you assign a value to a variable or a eld.
    When you pass a value as an argument to a
    method.
    22/39

    View Slide

  46. Aliases in Pony
    When you assign a value to a variable or a eld.
    When you pass a value as an argument to a
    method.
    When you call a method, an alias of the receiver
    of the call is created. It is accessible as this
    within the method body.
    22/39

    View Slide

  47. Count the aliases
    primitive Say
    fun say(msg: String, out: OutStream) =>
    let x = "We say '" + msg + "'"
    out.print(x)
    23/39

    View Slide

  48. Count the aliases
    fun say(msg: String, out: OutStream) =>
    primitive Say
    let x = "We say '" + msg + "'"
    out.print(x)
    msg and out are aliases
    23/39

    View Slide

  49. Count the aliases
    let x = "We say '" + msg + "'"
    primitive Say
    fun say(msg: String, out: OutStream) =>
    out.print(x)
    x is an alias
    23/39

    View Slide

  50. Count the aliases
    out.print(x)
    primitive Say
    fun say(msg: String, out: OutStream) =>
    let x = "We say '" + msg + "'"
    x is aliased when passed to print
    23/39

    View Slide

  51. Count the aliases
    primitive Say
    fun say(msg: String, out: OutStream) =>
    let x = "We say '" + msg + "'"
    out.print(x)
    23/39

    View Slide

  52. Capabilities
    Annotations on code that can be used to statically
    con rm some property
    24/39

    View Slide

  53. actor Main
    new create(env: Env) =>
    let msg: String val = "Hello World!"
    env.out.print(msg)
    25/39

    View Slide

  54. let msg: String val = "Hello World!"
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    val is a capability
    25/39

    View Slide

  55. let msg: String val = "Hello World!"
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    val is part of the type at compile-time
    25/39

    View Slide

  56. let msg: String val = "Hello World!"
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    val says "the alias msg to the String Hello World is immutable"
    25/39

    View Slide

  57. What can you deny?
    26/39

    View Slide

  58. What can you deny?
    Reading
    26/39

    View Slide

  59. What can you deny?
    Reading
    Mutating
    26/39

    View Slide

  60. What can you deny?
    Reading
    Mutating
    Aliasing
    26/39

    View Slide

  61. What can you deny?
    Reading
    Mutating
    Aliasing
    Sending
    26/39

    View Slide

  62. What can you deny?
    Reading
    Mutating
    Aliasing
    Sending
    Sharing
    26/39

    View Slide

  63. Some capabilities
    27/39

    View Slide

  64. Some capabilities
    ref
    27/39

    View Slide

  65. Some capabilities
    ref
    val
    27/39

    View Slide

  66. Some capabilities
    ref
    val
    iso
    27/39

    View Slide

  67. Some capabilities
    ref
    val
    iso
    tag
    27/39

    View Slide

  68. ref
    28/39

    View Slide

  69. ref
    allows reading
    28/39

    View Slide

  70. ref
    allows reading
    allows mutation
    28/39

    View Slide

  71. ref
    allows reading
    allows mutation
    denies sending
    28/39

    View Slide

  72. ref
    allows reading
    allows mutation
    denies sending
    allows unlimited aliases
    28/39

    View Slide

  73. ref
    allows reading
    allows mutation
    denies sending
    allows unlimited aliases
    denies sharing
    28/39

    View Slide

  74. iso
    29/39

    View Slide

  75. iso
    allows reading
    29/39

    View Slide

  76. iso
    allows reading
    allows mutation
    29/39

    View Slide

  77. iso
    allows reading
    allows mutation
    allows sending
    29/39

    View Slide

  78. iso
    allows reading
    allows mutation
    allows sending
    denies aliasing
    29/39

    View Slide

  79. iso
    allows reading
    allows mutation
    allows sending
    denies aliasing
    denies sharing
    29/39

    View Slide

  80. val
    30/39

    View Slide

  81. val
    allows reading
    30/39

    View Slide

  82. val
    allows reading
    denies mutation
    30/39

    View Slide

  83. val
    allows reading
    denies mutation
    allows sending
    30/39

    View Slide

  84. val
    allows reading
    denies mutation
    allows sending
    allows unlimited aliases
    30/39

    View Slide

  85. val
    allows reading
    denies mutation
    allows sending
    allows unlimited aliases
    allows sharing
    30/39

    View Slide

  86. tag
    31/39

    View Slide

  87. tag
    denies reading
    31/39

    View Slide

  88. tag
    denies reading
    denies mutation
    31/39

    View Slide

  89. tag
    denies reading
    denies mutation
    allows aliasing
    31/39

    View Slide

  90. tag
    denies reading
    denies mutation
    allows aliasing
    allows sharing
    31/39

    View Slide

  91. tag
    denies reading
    denies mutation
    allows aliasing
    allows sharing
    allows sending
    31/39

    View Slide

  92. Readable
    32/39

    View Slide

  93. Readable
    ref
    32/39

    View Slide

  94. Readable
    ref
    iso
    32/39

    View Slide

  95. Readable
    ref
    iso
    val
    32/39

    View Slide

  96. Readable
    ref
    iso
    val
    Mutable
    32/39

    View Slide

  97. Readable
    ref
    iso
    val
    Mutable
    ref
    32/39

    View Slide

  98. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    32/39

    View Slide

  99. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    32/39

    View Slide

  100. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    32/39

    View Slide

  101. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    32/39

    View Slide

  102. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    32/39

    View Slide

  103. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    32/39

    View Slide

  104. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    val
    32/39

    View Slide

  105. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    val
    tag
    32/39

    View Slide

  106. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    val
    tag
    iso
    32/39

    View Slide

  107. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    val
    tag
    iso
    Shareable
    32/39

    View Slide

  108. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    val
    tag
    iso
    Shareable
    val
    32/39

    View Slide

  109. Readable
    ref
    iso
    val
    Mutable
    ref
    iso
    Aliasable
    ref
    val
    tag
    Sendable
    val
    tag
    iso
    Shareable
    val
    tag
    32/39

    View Slide

  110. There's no platonic ideal for deny capabilities.
    33/39

    View Slide

  111. Code (and errors!)
    34/39

    View Slide

  112. actor Main
    new create(env: Env) =>
    let msg: String ref = "Hello World!".clone()
    env.out.print(msg)
    35/39

    View Slide

  113. let msg: String ref = "Hello World!".clone()
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    Hello World String is mutable
    35/39

    View Slide

  114. env.out.print(msg)
    actor Main
    new create(env: Env) =>
    let msg: String ref = "Hello World!".clone()
    send msg to actor out
    35/39

    View Slide

  115. let msg: String ref = "Hello World!".clone()
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    ref isn't sendable
    35/39

    View Slide

  116. env.out.print(msg)
    actor Main
    new create(env: Env) =>
    let msg: String ref = "Hello World!".clone()
    which will result in an error here
    35/39

    View Slide

  117. Error:
    main.pony:4:19: argument not a subtype of parameter
    env.out.print(msg)
    ^
    Info:
    main.pony:4:19: argument type is String ref
    env.out.print(msg)
    ^
    (...):13:12: parameter type is
    (String val | Array[U8 val] val)
    be print(data: ByteSeq)
    ^
    main.pony:3:14: String ref is not a subtype of String val:
    ref is not a subcap of val
    let msg: String ref = "Hello World!".clone()
    ^
    main.pony:3:14: String ref is not a subtype of Array[U8 val] val
    36/39

    View Slide

  118. main.pony:4:19: argument not a subtype of paramete
    env.out.print(msg)
    Error:
    ^
    Info:
    main.pony:4:19: argument type is String ref
    env.out.print(msg)
    ^
    (...):13:12: parameter type is
    (String val | Array[U8 val] val)
    be print(data: ByteSeq)
    ^
    main.pony:3:14: String ref is not a subtype of String val:
    ref is not a subcap of val
    let msg: String ref = "Hello World!".clone()
    ^
    msg isn't the correct type
    36/39

    View Slide

  119. main.pony:4:19: argument type is String ref
    env.out.print(msg)
    Error:
    main.pony:4:19: argument not a subtype of parameter
    env.out.print(msg)
    ^
    Info:
    ^
    (...):13:12: parameter type is
    (String val | Array[U8 val] val)
    be print(data: ByteSeq)
    ^
    main.pony:3:14: String ref is not a subtype of String val:
    ref is not a subcap of val
    let msg: String ref = "Hello World!".clone()
    ^
    msg is String ref
    36/39

    View Slide

  120. (...):13:12: parameter type is
    (String val | Array[U8 val] val)
    be print(data: ByteSeq)
    main.pony:4:19: argument not a subtype of parameter
    env.out.print(msg)
    ^
    Info:
    main.pony:4:19: argument type is String ref
    env.out.print(msg)
    ^
    ^
    main.pony:3:14: String ref is not a subtype of String val:
    ref is not a subcap of val
    let msg: String ref = "Hello World!".clone()
    ^
    main.pony:3:14: String ref is not a subtype of Array[U8 val] val
    l S i f "H ll W ld!" l ()
    print requires String val or Array[U8] val
    36/39

    View Slide

  121. The compiler just statically checked our data
    sharing.
    37/39

    View Slide

  122. The compiler just statically checked our data
    sharing.
    Let's x it
    37/39

    View Slide

  123. actor Main
    new create(env: Env) =>
    let msg: String val = "Hello World!"
    env.out.print(msg)
    38/39

    View Slide

  124. let msg: String val = "Hello World!"
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    Hello World String is immutable
    38/39

    View Slide

  125. env.out.print(msg)
    actor Main
    new create(env: Env) =>
    let msg: String val = "Hello World!"
    send msg to actor out
    38/39

    View Slide

  126. let msg: String val = "Hello World!"
    actor Main
    new create(env: Env) =>
    env.out.print(msg)
    val is sendable
    38/39

    View Slide

  127. env.out.print(msg)
    actor Main
    new create(env: Env) =>
    let msg: String val = "Hello World!"
    no error here
    38/39

    View Slide

  128. Learn more
    https:/
    /www.seantallen.com/talks/deny-
    capabilities/
    39/39

    View Slide