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_}yourcmc.ru Suggested by: James McCoy <jamessan{_AT_}debian.org>
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_get_internal, membuffer_cache_has_key_internal, membuffer_cache_get_partial_internal, membuffer_cache_set_partial_internal): Call the new utility. Found by: vitalif{_AT_}yourcmc.ru