forked from lei.chen/myxce
feat(raft-drive-async): LivenessAdmission pool reservation + commit fold (tasks 1.6/1.7)
vtaskmgr gains vtask_class_t (LIVENESS/LIVE_BLOCK/REQ_BLOCK) + a pool-level blocking reservation: REQ_BLOCK fast-rejects -XCE_ERR_NOT_READY past n_vcpus-R; LIVENESS never gated (deadlock-freedom). commit_submit folds its inflight_waits onto the pool via commit_set_pool; production wired in cluster.c phase2 (vtaskmgr_set_liveness_reserved(R) + commit_set_pool). Lock order p->lock->ce->lock->blk_lock. Dormant until 3.1. Commit suites 38/30/22/38 green; lib 282/0, controller 196/0, ASAN clean. Phase 1 done.
This commit is contained in:
parent
0781c6c027
commit
a36234a103
12 changed files with 721 additions and 22 deletions
|
|
@ -191,10 +191,11 @@ static void commit_advance_locked(commit_engine_t* ce)
|
|||
pthread_cond_broadcast(&ce->cond);
|
||||
}
|
||||
|
||||
/* Admission cap for concurrent blocking waits, expressed only relative to
|
||||
* the n_vcpus init argument: keep COMMIT_WAIT_RESERVED vtasks free of
|
||||
* blocking commit waits, floored at 1 so one wait is always admittable
|
||||
* (Req 7.1, 7.2). */
|
||||
/* Admission cap for concurrent blocking waits, LOCAL (no-pool) fallback:
|
||||
* keep COMMIT_WAIT_RESERVED vtasks free of blocking commit waits, floored at 1
|
||||
* so one wait is always admittable (Req 7.1, 7.2). Used only when no vtaskmgr
|
||||
* pool is wired (commit_set_pool); when a pool is wired the pool owns the
|
||||
* single reservation (cap = n_vcpus - VTASK_LIVENESS_RESERVED). */
|
||||
static int wait_cap(const commit_engine_t* ce)
|
||||
{
|
||||
int cap = ce->n_vcpus - COMMIT_WAIT_RESERVED;
|
||||
|
|
@ -202,6 +203,40 @@ static int wait_cap(const commit_engine_t* ce)
|
|||
return (cap < 1) ? 1 : cap;
|
||||
}
|
||||
|
||||
/* raft-drive-async task 1.6: acquire a blocking-commit-wait admission slot.
|
||||
* When a pool is wired, delegate to the pool's single LivenessAdmission
|
||||
* reservation (the pool owns the cap); otherwise apply the local cap. Returns
|
||||
* 0 (admitted) or -XCE_ERR_NOT_READY (cap exhausted — fast reject, never
|
||||
* blocks). Caller holds ce->lock. inflight_waits is maintained in BOTH modes
|
||||
* as the observable in-flight commit-wait count. */
|
||||
static int wait_admit_locked(commit_engine_t* ce)
|
||||
{
|
||||
if (ce->pool != NULL) {
|
||||
int rc = vtaskmgr_blocking_acquire(ce->pool);
|
||||
if (rc != 0) {
|
||||
return rc; /* -E_XCE_NOT_READY == -XCE_ERR_NOT_READY */
|
||||
}
|
||||
ce->inflight_waits++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Local fallback: cap = max(1, n_vcpus - COMMIT_WAIT_RESERVED). */
|
||||
if (ce->inflight_waits >= wait_cap(ce)) {
|
||||
return -XCE_ERR_NOT_READY;
|
||||
}
|
||||
ce->inflight_waits++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Release a blocking-commit-wait admission slot. Caller holds ce->lock. */
|
||||
static void wait_release_locked(commit_engine_t* ce)
|
||||
{
|
||||
ce->inflight_waits--;
|
||||
if (ce->pool != NULL) {
|
||||
vtaskmgr_blocking_release(ce->pool);
|
||||
}
|
||||
}
|
||||
|
||||
/* WAIT completion predicate (Req 1.1): own entry committed AND the
|
||||
* own-term gate (when set) reached. Caller holds ce->lock. */
|
||||
static int wait_done_locked(const commit_engine_t* ce, uint64_t lsn)
|
||||
|
|
@ -270,6 +305,7 @@ int commit_engine_init(commit_engine_t* ce, persist_t* p, int n_peers, int n_vcp
|
|||
ce->p = p;
|
||||
ce->n_peers = n_peers;
|
||||
ce->n_vcpus = n_vcpus;
|
||||
ce->pool = NULL; /* local cap until commit_set_pool wires the pool */
|
||||
ce->inflight_waits = 0;
|
||||
ce->writable_lsn = 0; /* no own-term gate until set by promotion */
|
||||
ce->raft_commit_index = 0; /* advisory record only; does not gate commit (optA) */
|
||||
|
|
@ -283,6 +319,20 @@ int commit_engine_init(commit_engine_t* ce, persist_t* p, int n_peers, int n_vcp
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* raft-drive-async task 1.6: fold commit-wait admission onto the vtaskmgr
|
||||
* pool's single LivenessAdmission reservation. Set-once at wiring time; safe
|
||||
* to set NULL to restore the local fallback. The pool must outlive the engine
|
||||
* (controller lifecycle guarantees this — vtaskmgr_fini after commit_engine_fini). */
|
||||
void commit_set_pool(commit_engine_t* ce, vtaskmgr_t* pool)
|
||||
{
|
||||
if (ce == NULL) {
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&ce->lock);
|
||||
ce->pool = pool;
|
||||
pthread_mutex_unlock(&ce->lock);
|
||||
}
|
||||
|
||||
void commit_engine_fini(commit_engine_t* ce)
|
||||
{
|
||||
if (ce == NULL) {
|
||||
|
|
@ -311,7 +361,7 @@ int commit_submit(commit_engine_t* ce, uint64_t lsn, commit_mode_t mode,
|
|||
struct timespec dl;
|
||||
uint64_t cur, gate;
|
||||
int rc = 0;
|
||||
int cap, wrc;
|
||||
int wrc, arc;
|
||||
|
||||
if (ce == NULL || ce->p == NULL || lsn == 0) {
|
||||
return -EINVAL;
|
||||
|
|
@ -333,19 +383,19 @@ int commit_submit(commit_engine_t* ce, uint64_t lsn, commit_mode_t mode,
|
|||
|
||||
/* Admission check: cap exhaustion is the ONLY -XCE_ERR_NOT_READY
|
||||
* cause (Req 7.1, 7.2; CORRECTED contract). Retriable fast-reject —
|
||||
* never blocks. */
|
||||
cap = wait_cap(ce);
|
||||
if (ce->inflight_waits >= cap) {
|
||||
* never blocks. When a vtaskmgr pool is wired (raft-drive-async task 1.6)
|
||||
* the cap is the pool's single LivenessAdmission reservation; otherwise
|
||||
* the local COMMIT_WAIT_RESERVED cap. */
|
||||
arc = wait_admit_locked(ce);
|
||||
if (arc != 0) {
|
||||
pthread_mutex_unlock(&ce->lock);
|
||||
WARN("commit: WAIT rejected, admission cap exhausted "
|
||||
"(cap=%d n_vcpus=%d lsn=%lu)",
|
||||
cap, ce->n_vcpus, lsn);
|
||||
return -XCE_ERR_NOT_READY;
|
||||
"(pool=%s n_vcpus=%d lsn=%lu)",
|
||||
ce->pool ? "pool" : "local", ce->n_vcpus, lsn);
|
||||
return arc;
|
||||
}
|
||||
|
||||
ce->inflight_waits++;
|
||||
#ifdef XCE_TESTING
|
||||
assert(ce->inflight_waits > 0 && ce->inflight_waits <= cap);
|
||||
assert(ce->inflight_waits > 0);
|
||||
#endif
|
||||
|
||||
/* Standalone / single-member: self constitutes the quorum (Req 6.3).
|
||||
|
|
@ -367,7 +417,7 @@ int commit_submit(commit_engine_t* ce, uint64_t lsn, commit_mode_t mode,
|
|||
}
|
||||
}
|
||||
|
||||
ce->inflight_waits--;
|
||||
wait_release_locked(ce);
|
||||
#ifdef XCE_TESTING
|
||||
assert(ce->inflight_waits >= 0);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue