Fill in section on scopes
This commit is contained in:
parent
a75c1a9c0e
commit
7ead50641b
1 changed files with 38 additions and 1 deletions
39
README.md
39
README.md
|
|
@ -236,7 +236,44 @@ This can be used to implement out variables often seen in native code.
|
||||||
(deserialize int-ptr [::ffi/pointer ::ffi/int])))
|
(deserialize int-ptr [::ffi/pointer ::ffi/int])))
|
||||||
```
|
```
|
||||||
|
|
||||||
### TODO Scopes
|
### Scopes
|
||||||
|
In order to serialize any non-primitive type (such as the previous
|
||||||
|
`[::ffi/pointer ::ffi/int]`), off-heap memory needs to be allocated. When memory
|
||||||
|
is allocated inside the JVM, the memory is associated with a scope. Because none
|
||||||
|
was provided here, the scope is an implicit scope, and the memory will be freed
|
||||||
|
when the serialized object is garbage collected.
|
||||||
|
|
||||||
|
In many cases this is not desirable, because the memory is not freed in a
|
||||||
|
deterministic manner, causing garbage collection pauses to become longer, as
|
||||||
|
well as changing allocation performance. Instead of an implicit scope, there are
|
||||||
|
other kinds of scopes as well. A `stack-scope` is a thread-local scope. Stack
|
||||||
|
scopes are `Closeable`, which means they should usually be used in a `with-open`
|
||||||
|
form. When a `stack-scope` is closed, it immediately frees all the memory
|
||||||
|
associated with it. The previous example, `out-int`, can be implemented with a
|
||||||
|
stack scope.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(defcfn out-int
|
||||||
|
"out_int" [::ffi/pointer] ::ffi/void
|
||||||
|
native-fn
|
||||||
|
[i]
|
||||||
|
(with-open [scope (ffi/stack-scope)]
|
||||||
|
(let [int-ptr (ffi/serialize i [::ffi/pointer ::ffi/int] scope)]
|
||||||
|
(native-fn int-ptr)
|
||||||
|
(ffi/deserialize int-ptr [::ffi/pointer ::ffi/int]))))
|
||||||
|
```
|
||||||
|
|
||||||
|
This will free the pointer immediately upon leaving the function.
|
||||||
|
|
||||||
|
When memory needs to be accessible from multiple threads, there's
|
||||||
|
`shared-scope`. When using a `shared-scope`, it should be accessed inside a
|
||||||
|
`with-acquired` block. When a `shared-scope` is `.close`d, it will release all
|
||||||
|
its associated memory when every `with-acquired` block associated with it is
|
||||||
|
exited.
|
||||||
|
|
||||||
|
In addition, two non-`Closeable` scopes are `global-scope`, which never frees
|
||||||
|
the resources associated with it, and `connected-scope`, which is a scope that
|
||||||
|
frees its resources on garbage collection, like an implicit scope.
|
||||||
|
|
||||||
### TODO Serialization and Deserialization
|
### TODO Serialization and Deserialization
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue