static struct vtree_slot * add_slot(node_t *node, node_t *left, node_t *right, node_t *parent, vtree_pthread_data_t *vtree_data) { vtree_slot_t *old_slot, *slot; vtree_record_t *rec = vtree_data->new_rec; slot = (vtree_slot_t *)malloc(sizeof(vtree_slot_t)); assert(slot != NULL); slot->epoch = INDIRECT_EPOCH; slot->rec = rec; slot->child[0] = left; slot->child[1] = right; slot->parent = parent; assert(rec->count < VTREE_ENTRIES_PER_TASK); rec->nodes[rec->count] = node; rec->slots[rec->count] = slot; rec->count++; do { old_slot = node->slots; slot->slot_next = old_slot; MEMBARSTLD(); } while (!CAS(&(node->slots), old_slot, slot)); return slot; }
/////////////////////////////////////////////////////////////////////////////// // Stack Track - Operation Management /////////////////////////////////////////////////////////////////////////////// void ST_init(st_thread_t *self) { self->is_slow_path = 1; self->n_next_stack = 0; self->n_stacks = 0; ST_HP_reset(self); MEMBARSTLD(); }
/* ============================================================================= * TxShutdown * ============================================================================= */ void TxShutdown (){ printf("CVSTM v3 system shutdown:\n" " Starts=%li Aborts=%li\n", StartTally, AbortTally); pthread_key_delete(global_key_self); Transaction::finishStaticFields(); MEMBARSTLD(); }
void ST_finish(st_thread_t *self) { self->n_stacks = 0; self->n_next_stack = 0; self->n_hp_records = 0; self->stack_counter++; if (self->is_slow_path) { self->is_slow_path = 0; } MEMBARSTLD(); }
void ST_HP_init(volatile st_hp_record_t *p_hp, volatile int64_t **ptr_ptr) { while (1) { p_hp->ptr = *ptr_ptr; MEMBARSTLD(); if (p_hp->ptr == *ptr_ptr) { return; } CPU_RELAX; } }
void ST_split_segment_start(st_thread_t *self) { long saved_capacity_aborts; long new_capacity_aborts; long n_htm_aborts; saved_capacity_aborts = self->p_htm_data->n_xabort_capacity; self->cur_segment_limit = self->segments[self->op_index][self->split_index].n_limit; self->cur_segment_len = 0; n_htm_aborts = 0; self->is_htm_active = 1; while (0 == HTM_start(self->p_htm_data)) { self->is_htm_active = 0; n_htm_aborts++; new_capacity_aborts = self->p_htm_data->n_xabort_capacity - saved_capacity_aborts; if (new_capacity_aborts > 0) { self->segments[self->op_index][self->split_index].saved_n_htm_success = self->segments[self->op_index][self->split_index].n_htm_success; } if (new_capacity_aborts > ST_SEGMENT_MAX_CAPACITY_ABORTS_FOR_DEC) { if (self->segments[self->op_index][self->split_index].n_limit > ST_SEGMENT_MIN_LENGTH) { self->segments[self->op_index][self->split_index].n_limit -= ST_SEGMENT_LEN_DELTA; } saved_capacity_aborts = self->p_htm_data->n_xabort_capacity; self->cur_segment_limit = self->segments[self->op_index][self->split_index].n_limit; } self->cur_segment_len = 0; if (n_htm_aborts > ST_SEGMENT_MAX_HTM_ABORTS) { self->is_slow_path = 1; self->stats.n_slow_path_segments++; MEMBARSTLD(); return; } } }
void ST_split_segment_finish(st_thread_t *self) { long new_success; self->split_counter++; if (unlikely(self->is_slow_path)) { self->stats.n_splits++; self->stats.n_split_length += self->cur_segment_len; self->split_index++; self->is_slow_path = 0; MEMBARSTLD(); return; } HTM_commit(); self->is_htm_active = 0; self->segments[self->op_index][self->split_index].n_htm_success++; self->stats.n_splits++; self->stats.n_split_length += self->cur_segment_len; new_success = self->segments[self->op_index][self->split_index].n_htm_success - self->segments[self->op_index][self->split_index].saved_n_htm_success; if (new_success > ST_SEGMENT_MIN_SUCCESS_FOR_INC) { if (self->segments[self->op_index][self->split_index].n_limit < self->max_segment_len) { self->segments[self->op_index][self->split_index].n_limit += ST_SEGMENT_LEN_DELTA; self->segments[self->op_index][self->split_index].saved_n_htm_success = self->segments[self->op_index][self->split_index].n_htm_success; } } self->split_index++; if (self->split_index > ST_MAX_SEGMENTS) { printf("ERROR: too many segments [%d] > [%d]\n", self->split_index, ST_MAX_SEGMENTS); abort(); } }
void ST_stack_publish(st_thread_t *self) { self->n_stacks++; self->n_next_stack = self->n_stacks; MEMBARSTLD(); }