diff options
Diffstat (limited to 'erts/emulator/beam/erl_db.c')
-rw-r--r-- | erts/emulator/beam/erl_db.c | 84 |
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; |