Use shared lock and atomic timestamp in LogicalSessionCacheImpl::vivify fast path

XMLWordPrintableJSON

    • Product Performance
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Problem

      LogicalSessionCacheImpl::vivify runs once per request from ServiceEntryPointShardRole::handleRequestinitializeOperationSessionInfo. On a 128-thread YCSB 100% read workload, it acquires an exclusive stdx::mutex on every call even though the steady-state path is just an absl::raw_hash_set::find plus a lastUse timestamp stamp. In the pinned-baseline pprof, vivify accounts for 0.44% cum of total mongod CPU and 52% of that is pthread_mutex_lock + pthread_mutex_unlock overhead — the mutex itself is the dominant cost, not the actual cache lookup. With a single shared mutex across all worker threads, this is pure cache-line ping-pong on the lock word at ~88K finds/sec.

      Solution

      Replace stdx::mutex _mutex with RWMutex _mutex, wrap each cache record in a stable-address CachedSessionEntry containing the existing LogicalSessionRecord plus an AtomicWord<long long> lastUseMs shadow, and split vivify() into a shared-lock fast path (find + atomic timestamp stamp) and an exclusive-lock slow path (insert / refresh / reap / endSessions, semantically unchanged). Callers that expose record.lastUse (peekCached, _refresh, _reap, getStats, listIds) reconcile the atomic shadow back into the record via _syncLastUseToRecord under exclusive lock before reading. The fast path no longer ping-pongs the mutex's cache line across cores; the slow path preserves every existing invariant — including the _refresh() swap-then-back-swap protocol that prevents the SERVER-123432 reap race.

            Assignee:
            Jawwad Asghar
            Reporter:
            Jawwad Asghar
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: