-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathweak.h
95 lines (76 loc) · 3.28 KB
/
weak.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**************************************************************************/
/* */
/* 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"
#include "memory.h"
#ifdef __cplusplus
extern "C" {
#endif
extern value caml_ephe_none, caml_ephe_locked;
#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 them off the unreachable keys and releasing the data
if any of the keys are unreachable. */
value live;
/* These are ephemerons 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 */
#ifdef __cplusplus
}
#endif
#endif /* CAML_WEAK_H */