85 static void destroyInstance() {
100 void registerCache(
Cache* pCache);
101 void unregisterCache(
Cache* pCache);
106 bool trimAll(
size_t count = 1);
108 virtual void timer(uint64_t delta);
115 void stopPeriodicWork();
116 void timerTick(uint64_t delta,
bool memoryPressure);
119 uint64_t elapsed = 0;
122 void advance(uint64_t delta);
123 uint64_t since(
const TimerStamp& previous)
const;
127 bool findNextCache(uint64_t afterId, uint64_t maximumId,
Cache*& cache, uint64_t& cacheId,
128 bool timersOnly =
false);
136 : cache(requestCache), lease(pedigree_std::move(requestLease)) {}
142 bool callbackContext()
const {
150 bool acquireNextCache(uint64_t afterId, uint64_t maximumId,
Cache*& cache, uint64_t& cacheId,
154 uint64_t cacheGenerationWatermark();
158 uint64_t addCacheRequest(
Cache* cache,
bool asynchronous, CacheConstants::CallbackCause cause,
159 uintptr_t key, uintptr_t location = 0,
bool transferredPin =
false,
166 virtual uint64_t
executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5,
167 uint64_t p6, uint64_t p7, uint64_t p8);
177 return (a.p1 == b.p1) && (a.p2 == b.p2) && (a.p3 == b.p3) && (a.p6 == b.p6);
187 uint64_t m_TrimDelta;
195 bool m_bTrimRequested;
209 friend class CacheMemoryTestPeer;
222 size_t writebackPins;
224 bool directWriteback;
231 enum class EvictionState {
239 uint64_t checksum[2];
244 bool writebackFailed;
245 bool externallyWritable;
246 bool writebackIndexed;
247 uint64_t mutationGeneration;
248 uint64_t writtenGeneration;
249 uint64_t writebackEpoch;
271 bool checkChecksum(uint64_t other[2])
const;
274 bool checkZeroChecksum()
const;
289 typedef bool (*writeback_t)(CacheConstants::CallbackCause cause, uintptr_t loc, uintptr_t page,
293 typedef bool (*retirement_writeback_t)(uintptr_t key, uintptr_t page,
void* meta);
295#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
296 typedef void (*writeback_admission_hook_t)(
Cache* cache, uintptr_t key,
void* meta);
299 Cache(
size_t pageConstraints = 0);
302 enum class ShutdownMode { WriteBack, Discard, DiscardDeferred };
317 bool shutdown(ShutdownMode mode = ShutdownMode::WriteBack);
325 void setCallback(writeback_t newCallback,
void* meta);
327 enum class DirtyTracking { Checksum, Explicit };
332 void setDirtyTracking(DirtyTracking tracking);
335 uintptr_t lookup(uintptr_t key);
343 size_t read(uintptr_t offset,
size_t length, uintptr_t buffer,
344 bool (*prepare)(uintptr_t,
size_t) =
nullptr);
351 MUST_USE_RESULT bool lookupStable(uintptr_t key, uintptr_t& location,
bool wait =
false);
367 uintptr_t insert(uintptr_t key,
bool* alreadyExisted =
nullptr);
385 uintptr_t insert(uintptr_t key,
size_t size,
bool* alreadyExisted =
nullptr);
388 bool exists(uintptr_t key,
size_t length);
396 bool evict(uintptr_t key);
417 MUST_USE_RESULT bool retireWriteback(uintptr_t key, retirement_writeback_t callback,
void* meta);
419#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
421 void setWritebackAdmissionHookForTest(writeback_admission_hook_t hook,
void* meta);
436 enum class DiscardStatus { Ready, NoMemory, Busy, Invalid, Closed };
444 MUST_USE_RESULT bool writeback(retirement_writeback_t callback,
void* context);
466 DiscardStatus prepareDiscardFrom(uintptr_t cutoff,
const DiscardReference* references,
470 void release(uintptr_t key);
497 size_t trim(
size_t count = 1);
505 bool sync(uintptr_t key,
bool async);
514 static constexpr size_t MaxWritebackPages = 64;
531 bool acquire(
Cache& cache, uintptr_t key, uintptr_t location);
533 physical_uintptr_t physical()
const {
540 physical_uintptr_t m_Physical;
542 using writeback_batch_t = bool (*)(
const WritebackPage*, size_t,
void*);
544 void setBackgroundWriteback(writeback_batch_t callback);
549 MUST_USE_RESULT bool syncAll(writeback_batch_t callback,
void* metadata);
559 MUST_USE_RESULT bool syncBatch(
const uintptr_t* keys,
size_t count, writeback_batch_t callback,
567 void triggerChecksum(uintptr_t key);
570 void markDirty(uintptr_t key);
575 void markExternallyWritable(uintptr_t key);
583 void endMutableLoan(uintptr_t key);
595 if (!ensureUsable(
"startAtomic")) {
605 if (!ensureUsable(
"endAtomic")) {
621 void markEditing(uintptr_t key,
size_t length = 0);
628 void markNoLongerEditing(uintptr_t key,
size_t length = 0);
631 enum class EvictionMode {
633 DiscardBaseReference,
639 bool map(uintptr_t virt)
const;
642 bool evict(uintptr_t key, EvictionMode mode,
size_t* discardedDirtyPages =
nullptr);
643 bool empty(EvictionMode mode,
size_t* discardedDirtyPages,
bool waitForPins =
true);
646 bool finishRetirement(CachePage* page, writeback_t callback,
void* callbackMeta);
648 void releaseWriteback(uintptr_t key);
651 void waitForPageEviction(uintptr_t key);
654 bool ensureUsable(
const char* operation)
const;
662 size_t lruEvict(
bool force =
false);
667 void linkPage(CachePage* pPage);
674 void promotePage(CachePage* pPage);
679 void unlinkPage(CachePage* pPage);
684 void calculateChecksum(CachePage* pPage);
689 bool verifyChecksum(CachePage* pPage,
bool replace =
false);
691 bool tracksChecksum(
const CachePage* page)
const;
692 bool needsWriteback(CachePage* page);
693 void updateWritebackIndex(CachePage* page);
694 void recordMutation(CachePage* page);
699 void checksum(
const void* data,
size_t len, uint64_t out[2]);
702 CacheConstants::CallbackCause cause;
703 writeback_t callback;
716 return __atomic_load_n(&m_PeriodicTimerEnabled, __ATOMIC_ACQUIRE);
726 virtual void timer(uint64_t delta);
731 virtual uint64_t
executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5,
732 uint64_t p6, uint64_t p7, uint64_t p8);
737 uintptr_t keys[MaxWritebackPages];
740 bool syncBatchInternal(
const uintptr_t* keys,
size_t count, writeback_batch_t callback,
741 void* metadata,
bool snapshot);
743 bool writebackPage(uintptr_t key, uintptr_t location,
bool wait);
750 DirtyTracking m_DirtyTracking;
782 bool m_PeriodicTimerEnabled;
786 writeback_batch_t m_BackgroundWriteback;
791 uint64_t m_WritebackEpoch;
806#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
807 writeback_admission_hook_t m_WritebackAdmissionHook;
808 void* m_WritebackAdmissionHookMeta;
811#ifdef STANDALONE_CACHE
bool checksumChanging
Marker to check that a page's contents are in flux.
CachePage * pNext
Linked list components for LRU.
uintptr_t location
The location of this page in memory.