static inline void sx_rollback_index(sx *t, int translate) { ssiter i; ss_iterinit(ss_bufiter, &i); ss_iteropen(ss_bufiter, &i, &t->log.buf, sizeof(svlogv)); for (; ss_iterhas(ss_bufiter, &i); ss_iternext(ss_bufiter, &i)) { svlogv *lv = ss_iterof(ss_bufiter, &i); sxv *v = lv->v.v; /* remove from index and replace head with * a first waiter */ if (v->prev) goto unlink; sxindex *i = v->index; if (v->next == NULL) ss_rbremove(&i->i, &v->node); else ss_rbreplace(&i->i, &v->node, &v->next->node); unlink: sx_vunlink(v); /* translate log version from sxv to svv */ if (translate) { sv_init(&lv->v, &sv_vif, v->v, NULL); lv->vgc = v; } } }
sxstate sx_commit(sx *t) { assert(t->s == SXPREPARE); if (t->complete) goto complete; ssiter i; ss_iterinit(ss_bufiter, &i); ss_iteropen(ss_bufiter, &i, &t->log.buf, sizeof(svlogv)); for (; ss_iterhas(ss_bufiter, &i); ss_iternext(ss_bufiter, &i)) { svlogv *lv = ss_iterof(ss_bufiter, &i); sxv *v = lv->v.v; /* mark waiters as aborted */ sx_vabortwaiters(v); /* remove from concurrent index and replace * head with a first waiter */ sxindex *i = v->index; if (v->next == NULL) ss_rbremove(&i->i, &v->node); else ss_rbreplace(&i->i, &v->node, &v->next->node); /* unlink version */ sx_vunlink(v); /* translate log version from sxv to svv */ sv_init(&lv->v, &sv_vif, v->v, NULL); lv->vgc = v; } complete: t->s = SXCOMMIT; sx_end(t); return SXCOMMIT; }
static inline void sx_untrack(sxv *v) { if (v->prev == NULL) { sxindex *i = v->index; if (v->next == NULL) ss_rbremove(&i->i, &v->node); else ss_rbreplace(&i->i, &v->node, &v->next->node); } sx_vunlink(v); }