r1567996, r1567985

r1567985 | stefan2 | 2014-02-13 17:48:59 +0000 (Thu, 13 Feb 2014)

On 32 bit systems, integer underflows can cause the membuffer usage counters
to grow beyond 32 bit limits.  That makes all entries appear to be "small"
and being kept instead of being potentially evicted.

* subversion/libsvn_subr/cache-membuffer.c
  (svn_membuffer_t): Update comment.
  (membuffer_cache_set_internal): Adding a cast to prevent off-by-4GB in the
                                  cache->DATA_USED tracker in 32 bits systems.

Found by: vitalif{_AT_}
Suggested by: James McCoy <jamessan{_AT_}>

r1567996 | stefan2 | 2014-02-13 18:24:17 +0000 (Thu, 13 Feb 2014)

In the membuffer cache code, we update hit counters without further
synchronization as they are mere hints.  However, that can cause
64 bit underflows in the global hit counters which will make all
entry hit counters appear to be very small in comparison, i.e.
entries get evicted sooner than they should.

We fix this by simply switching to signed global counters which
compare nicely to unsigned values of less precision. This allows
us to keep the lock-free racy code without introducing a bias
(e.g. by saturating at 0 upon underflow).

Once at it, fix the local <-> global hit counter inconsistency
that occurs when the entry hit counter exceeds 4G - which might
happen for certain root objects.

* subversion/libsvn_subr/cache-membuffer.c
  (svn_membuffer_t): Switch to signed counters as those work
                     nicely with our comparison / eviction logic
                     even if we underflow to negative values.
  (increment_hit_counters): New utility function handling the
                            potential 32 bit counter overflow.
   membuffer_cache_set_partial_internal): Call the new utility.

Found by: vitalif{_AT_}