Skip to content

Instantly share code, notes, and snippets.

@physacco
Created June 18, 2013 02:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save physacco/5802293 to your computer and use it in GitHub Desktop.
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.
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