Created
June 18, 2013 02:44
-
-
Save physacco/5802293 to your computer and use it in GitHub Desktop.
Erlang references are unique indentifiers. They are commonly used to identify timers, rpc calls, etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Erlang references are unique indentifiers. They are commonly used to | |
identify timers, rpc calls, etc. | |
make_ref() -> ref() | |
Returns an almost unique reference. | |
The returned reference will re-occur after approximately 2^82 calls; | |
therefore it is unique enough for practical purposes. | |
A reference is internally stored as three 32-bit unsigned integers, but | |
only 82 (out of 96) bits are used to distinguish them. The three global | |
variables reference0, reference1, and reference2 are used as a counter. | |
The string representation of a reference contains 4 integers. The first | |
is an index of node on which the reference was created, 0 for local node | |
and > 0 for other nodes. The other 3 are exactly the same as its internal | |
representation. | |
(foo@localhost)1> make_ref(). | |
#Ref<0.0.0.135> | |
(foo@localhost)2> rpc:call(bar@localhost, erlang, make_ref,[]). | |
#Ref<6583.0.0.80> | |
/* otp_src_R14B01/erts/emulator/beam/bif.c */ | |
static Uint32 reference0; /* Initialized to 0 in erts_init_bif */ | |
static Uint32 reference1; /* Initialized to 0 in erts_init_bif */ | |
static Uint32 reference2; /* Initialized to 0 in erts_init_bif */ | |
static erts_smp_spinlock_t make_ref_lock; | |
static erts_smp_mtx_t ports_snapshot_mtx; | |
erts_smp_atomic_t erts_dead_ports_ptr; /* To store dying ports during snapshot */ | |
Eterm erts_make_ref_in_buffer(Eterm buffer[REF_THING_SIZE]) | |
{ | |
Eterm* hp = buffer; | |
Uint32 ref0, ref1, ref2; | |
erts_smp_spin_lock(&make_ref_lock); | |
reference0++; | |
if (reference0 >= MAX_REFERENCE) { | |
reference0 = 0; | |
reference1++; | |
if (reference1 == 0) { | |
reference2++; | |
} | |
} | |
ref0 = reference0; | |
ref1 = reference1; | |
ref2 = reference2; | |
erts_smp_spin_unlock(&make_ref_lock); | |
write_ref_thing(hp, ref0, ref1, ref2); | |
return make_internal_ref(hp); | |
} | |
/* used in beam sources */ | |
Eterm erts_make_ref(Process *p) | |
{ | |
Eterm* hp; | |
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p)); | |
hp = HAlloc(p, REF_THING_SIZE); | |
return erts_make_ref_in_buffer(hp); | |
} | |
/* wrapped as a bif. */ | |
BIF_RETTYPE make_ref_0(BIF_ALIST_0) | |
{ | |
return erts_make_ref(BIF_P); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment