write_rec_t *writes;
size_t writes_size;
size_t writes_count;
- size_t writes_scan;
+ size_t validate_scan;
txn_state_e state;
};
static txn_state_e txn_validate (txn_t *txn);
-static version_t version_ = 1;
-
static skiplist_t *active_ = NULL;
-__attribute__ ((constructor)) void txn_init (void) {
- active_ = sl_alloc(NULL);
-}
+static version_t version_ = 1;
// Validate the updates for <key>. Validation fails if there is a write-write conflict. That is if after our
// read version another transaction committed a change to an entry we are also trying to change.
static txn_state_e txn_validate (txn_t *txn) {
assert(txn->state != TXN_RUNNING);
- int i;
switch (txn->state) {
case TXN_VALIDATING:
if (txn->wv == UNDETERMINED_VERSION) {
version_t wv = SYNC_ADD(&version_, 1);
- SYNC_CAS(&txn->wv, UNDETERMINED_VERSION, wv);
+ (void)SYNC_CAS(&txn->wv, UNDETERMINED_VERSION, wv);
}
- for (i = 0; i < txn->writes_count; ++i) {
+ for (int i = 0; i < txn->writes_count; ++i) {
txn_state_e s = validate_key(txn, txn->writes[i].key);
if (s == TXN_ABORTED) {
txn->state = TXN_ABORTED;
txn->map = map;
txn->writes = nbd_malloc(sizeof(*txn->writes) * INITIAL_WRITES_SIZE);
txn->writes_size = INITIAL_WRITES_SIZE;
+ if (EXPECT_FALSE(active_ == NULL)) {
+ skiplist_t *a = sl_alloc(NULL);
+ if (SYNC_CAS(&active_, NULL, a) != NULL) {
+ sl_free(a);
+ }
+ }
// acquire the read version for txn. must be careful to avoid a race
do {
map_val_t value = update->value;
TRACE("x1", "txn_map_get: key found returning value %p", value, 0);
- return value;
// collect some garbage
version_t min_active_version = UNDETERMINED_VERSION;
update_t *next_update = NULL;