sxstate sx_commit(sx *x) { if (x->state == SX_COMMIT) return SX_COMMIT; assert(x->state == SX_PREPARE); sxmanager *m = x->manager; ssiter i; ss_iterinit(ss_bufiter, &i); ss_iteropen(ss_bufiter, &i, &x->log->buf, sizeof(svlogv)); uint64_t csn = ++m->csn; for (; ss_iterhas(ss_bufiter, &i); ss_iternext(ss_bufiter, &i)) { svlogv *lv = ss_iterof(ss_bufiter, &i); sxv *v = lv->ptr; if ((int)v->lo == x->log_read) break; /* abort conflict reader */ if (v->prev && !sx_vcommitted(v->prev)) { sxindex *i = v->prev->index; assert(sv_vflags(v->prev->v, i->r) & SVGET); sx_vabort(v->prev); } /* abort waiters */ sx_vabort_all(v->next); /* mark stmt as commited */ sx_vcommit(v, csn); lv->ptr = NULL; /* schedule read stmt for gc */ sxindex *i = v->index; if (sv_vflags(v->v, i->r) & SVGET) { sv_vref(v->v); v->gc = m->gc; m->gc = v; m->count_gc++; } else { sx_untrack(v); sx_vpool_push(&m->pool, v); } } /* rollback latest reads */ sx_rollback_svp(x, &i, 0); sx_promote(x, SX_COMMIT); sx_end(x); return SX_COMMIT; }
sxstate sx_commit(sx *x) { assert(x->state == SXPREPARE); sxmanager *m = x->manager; ssiter i; ss_iterinit(ss_bufiter, &i); ss_iteropen(ss_bufiter, &i, &x->log.buf, sizeof(svlogv)); uint64_t csn = ++m->csn; for (; ss_iterhas(ss_bufiter, &i); ss_iternext(ss_bufiter, &i)) { svlogv *lv = ss_iterof(ss_bufiter, &i); sxv *v = lv->v.v; if ((int)v->lo == x->log_read) break; /* abort conflict reader */ if (v->prev && !sx_vcommitted(v->prev)) { assert(v->prev->v->flags & SVGET); sx_vabort(v->prev); } /* abort waiters */ sx_vabort_all(v->next); /* mark stmt as commited */ sx_vcommit(v, csn); /* translate log version from sxv to svv */ sv_init(&lv->v, &sv_vif, v->v, NULL); /* schedule read stmt for gc */ if (v->v->flags & SVGET) { sv_vref(v->v); v->gc = m->gc; m->gc = v; m->count_gc++; } else { sx_untrack(v); ss_free(m->asxv, v); } } /* rollback latest reads */ sx_rollback_svp(x, &i, 0); sx_promote(x, SXCOMMIT); sx_end(x); return SXCOMMIT; }