/**************************************************************************/ /* */ /* OCaml */ /* */ /* Damien Doligez, projet Para, INRIA Rocquencourt */ /* */ /* Copyright 1997 Institut National de Recherche en Informatique et */ /* en Automatique. */ /* */ /* All rights reserved. This file is distributed under the terms of */ /* the GNU Lesser General Public License version 2.1, with the */ /* special exception on linking described in the file LICENSE. */ /* */ /**************************************************************************/ /* Operations on weak arrays */ #ifndef CAML_WEAK_H #define CAML_WEAK_H #include "mlvalues.h" #ifdef __cplusplus extern "C" { #endif extern value caml_ephe_none, caml_ephe_locked; #ifdef __cplusplus } #endif #ifdef CAML_INTERNALS struct caml_ephe_info { value todo; /* These are ephemerons which need to be marked and swept in the current cycle. If the ephemeron is alive, after marking, they go into the live list after cleaning off the unreachable keys and releasing the data if any of the keys are unreachable. */ value live; /* These are ephemerons which are alive (marked). The keys of these ephemerons may be unmarked if these ephemerons were the target of a blit operation. The data field is never unmarked. */ int must_sweep_ephe; /* At the beginning of [Phase_sweep_ephe] the [live] list is moved to the [todo] list since the ephemerons in the [live] list may contain unmarked keys if the blit operation was performed in earlier phases ([Phase_mark_final] or [Phase_sweep_and_mark_main]). This move is done exactly once per major cycle per domain. This field keeps track of whether this move has been done for the current cycle. */ uintnat cycle; struct { value* todop; uintnat cycle; } cursor; }; /** The first field 0: weak list; second field 1: data; others 2..: keys; A weak pointer is an ephemeron with the data at caml_ephe_none If fields are added, don't forget to update weak.ml, [additional_values], and obj.ml, [Ephemeron.additional_values]. */ #define CAML_EPHE_LINK_OFFSET 0 #define CAML_EPHE_DATA_OFFSET 1 #define CAML_EPHE_FIRST_KEY 2 #define CAML_EPHE_MAX_WOSIZE (Max_wosize - CAML_EPHE_FIRST_KEY) #define Ephe_link(e) (*(Op_val(e) + CAML_EPHE_LINK_OFFSET)) #define Ephe_data(e) (*(Op_val(e) + CAML_EPHE_DATA_OFFSET)) value caml_ephe_await_key(value ephe, uintnat i); Caml_inline value Ephe_key(value ephe, uintnat i) { value v = atomic_load_acquire(Op_atomic_val(ephe) + i); if (v == caml_ephe_locked) return caml_ephe_await_key(ephe, i); else return v; } struct caml_ephe_info* caml_alloc_ephe_info (void); void caml_ephe_clean(value e); #endif /* CAML_INTERNALS */ #endif /* CAML_WEAK_H */