| 1225 | template <typename AllocatorT> |
| 1226 | template <typename T> |
| 1227 | void ObjectCache<AllocatorT>::mutateObject(const std::shared_ptr<T>& object, |
| 1228 | std::function<void()> mutateCb) { |
| 1229 | if (!object) { |
| 1230 | return; |
| 1231 | } |
| 1232 | |
| 1233 | cachelib::objcache2::ThreadMemoryTracker tMemTracker; |
| 1234 | size_t memUsageBefore = tMemTracker.getMemUsageBytes(); |
| 1235 | mutateCb(); |
| 1236 | size_t memUsageAfter = tMemTracker.getMemUsageBytes(); |
| 1237 | |
| 1238 | auto& hdl = getWriteHandleRefInternal<T>(object); |
| 1239 | size_t memUsageDiff = 0; |
| 1240 | #pragma clang diagnostic push |
| 1241 | #pragma clang diagnostic ignored "-Watomic-alignment" |
| 1242 | if (memUsageAfter > memUsageBefore) { // updated to a larger value |
| 1243 | memUsageDiff = memUsageAfter - memUsageBefore; |
| 1244 | // do atomic update on objectSize |
| 1245 | ObjectCacheItem* o = getAlignedItemPtr(hdl->getMemory()); |
| 1246 | __atomic_fetch_add(&(o->objectSize), memUsageDiff, __ATOMIC_SEQ_CST); |
| 1247 | totalObjectSizeBytes_.fetch_add(memUsageDiff, std::memory_order_relaxed); |
| 1248 | } else if (memUsageAfter < memUsageBefore) { // updated to a smaller value |
| 1249 | memUsageDiff = memUsageBefore - memUsageAfter; |
| 1250 | // do atomic update on objectSize |
| 1251 | ObjectCacheItem* o = getAlignedItemPtr(hdl->getMemory()); |
| 1252 | __atomic_fetch_sub(&(o->objectSize), memUsageDiff, __ATOMIC_SEQ_CST); |
| 1253 | totalObjectSizeBytes_.fetch_sub(memUsageDiff, std::memory_order_relaxed); |
| 1254 | } |
| 1255 | #pragma clang diagnostic pop |
| 1256 | } |
| 1257 | |
| 1258 | template <typename AllocatorT> |
| 1259 | template <typename T> |