| ... | ... | @@ -108,7 +108,7 @@ expect. |
|
|
|
|
|
|
|
|
|
|
|
- Simpler from the programmer's point of view: no yield, no
|
|
|
|
worrying about latency. "write a thread as if the current
|
|
|
|
worrying about latency. "write code as if the current
|
|
|
|
thread is the only one.".
|
|
|
|
|
|
|
|
|
| ... | ... | @@ -146,7 +146,7 @@ expect. |
|
|
|
|
|
|
|
- Hard to implement, no implementations yet.
|
|
|
|
|
|
|
|
### 2. nomenclature for foreign call annoatations.
|
|
|
|
### 2. Syntax for foreign call annoatations.
|
|
|
|
|
|
|
|
|
|
|
|
|
| ... | ... | @@ -157,89 +157,131 @@ expect. |
|
|
|
**2.1.a.** we annotate concurrent calls:
|
|
|
|
|
|
|
|
|
|
|
|
1. concurrent
|
|
|
|
1. mayblock
|
|
|
|
1. mightblock
|
|
|
|
1. blocks
|
|
|
|
1. longrunning
|
|
|
|
|
|
|
|
|
|
|
|
**Rationale** for using the term "block": blocking is the main
|
|
|
|
reason for wanting concurrent calls. Concurrent calls allow
|
|
|
|
the progress guarantee to be retained in the presence of a
|
|
|
|
blocking foreign call. A foreign call that just takes a long
|
|
|
|
time is still making progress.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **a.** concurrent
|
|
|
|
>
|
|
|
|
> **b.** mayblock
|
|
|
|
>
|
|
|
|
> **c.** mightblock
|
|
|
|
>
|
|
|
|
> **d.** blocks
|
|
|
|
>
|
|
|
|
> **e.** longrunning
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **Rationale** for using the term "block": blocking is the main
|
|
|
|
> reason for wanting concurrent calls. Concurrent calls allow
|
|
|
|
> the progress guarantee to be retained in the presence of a
|
|
|
|
> blocking foreign call. A foreign call that just takes a long
|
|
|
|
> time is still making progress.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **Rationale** for not using the term "block": the fact that the
|
|
|
|
> call blocks is immaterial, the property we want to provide is
|
|
|
|
> that it doesn't impede progress of other Haskell threads. A
|
|
|
|
> long-running call is indistinguishable from a blocked call in
|
|
|
|
> terms of the progress of other threads.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
**Rationale** for not using the term "block": the fact that the
|
|
|
|
call blocks is immaterial, the property we want to provide is
|
|
|
|
that it doesn't impede progress of other Haskell threads. A
|
|
|
|
long-running call is indistinguishable from a blocked call in
|
|
|
|
terms of the progress of other threads.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> We often don't know whether a library call will block or not
|
|
|
|
> (it isn't documented), whereas saying a call should run
|
|
|
|
> concurrently with other threads is a choice the programmer can
|
|
|
|
> reasonably make.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
**2.1.b.** we annotate non concurrent calls:
|
|
|
|
|
|
|
|
We often don't know whether a library call will block or not
|
|
|
|
(it isn't documented), whereas saying a call should run
|
|
|
|
concurrently with other threads is a choice the programmer can
|
|
|
|
reasonably make.
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **Rationale** for annotating the non-concurrent calls: this is a
|
|
|
|
> performance issue. It is always correct to make a concurrent
|
|
|
|
> call, but it might be more efficient to make a non-concurrent
|
|
|
|
> call if the call does not block. An implementation might
|
|
|
|
> implement \*all\* calls as concurrent, for simplicity.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
**2.1.b.** we annotate non concurrent calls:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**Rationale** for annotating the non-concurrent calls: this is a
|
|
|
|
performance issue. It is always correct to make a concurrent
|
|
|
|
call, but it might be more efficient to make a non-concurrent
|
|
|
|
call if the call does not block. An implementation might
|
|
|
|
implement \*all\* calls as concurrent, for simplicity.
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> Against: John Meacham says "The FFI is inherently unsafe. We
|
|
|
|
> do not need to coddle the programer who is writing raw FFI
|
|
|
|
> code."
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **a.** nonconcurrent
|
|
|
|
>
|
|
|
|
> **b.** noblock
|
|
|
|
>
|
|
|
|
> **c.** returnsquickly
|
|
|
|
>
|
|
|
|
> **d.** fast
|
|
|
|
>
|
|
|
|
> **e.** quick
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
Against: John Meacham says "The FFI is inherently unsafe. We
|
|
|
|
do not need to coddle the programer who is writing raw FFI
|
|
|
|
code."
|
|
|
|
**2.2.** choices for non-reentrant calls:
|
|
|
|
|
|
|
|
|
|
|
|
1. nonconcurrent
|
|
|
|
1. noblock
|
|
|
|
1. returnsquickly
|
|
|
|
1. fast
|
|
|
|
1. quick
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **a.** nonreentrant
|
|
|
|
>
|
|
|
|
> **b.** nocallback
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
**2.2.** choices for non-reentrant calls:
|
|
|
|
|
|
|
|
|
|
|
|
1. nonreentrant
|
|
|
|
1. nocallback
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> **Rationale** for annotating the non-reentrant calls, as opposed
|
|
|
|
> to the reentrant ones: we want the "safe" option to be the
|
|
|
|
> default (as in the FFI spec).
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
**Rationale** for annotating the non-reentrant calls, as opposed
|
|
|
|
to the reentrant ones: we want the "safe" option to be the
|
|
|
|
default (as in the FFI spec).
|
|
|
|
|
|
|
|
**2.3.** should we annotate foreign calls according to whether they need
|
|
|
|
to access thread-local state (TLS) or not?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In favour: a call that doesn't need access to thread-local state,
|
|
|
|
called from a bound thread, can be executed much more quickly on
|
|
|
|
an implementation that doesn't run the Haskell thread directly on
|
|
|
|
the bound OS thread, because it doesn't need to context switch.
|
|
|
|
**Pros**
|
|
|
|
|
|
|
|
|
|
|
|
- a call that doesn't need access to thread-local state, called from a bound thread, can be executed much more quickly on an implementation that doesn't run the Haskell thread directly on the bound OS thread, because it doesn't need to context switch.
|
|
|
|
|
|
|
|
|
|
|
|
**Cons**
|
|
|
|
|
|
|
|
|
|
|
|
Against: libraries that require TLS, eg. OpenGL, often have many
|
|
|
|
fast TLS-using functions. So implementations that need the no-TLS
|
|
|
|
annotation in order to get good performance, will probably still
|
|
|
|
get poor performance from libraries that need TLS anyway.
|
|
|
|
|
|
|
|
- libraries that require TLS, eg. OpenGL, often have many fast TLS-using functions. So implementations that need the no-TLS annotation in order to get good performance, will probably still get poor performance from libraries that need TLS anyway.
|
|
|
|
|
|
|
|
### 3. Semantics of IORefs
|
|
|
|
|
| ... | ... | |