Avoid taking PMS snapshot lock when snapshot is still valid

Maintains 2 integers, one for snapshot current version and one for
snapshot pending version, where the former is updated to the latter
whenever a snapshot is rebuilt.

Calling threads can compare the volatile integers to see if the
snapshot is valid without taking mSnapshotLock. This avoids blocking
parallel threads using the snapshot.

Snapshot rebuilds are guaranteed to be accurate to the point in
time when one is requested, not the time that the snapshot is returned,
and this is enforced by caching the most recent pending version
before rebuilding the snapshot.

The thread that rebuilds will continue with its result regardless of
whether the snapshot was invalidated in between pending version read
and rebuild finish, and update the current version to the pending
version read. If an invalidation came in from the background, this
committed version will no longer be equivalent to the latest pending
version in the field, and so when the rebuild thread releases,
future/waiting threads will still see the snapshot as invalid and
cause a further rebuild.

This ensures changes are never lost and the snapshot will always
eventually be brought up to date.

Bug: 232282785

Test: presubmit

Change-Id: I99656d573c7cec88069ec2eb35a1c7be48c782e0
5 files changed