mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-14 23:50:19 +02:00
Merged Whippet into libguile/whippet
This commit is contained in:
commit
db181e67ff
112 changed files with 18115 additions and 0 deletions
81
libguile/whippet/api/gc-finalizer.h
Normal file
81
libguile/whippet/api/gc-finalizer.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef GC_FINALIZER_H_
|
||||
#define GC_FINALIZER_H_
|
||||
|
||||
#include "gc-edge.h"
|
||||
#include "gc-ref.h"
|
||||
#include "gc-visibility.h"
|
||||
|
||||
// A finalizer allows the embedder to be notified when an object becomes
|
||||
// unreachable.
|
||||
//
|
||||
// A finalizer has a priority. When the heap is created, the embedder
|
||||
// should declare how many priorities there are. Lower-numbered
|
||||
// priorities take precedence; if an object has a priority-0 finalizer
|
||||
// outstanding, that will prevent any finalizer at level 1 (or 2, ...)
|
||||
// from firing until no priority-0 finalizer remains.
|
||||
//
|
||||
// Call gc_attach_finalizer to attach a finalizer to an object.
|
||||
//
|
||||
// A finalizer also references an associated GC-managed closure object.
|
||||
// A finalizer's reference to the closure object is strong: if a
|
||||
// finalizer's closure closure references its finalizable object,
|
||||
// directly or indirectly, the finalizer will never fire.
|
||||
//
|
||||
// When an object with a finalizer becomes unreachable, it is added to a
|
||||
// queue. The embedder can call gc_pop_finalizable to get the next
|
||||
// finalizable object and its associated closure. At that point the
|
||||
// embedder can do anything with the object, including keeping it alive.
|
||||
// Ephemeron associations will still be present while the finalizable
|
||||
// object is live. Note however that any objects referenced by the
|
||||
// finalizable object may themselves be already finalized; finalizers
|
||||
// are enqueued for objects when they become unreachable, which can
|
||||
// concern whole subgraphs of objects at once.
|
||||
//
|
||||
// The usual way for an embedder to know when the queue of finalizable
|
||||
// object is non-empty is to call gc_set_finalizer_callback to
|
||||
// provide a function that will be invoked when there are pending
|
||||
// finalizers.
|
||||
//
|
||||
// Arranging to call gc_pop_finalizable and doing something with the
|
||||
// finalizable object and closure is the responsibility of the embedder.
|
||||
// The embedder's finalization action can end up invoking arbitrary
|
||||
// code, so unless the embedder imposes some kind of restriction on what
|
||||
// finalizers can do, generally speaking finalizers should be run in a
|
||||
// dedicated thread instead of recursively from within whatever mutator
|
||||
// thread caused GC. Setting up such a thread is the responsibility of
|
||||
// the mutator. gc_pop_finalizable is thread-safe, allowing multiple
|
||||
// finalization threads if that is appropriate.
|
||||
//
|
||||
// gc_allocate_finalizer returns a finalizer, which is a fresh
|
||||
// GC-managed heap object. The mutator should then directly attach it
|
||||
// to an object using gc_finalizer_attach. When the finalizer is fired,
|
||||
// it becomes available to the mutator via gc_pop_finalizable.
|
||||
|
||||
struct gc_heap;
|
||||
struct gc_mutator;
|
||||
struct gc_finalizer;
|
||||
|
||||
GC_API_ size_t gc_finalizer_size(void);
|
||||
GC_API_ struct gc_finalizer* gc_allocate_finalizer(struct gc_mutator *mut);
|
||||
GC_API_ void gc_finalizer_attach(struct gc_mutator *mut,
|
||||
struct gc_finalizer *finalizer,
|
||||
unsigned priority,
|
||||
struct gc_ref object, struct gc_ref closure);
|
||||
|
||||
GC_API_ struct gc_ref gc_finalizer_object(struct gc_finalizer *finalizer);
|
||||
GC_API_ struct gc_ref gc_finalizer_closure(struct gc_finalizer *finalizer);
|
||||
|
||||
GC_API_ struct gc_finalizer* gc_pop_finalizable(struct gc_mutator *mut);
|
||||
|
||||
typedef void (*gc_finalizer_callback)(struct gc_heap *heap, size_t count);
|
||||
GC_API_ void gc_set_finalizer_callback(struct gc_heap *heap,
|
||||
gc_finalizer_callback callback);
|
||||
|
||||
GC_API_ void gc_trace_finalizer(struct gc_finalizer *finalizer,
|
||||
void (*visit)(struct gc_edge edge,
|
||||
struct gc_heap *heap,
|
||||
void *visit_data),
|
||||
struct gc_heap *heap,
|
||||
void *trace_data);
|
||||
|
||||
#endif // GC_FINALIZER_H_
|
Loading…
Add table
Add a link
Reference in a new issue