static Oc_bpt_node* node_alloc(Oc_wu *wu_p) { Oc_bpt_test_node *tnode_p; Oc_bpt_node *node_p; // simple checking for ref-counts g_refcnt++; if (wu_p->po_id != 0) if (oc_bpt_test_utl_random_number(2) == 0) oc_crt_yield_task(); tnode_p = (struct Oc_bpt_test_node*) wrap_malloc(sizeof(Oc_bpt_test_node)); memset(tnode_p, 0, sizeof(Oc_bpt_test_node)); oc_crt_init_rw_lock(&tnode_p->node.lock); tnode_p->node.data = (char*) wrap_malloc(NODE_SIZE); tnode_p->node.disk_addr = oc_bpt_test_fs_alloc(); tnode_p->magic = MAGIC; // add the node into the virtual-disk vd_node_insert(tnode_p); node_p = &tnode_p->node; // Lock the node oc_utl_trk_crt_lock_write(wu_p, &node_p->lock); return node_p; }
bool oc_bpt_dbg_validate_clones_b( struct Oc_wu *wu_p, int n_clones, Oc_bpt_state *st_array[]) { bool rc; int i; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_VALIDATE_CLONES, wu_p, ""); // lock all the clones for (i=0; i<n_clones; i++) { Oc_bpt_state *s_p = st_array[i]; oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); } rc = oc_bpt_op_validate_clones_b(wu_p, n_clones, st_array); // unlock all the clones for (i=0; i<n_clones; i++) { Oc_bpt_state *s_p = st_array[i]; oc_utl_trk_crt_unlock(wu_p, &s_p->lock); } return rc; }
void oc_bpt_iter_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, void (*iter_f)(struct Oc_wu *, Oc_bpt_node*)) { oc_bpt_trace_wu_lvl(2, OC_EV_BPT_ITER, wu_p, "tid=%Lu", s_p->tid); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); oc_bpt_utl_iter_b(wu_p, s_p, iter_f, s_p->root_node_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
void oc_bpt_dbg_output_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, char *tag_p) { oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); oc_bpt_op_output_dot_b(wu_p, s_p, tag_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
bool oc_bpt_dbg_validate_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p) { bool rc; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_VALIDATE, wu_p, "tid=%Lu", s_p->tid); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); rc = oc_bpt_op_validate_b(wu_p, s_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return rc; }
static Oc_bpt_node* node_get_xl(Oc_wu *wu_p, uint64 addr) { Oc_bpt_node *node_p; while (1) { node_p = node_get(wu_p, addr); oc_utl_trk_crt_lock_write(wu_p, &node_p->lock); if (node_p->disk_addr != addr) { node_release(wu_p, node_p); } else break; } oc_utl_debugassert(addr == node_p->disk_addr); return node_p; }
uint64 oc_bpt_create_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p) { oc_utl_assert(NULL == s_p->root_node_p); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); { s_p->root_node_p = s_p->cfg_p->node_alloc(wu_p); oc_bpt_nd_create_root(wu_p, s_p, s_p->root_node_p); oc_utl_trk_crt_unlock(wu_p, &s_p->root_node_p->lock); } oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return s_p->root_node_p->disk_addr; }
int oc_bpt_remove_range_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p, struct Oc_bpt_key *min_key_p, struct Oc_bpt_key *max_key_p) { int rc; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_REMOVE_RANGE, wu_p, "tid=%Lu [%s]", s_p->tid, oc_bpt_nd_string_of_2key(s_p, min_key_p, max_key_p)); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); rc = oc_bpt_op_remove_range_b(wu_p, s_p, min_key_p, max_key_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return rc; }
void oc_bpt_delete_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p) { oc_bpt_trace_wu_lvl(2, OC_EV_BPT_DELETE, wu_p, "tid=%Lu", s_p->tid); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); /* We need to upgrade the root-lock to a shared-lock * because the delete-code unlocks all the pages after * deleting them. This means that the root cannot remain * unlocked, as usual. */ oc_utl_trk_crt_lock_read(wu_p, &s_p->root_node_p->lock); oc_bpt_utl_delete_subtree_b(wu_p, s_p, s_p->root_node_p); s_p->root_node_p = NULL; oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
uint64 oc_bpt_clone_b( struct Oc_wu *wu_p, Oc_bpt_state *src_p, Oc_bpt_state *trg_p) { // make sure the configurations are equivalent oc_utl_assert(trg_p->cfg_p == src_p->cfg_p); oc_bpt_trace_wu_lvl(2, OC_EV_BPT_CLONE, wu_p, "tid=%Lu -> tid=%Lu", src_p->tid, trg_p->tid); oc_utl_debugassert(src_p->cfg_p->initialized); oc_utl_debugassert(trg_p->cfg_p->initialized); oc_utl_assert(NULL == trg_p->root_node_p); oc_utl_trk_crt_lock_write(wu_p, &src_p->lock); oc_bpt_nd_clone_root(wu_p, src_p, trg_p); oc_utl_trk_crt_unlock(wu_p, &src_p->lock); return trg_p->root_node_p->disk_addr; }
void oc_bpt_cow_root_and_update_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, struct Oc_bpt_data *father_data_p, int size) { // Old disk-addr stored as data in father uint64 prev_addr = *((uint64*)father_data_p); Oc_bpt_node *node_p; int fs_refcnt; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_COW_ROOT_AND_UPDATE, wu_p, "lba of root as appers in father (before update):%llu", prev_addr); oc_utl_assert(NULL != s_p->root_node_p); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); node_p = s_p->cfg_p->node_get_xl(wu_p, s_p->root_node_p->disk_addr); oc_utl_debugassert(node_p == s_p->root_node_p); fs_refcnt = s_p->cfg_p->fs_get_refcount( wu_p, s_p->root_node_p->disk_addr); s_p->cfg_p->node_mark_dirty(wu_p, s_p->root_node_p, (fs_refcnt > 1)); if (s_p->root_node_p->disk_addr != prev_addr) { uint64 new_addr = s_p->root_node_p->disk_addr; memcpy((char*)father_data_p, &new_addr, size); } oc_bpt_trace_wu_lvl(2, OC_EV_BPT_COW_ROOT_AND_UPDATE, wu_p, "lba of root as appers in father (AFTER update):%llu", *((uint64*)father_data_p)); oc_bpt_nd_release(wu_p, s_p, s_p->root_node_p);// Dalit: may not be needed oc_utl_trk_crt_unlock(wu_p, &s_p->lock); // Dalit: may not be needed }
void oc_bpt_dbg_output_clones_b( struct Oc_wu *wu_p, int n_clones, struct Oc_bpt_state *st_array[], char *tag_p) { int i; for (i=0 ; i < n_clones; i++) { struct Oc_bpt_state *s_p = st_array[i]; oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); } oc_bpt_op_output_clones_dot_b(wu_p, n_clones, st_array, tag_p); for (i=0 ; i < n_clones; i++) { struct Oc_bpt_state *s_p = st_array[i]; oc_utl_trk_crt_unlock(wu_p, &s_p->lock); } }