summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/erl_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_db.c')
-rw-r--r--erts/emulator/beam/erl_db.c84
1 files changed, 60 insertions, 24 deletions
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 514fd2b74d..8f5e1a9543 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -507,13 +507,13 @@ save_sched_table(Process *c_p, DbTable *tb)
DbTable *first;
ASSERT(esdp);
- erts_atomic_inc_nob(&esdp->ets_tables.count);
+ erts_atomic_inc_nob(&esdp->u.ets_tables.count);
erts_refc_inc(&tb->common.refc, 1);
- first = esdp->ets_tables.clist;
+ first = esdp->u.ets_tables.clist;
if (!first) {
tb->common.all.next = tb->common.all.prev = tb;
- esdp->ets_tables.clist = tb;
+ esdp->u.ets_tables.clist = tb;
}
else {
tb->common.all.prev = first->common.all.prev;
@@ -531,14 +531,14 @@ remove_sched_table(ErtsSchedulerData *esdp, DbTable *tb)
ASSERT(erts_get_ref_numbers_thr_id(ERTS_MAGIC_BIN_REFN(tb->common.btid))
== (Uint32) esdp->no);
- ASSERT(erts_atomic_read_nob(&esdp->ets_tables.count) > 0);
- erts_atomic_dec_nob(&esdp->ets_tables.count);
+ ASSERT(erts_atomic_read_nob(&esdp->u.ets_tables.count) > 0);
+ erts_atomic_dec_nob(&esdp->u.ets_tables.count);
eaydp = ERTS_SCHED_AUX_YIELD_DATA(esdp, ets_all);
if (eaydp->ongoing) {
/* ets:all() op process list from last to first... */
if (eaydp->tab == tb) {
- if (eaydp->tab == esdp->ets_tables.clist)
+ if (eaydp->tab == esdp->u.ets_tables.clist)
eaydp->tab = NULL;
else
eaydp->tab = tb->common.all.prev;
@@ -547,23 +547,23 @@ remove_sched_table(ErtsSchedulerData *esdp, DbTable *tb)
if (tb->common.all.next == tb) {
ASSERT(tb->common.all.prev == tb);
- ASSERT(esdp->ets_tables.clist == tb);
- esdp->ets_tables.clist = NULL;
+ ASSERT(esdp->u.ets_tables.clist == tb);
+ esdp->u.ets_tables.clist = NULL;
}
else {
#ifdef DEBUG
- DbTable *tmp = esdp->ets_tables.clist;
+ DbTable *tmp = esdp->u.ets_tables.clist;
do {
if (tmp == tb) break;
tmp = tmp->common.all.next;
- } while (tmp != esdp->ets_tables.clist);
+ } while (tmp != esdp->u.ets_tables.clist);
ASSERT(tmp == tb);
#endif
tb->common.all.prev->common.all.next = tb->common.all.next;
tb->common.all.next->common.all.prev = tb->common.all.prev;
- if (esdp->ets_tables.clist == tb)
- esdp->ets_tables.clist = tb->common.all.next;
+ if (esdp->u.ets_tables.clist == tb)
+ esdp->u.ets_tables.clist = tb->common.all.next;
}
@@ -2765,8 +2765,44 @@ BIF_RETTYPE ets_lookup_element_3(BIF_ALIST_3)
}
}
-/*
- * BIF to erase a whole table and release all memory it holds
+/*
+** Get an element from a term
+** get_element_4(Tab, Key, Index, Default)
+** return the element or a list of elements if bag or Default if the element is not present
+*/
+BIF_RETTYPE ets_lookup_element_4(BIF_ALIST_4)
+{
+ DbTable* tb;
+ Sint index;
+ int cret;
+ Eterm ret;
+
+ CHECK_TABLES();
+
+ DB_BIF_GET_TABLE(tb, DB_READ, LCK_READ, BIF_ets_lookup_element_4);
+
+ if (is_not_small(BIF_ARG_3) || ((index = signed_val(BIF_ARG_3)) < 1)) {
+ db_unlock(tb, LCK_READ);
+ BIF_ERROR(BIF_P, BADARG);
+ }
+
+ cret = tb->common.meth->db_get_element(BIF_P, tb,
+ BIF_ARG_2, index, &ret);
+ db_unlock(tb, LCK_READ);
+ switch (cret) {
+ case DB_ERROR_NONE:
+ BIF_RET(ret);
+ case DB_ERROR_BADKEY:
+ BIF_RET(BIF_ARG_4);
+ case DB_ERROR_SYSRES:
+ BIF_ERROR(BIF_P, SYSTEM_LIMIT);
+ default:
+ BIF_ERROR(BIF_P, BADARG);
+ }
+}
+
+/*
+ * BIF to erase a whole table and release all memory it holds
*/
BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
{
@@ -3311,7 +3347,7 @@ ets_all_reply(ErtsSchedulerData *esdp, ErtsEtsAllReq **reqpp,
hp = &hfragp->mem[hfragp->used_size];
list = *hp;
hfragp->used_size = hfragp->alloc_size;
- first = esdp->ets_tables.clist;
+ first = esdp->u.ets_tables.clist;
tb = *tablepp;
}
else {
@@ -3319,7 +3355,7 @@ ets_all_reply(ErtsSchedulerData *esdp, ErtsEtsAllReq **reqpp,
ASSERT(!*tablepp);
/* Max heap size needed... */
- sz = erts_atomic_read_nob(&esdp->ets_tables.count);
+ sz = erts_atomic_read_nob(&esdp->u.ets_tables.count);
sz *= ERTS_MAGIC_REF_THING_SIZE + 2;
sz += 3 + ERTS_REF_THING_SIZE;
hfragp = new_message_buffer(sz);
@@ -3327,7 +3363,7 @@ ets_all_reply(ErtsSchedulerData *esdp, ErtsEtsAllReq **reqpp,
hp = &hfragp->mem[0];
ohp = &hfragp->off_heap;
list = NIL;
- first = esdp->ets_tables.clist;
+ first = esdp->u.ets_tables.clist;
tb = first ? first->common.all.prev : NULL;
}
@@ -3413,7 +3449,7 @@ erts_handle_yielded_ets_all_request(ErtsAuxWorkData *awdp)
return 0; /* All work completed! */
if (yc < ERTS_ETS_ALL_TB_YCNT_START &&
- yc > erts_atomic_read_nob(&esdp->ets_tables.count))
+ yc > erts_atomic_read_nob(&esdp->u.ets_tables.count))
return 1; /* Yield! */
eaydp->ongoing = ongoing = eaydp->queue;
@@ -4615,8 +4651,8 @@ erts_ets_sched_spec_data_init(ErtsSchedulerData *esdp)
eaydp->hfrag = NULL;
eaydp->tab = NULL;
eaydp->queue = NULL;
- esdp->ets_tables.clist = NULL;
- erts_atomic_init_nob(&esdp->ets_tables.count, 0);
+ esdp->u.ets_tables.clist = NULL;
+ erts_atomic_init_nob(&esdp->u.ets_tables.count, 0);
}
@@ -5455,7 +5491,7 @@ erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg, int alive_only
for (ix = 0; ix < erts_no_schedulers; ix++) {
ErtsSchedulerData *esdp = ERTS_SCHEDULER_IX(ix);
- DbTable *first = esdp->ets_tables.clist;
+ DbTable *first = esdp->u.ets_tables.clist;
if (first) {
DbTable *tb = first;
do {
@@ -5487,7 +5523,7 @@ erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *),
/* retrieve max number of ets tables */
Uint
-erts_db_get_max_tabs()
+erts_db_get_max_tabs(void)
{
return db_max_tabs;
}
@@ -5499,7 +5535,7 @@ Uint erts_ets_table_count(void)
for (six = 0; six < erts_no_schedulers; six++) {
ErtsSchedulerData *esdp = &erts_aligned_scheduler_data[six].esd;
- tb_count += erts_atomic_read_nob(&esdp->ets_tables.count);
+ tb_count += erts_atomic_read_nob(&esdp->u.ets_tables.count);
}
return tb_count;
}
@@ -5566,7 +5602,7 @@ static void lcnt_update_db_locks_per_sched(void *enable) {
DbTable *head;
esdp = erts_get_scheduler_data();
- head = esdp->ets_tables.clist;
+ head = esdp->u.ets_tables.clist;
if(head) {
DbTable *iterator = head;