aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r--erts/emulator/beam/bif.c100
1 files changed, 29 insertions, 71 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 84513c1b0e..5ea441ad81 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -37,6 +37,8 @@
#include "erl_db_util.h"
#include "register.h"
#include "erl_thr_progress.h"
+#define ERTS_PTAB_WANT_BIF_IMPL__
+#include "erl_ptab.h"
static Export* flush_monitor_message_trap = NULL;
static Export* set_cpu_topology_trap = NULL;
@@ -155,7 +157,10 @@ BIF_RETTYPE link_1(BIF_ALIST_1)
}
if (is_internal_port(BIF_ARG_1)) {
- Port *pt = erts_id2port(BIF_ARG_1, BIF_P, ERTS_PROC_LOCK_MAIN);
+ Port *pt = erts_id2port_sflgs(BIF_ARG_1,
+ BIF_P,
+ ERTS_PROC_LOCK_MAIN,
+ ERTS_PORT_SFLGS_INVALID_LOOKUP);
if (!pt) {
goto res_no_proc;
}
@@ -167,7 +172,7 @@ BIF_RETTYPE link_1(BIF_ALIST_1)
/* else: already linked */
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);
- erts_smp_port_unlock(pt);
+ erts_port_release(pt);
BIF_RET(am_true);
}
else if (is_external_port(BIF_ARG_1)
@@ -948,7 +953,7 @@ BIF_RETTYPE unlink_1(BIF_ALIST_1)
#ifdef ERTS_SMP
if (ERTS_PROC_PENDING_EXIT(BIF_P)) {
if (pt)
- erts_smp_port_unlock(pt);
+ erts_port_release(pt);
goto handle_pending_exit;
}
#endif
@@ -959,7 +964,7 @@ BIF_RETTYPE unlink_1(BIF_ALIST_1)
if (pt) {
rl = erts_remove_link(&ERTS_P_LINKS(pt), BIF_P->common.id);
- erts_smp_port_unlock(pt);
+ erts_port_release(pt);
if (rl)
erts_destroy_link(rl);
}
@@ -1341,7 +1346,7 @@ BIF_RETTYPE exit_2(BIF_ALIST_2)
if (is_internal_port(BIF_ARG_1)) {
Port *prt;
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- prt = erts_id2port(BIF_ARG_1, NULL, 0);
+ prt = erts_id2port(BIF_ARG_1);
if (prt) {
erts_do_exit_port(prt, BIF_P->common.id, BIF_ARG_2);
erts_port_release(prt);
@@ -1894,7 +1899,10 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
if (erts_system_profile_flags.runnable_procs && erts_system_profile_flags.exclusive) {
profile_runnable_proc(p, am_inactive);
}
- pt = erts_id2port(to, p, ERTS_PROC_LOCK_MAIN);
+ pt = erts_id2port_sflgs(to,
+ p,
+ ERTS_PROC_LOCK_MAIN,
+ ERTS_PORT_SFLGS_INVALID_LOOKUP);
port_common:
ERTS_SMP_LC_ASSERT(!pt || erts_lc_is_port_locked(pt));
@@ -1908,7 +1916,7 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend) {
profile_runnable_port(pt, am_active);
}
- state = erts_smp_atomic32_read_nob(&pt->state);
+ state = erts_atomic32_read_nob(&pt->state);
/* XXX let port_command handle the busy stuff !!! */
if (state & ERTS_PORT_SFLG_PORT_BUSY) {
if (suspend) {
@@ -3510,75 +3518,25 @@ BIF_RETTYPE garbage_collect_message_area_0(BIF_ALIST_0)
#endif
}
+
/**********************************************************************/
-/* Return a list of active ports */
+/*
+ * The erlang:processes/0 BIF.
+ */
-BIF_RETTYPE ports_0(BIF_ALIST_0)
+BIF_RETTYPE processes_0(BIF_ALIST_0)
{
- Eterm res = NIL;
- Eterm* port_buf = erts_alloc(ERTS_ALC_T_TMP,
- sizeof(Eterm)*erts_max_ports);
- Eterm* pp = port_buf;
- Eterm* dead_ports;
- int alive, dead;
- Uint32 next_ss;
- int i;
-
- /* To get a consistent snapshot...
- * We add alive ports from start of the buffer
- * while dying ports are added from the other end by the killing threads.
- */
-
- erts_smp_mtx_lock(&ports_snapshot_mtx); /* One snapshot at a time */
-
- erts_smp_atomic_set_nob(&erts_dead_ports_ptr,
- (erts_aint_t) (port_buf + erts_max_ports));
-
- next_ss = erts_smp_atomic32_inc_read_relb(&erts_ports_snapshot);
-
- for (i = erts_max_ports-1; i >= 0; i--) {
- Port* prt = &erts_port[i];
- erts_aint32_t state = erts_smp_atomic32_read_acqb(&prt->state);
- if (!(state & ERTS_PORT_SFLGS_DEAD)) {
- erts_smp_port_minor_lock(prt);
- state = erts_smp_atomic32_read_nob(&prt->state);
- if (!(state & ERTS_PORT_SFLGS_DEAD) && prt->snapshot != next_ss) {
- ASSERT(prt->snapshot == next_ss - 1);
- *pp++ = prt->common.id;
- prt->snapshot = next_ss; /* Consumed by this snapshot */
- }
- erts_smp_port_minor_unlock(prt);
- }
- }
-
- dead_ports = (Eterm*)erts_smp_atomic_xchg_nob(&erts_dead_ports_ptr,
- (erts_aint_t) NULL);
- erts_smp_mtx_unlock(&ports_snapshot_mtx);
-
- ASSERT(pp <= dead_ports);
-
- alive = pp - port_buf;
- dead = port_buf + erts_max_ports - dead_ports;
-
- ASSERT((alive+dead) <= erts_max_ports);
-
- if (alive+dead > 0) {
- erts_aint_t i;
- Eterm *hp = HAlloc(BIF_P, (alive+dead)*2);
-
- for (i = 0; i < alive; i++) {
- res = CONS(hp, port_buf[i], res);
- hp += 2;
- }
- for (i = 0; i < dead; i++) {
- res = CONS(hp, dead_ports[i], res);
- hp += 2;
- }
- }
+ return erts_ptab_list(BIF_P, &erts_proc);
+}
- erts_free(ERTS_ALC_T_TMP, port_buf);
+/**********************************************************************/
+/*
+ * The erlang:ports/0 BIF.
+ */
- BIF_RET(res);
+BIF_RETTYPE ports_0(BIF_ALIST_0)
+{
+ return erts_ptab_list(BIF_P, &erts_port);
}
/**********************************************************************/