Fill in section on scopes

This commit is contained in:
Joshua Suskalo 2021-09-25 11:40:16 -05:00
parent a75c1a9c0e
commit 7ead50641b

View file

@ -236,7 +236,44 @@ This can be used to implement out variables often seen in native code.
(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