#include #include #include #include #include #include #include #define CODEC_COUNT 4 #define MOUNT_BUDGET (256U * 1024) #define GLOBAL_BUDGET (512U * 1024) #define MINIMUM_WORK (128U * 1024) enum cache_state { CACHE_EMPTY, CACHE_INFLIGHT, CACHE_READY, }; enum cache_lookup { CACHE_BYPASS, CACHE_HIT, CACHE_OWNER, }; struct metric { uint64_t hits; uint64_t misses; uint64_t bypasses; uint64_t evictions; uint64_t reclaims; size_t resident_bytes; }; struct budget { size_t limit; size_t used; size_t peak; }; struct key { uint64_t identity; uint8_t codec; }; struct cache { struct budget *global; struct metric metrics[CODEC_COUNT]; struct key key; unsigned char *data; size_t charged_bytes; size_t budget_bytes; size_t peak_bytes; enum cache_state state; bool enabled; }; static void fail(const char *message) { fprintf(stderr, "B33 cache oracle failure: %s\n", message); exit(1); } static uint64_t hash_bytes(const unsigned char *data, size_t size) { uint64_t hash; size_t index; hash = UINT64_C(1469598103934665603); for (index = 0; index < size; ++index) { hash ^= data[index]; hash *= UINT64_C(1099511628211); } return (hash); } static void fill(unsigned char *data, size_t size, const struct key *key) { size_t index; for (index = 0; index < size; ++index) data[index] = (unsigned char)(key->identity + key->codec * 31 + index * 17); } static bool key_equal(const struct key *left, const struct key *right) { return (left->identity == right->identity && left->codec == right->codec); } static bool reserve(struct budget *budget, size_t bytes) { if (bytes > budget->limit || budget->used > budget->limit - bytes) return (false); budget->used += bytes; if (budget->used > budget->peak) budget->peak = budget->used; return (true); } static void release(struct budget *budget, size_t bytes) { if (bytes > budget->used) fail("global budget underflow"); budget->used -= bytes; } static void cache_init(struct cache *cache, struct budget *global, bool enabled) { memset(cache, 0, sizeof(*cache)); cache->global = global; cache->budget_bytes = MOUNT_BUDGET; cache->enabled = enabled; } static bool policy_admit(const struct cache *cache, uint8_t codec, size_t decoded_size, size_t compressed_size) { return (cache->enabled && codec < CODEC_COUNT && decoded_size <= cache->budget_bytes && compressed_size + decoded_size >= MINIMUM_WORK); } static void drop(struct cache *cache, bool evicted, bool reclaimed) { struct metric *metric; if (cache->charged_bytes == 0) return; if (cache->key.codec >= CODEC_COUNT) fail("charged unknown codec"); metric = &cache->metrics[cache->key.codec]; if (cache->state == CACHE_READY) { if (metric->resident_bytes != cache->charged_bytes) fail("codec resident accounting mismatch"); metric->resident_bytes = 0; if (evicted) ++metric->evictions; if (reclaimed) ++metric->reclaims; } release(cache->global, cache->charged_bytes); cache->charged_bytes = 0; free(cache->data); cache->data = NULL; } static enum cache_lookup claim(struct cache *cache, const struct key *key, size_t decoded_size, size_t compressed_size, unsigned char *output) { struct metric *metric; if (key->codec >= CODEC_COUNT) fail("unknown requested codec"); metric = &cache->metrics[key->codec]; if (!policy_admit(cache, key->codec, decoded_size, compressed_size)) { ++metric->bypasses; return (CACHE_BYPASS); } if (cache->state == CACHE_READY && key_equal(&cache->key, key)) { memcpy(output, cache->data, decoded_size); ++metric->hits; return (CACHE_HIT); } if (cache->state == CACHE_INFLIGHT) { ++metric->bypasses; return (CACHE_BYPASS); } if (cache->state == CACHE_READY) drop(cache, true, false); cache->state = CACHE_EMPTY; if (!reserve(cache->global, decoded_size)) { ++metric->bypasses; return (CACHE_BYPASS); } cache->charged_bytes = decoded_size; if (decoded_size > cache->peak_bytes) cache->peak_bytes = decoded_size; cache->key = *key; cache->state = CACHE_INFLIGHT; ++metric->misses; return (CACHE_OWNER); } static void complete(struct cache *cache, const struct key *key, unsigned char *data, int error) { struct metric *metric; if (cache->state != CACHE_INFLIGHT || !key_equal(&cache->key, key)) fail("owner lost key"); metric = &cache->metrics[key->codec]; if (error != 0) { if (data != NULL || error < 1) fail("failure publication is untyped"); release(cache->global, cache->charged_bytes); cache->charged_bytes = 0; cache->state = CACHE_EMPTY; return; } if (data == NULL || metric->resident_bytes != 0) fail("success publication is untyped"); cache->data = data; metric->resident_bytes = cache->charged_bytes; cache->state = CACHE_READY; } static bool reclaim(struct cache *cache) { if (cache->state == CACHE_INFLIGHT) return (false); if (cache->state == CACHE_READY) { drop(cache, true, true); cache->state = CACHE_EMPTY; } return (true); } static void cache_fini(struct cache *cache) { if (cache->state == CACHE_INFLIGHT) fail("unmount did not drain owner"); drop(cache, false, false); cache->state = CACHE_EMPTY; } static unsigned char * make_data(const struct key *key, size_t size) { unsigned char *data; data = malloc(size); if (data == NULL) fail("decoded allocation"); fill(data, size, key); return (data); } static void test_codec_accounting(struct budget *global, struct metric output[CODEC_COUNT], uint64_t *eviction_hash) { struct cache cache; struct key key; unsigned char *expected, *readback; uint64_t before, after; unsigned int codec; cache_init(&cache, global, true); expected = malloc(MOUNT_BUDGET); readback = malloc(MOUNT_BUDGET); if (expected == NULL || readback == NULL) fail("accounting buffers"); before = 0; for (codec = 0; codec < CODEC_COUNT; ++codec) { key = (struct key){ .identity = 100 + codec, .codec = codec }; fill(expected, MOUNT_BUDGET, &key); if (claim(&cache, &key, MOUNT_BUDGET, 4096, readback) != CACHE_OWNER) fail("codec-neutral request was not admitted"); complete(&cache, &key, make_data(&key, MOUNT_BUDGET), 0); if (claim(&cache, &key, MOUNT_BUDGET, 4096, readback) != CACHE_HIT || memcmp(readback, expected, MOUNT_BUDGET) != 0) fail("codec cache hit changed bytes"); if (codec == 0) before = hash_bytes(readback, MOUNT_BUDGET); } key = (struct key){ .identity = 100, .codec = 0 }; if (claim(&cache, &key, MOUNT_BUDGET, 4096, readback) != CACHE_OWNER) fail("evicted codec key was not reusable"); complete(&cache, &key, make_data(&key, MOUNT_BUDGET), 0); if (claim(&cache, &key, MOUNT_BUDGET, 4096, readback) != CACHE_HIT) fail("reused codec key did not hit"); after = hash_bytes(readback, MOUNT_BUDGET); if (before != after) fail("eviction changed decoded hash"); if (!reclaim(&cache) || global->used != 0) fail("ready reclaim did not release bytes"); if (cache.peak_bytes != MOUNT_BUDGET) fail("mount peak did not equal hard budget"); memcpy(output, cache.metrics, sizeof(cache.metrics)); *eviction_hash = after; free(readback); free(expected); } static uint64_t test_global_exhaustion(struct budget *global) { struct cache first, second, third; struct key first_key = { .identity = 201, .codec = 0 }; struct key second_key = { .identity = 202, .codec = 2 }; struct key third_key = { .identity = 203, .codec = 3 }; unsigned char *scratch; uint64_t fallback_hash; cache_init(&first, global, true); cache_init(&second, global, true); cache_init(&third, global, true); scratch = malloc(MOUNT_BUDGET); if (scratch == NULL) fail("global fallback allocation"); if (claim(&first, &first_key, MOUNT_BUDGET, 4096, scratch) != CACHE_OWNER || claim(&second, &second_key, MOUNT_BUDGET, 4096, scratch) != CACHE_OWNER) fail("two mounts did not fill global budget"); complete(&first, &first_key, make_data(&first_key, MOUNT_BUDGET), 0); complete(&second, &second_key, make_data(&second_key, MOUNT_BUDGET), 0); if (global->used != GLOBAL_BUDGET || global->peak != GLOBAL_BUDGET) fail("global hard budget was not reached exactly"); if (claim(&third, &third_key, MOUNT_BUDGET, 4096, scratch) != CACHE_BYPASS) fail("global exhaustion did not bypass"); fill(scratch, MOUNT_BUDGET, &third_key); fallback_hash = hash_bytes(scratch, MOUNT_BUDGET); if (!reclaim(&first) || claim(&third, &third_key, MOUNT_BUDGET, 4096, scratch) != CACHE_OWNER) fail("reclaimed global bytes were not reusable"); complete(&third, &third_key, make_data(&third_key, MOUNT_BUDGET), 0); cache_fini(&second); cache_fini(&third); if (global->used != 0) fail("unmount did not release global bytes"); free(scratch); return (fallback_hash); } static void test_failure_and_policy(struct budget *global) { struct cache cache, disabled; struct key key = { .identity = 301, .codec = 1 }; unsigned char output[MOUNT_BUDGET]; unsigned int codec; cache_init(&cache, global, true); if (claim(&cache, &key, MOUNT_BUDGET, 4096, output) != CACHE_OWNER) fail("failure setup was not admitted"); if (reclaim(&cache)) fail("inflight reclaim did not report busy"); complete(&cache, &key, NULL, EIO); if (global->used != 0 || claim(&cache, &key, MOUNT_BUDGET, 4096, output) != CACHE_OWNER) fail("failure did not release budget for retry"); complete(&cache, &key, make_data(&key, MOUNT_BUDGET), 0); cache_fini(&cache); cache_init(&disabled, global, false); for (codec = 0; codec < CODEC_COUNT; ++codec) { key.codec = codec; if (claim(&disabled, &key, MOUNT_BUDGET, 4096, output) != CACHE_BYPASS) fail("disabled codec policy did not bypass"); disabled.enabled = true; if (claim(&disabled, &key, 64U * 1024, 1, output) != CACHE_BYPASS) fail("low-work policy did not bypass"); disabled.enabled = false; } disabled.enabled = true; if (claim(&disabled, &key, MOUNT_BUDGET + 1, 4096, output) != CACHE_BYPASS) fail("oversized policy did not bypass"); cache_fini(&disabled); if (global->used != 0) fail("policy tests leaked global bytes"); } int main(void) { struct budget global = { .limit = GLOBAL_BUDGET }; struct metric metrics[CODEC_COUNT]; uint64_t eviction_hash, fallback_hash; unsigned int codec; test_codec_accounting(&global, metrics, &eviction_hash); fallback_hash = test_global_exhaustion(&global); test_failure_and_policy(&global); for (codec = 0; codec < CODEC_COUNT; ++codec) { if (metrics[codec].hits == 0 || metrics[codec].misses == 0 || metrics[codec].evictions == 0 || metrics[codec].resident_bytes != 0) fail("four-codec metrics are incomplete"); } printf("{\"status\":\"PASS\",\"global_limit\":%u," "\"global_peak\":%zu,\"global_remaining\":%zu," "\"mount_limit\":%u,\"eviction_hash\":\"%016" PRIx64 "\"," "\"fallback_hash\":\"%016" PRIx64 "\",\"metrics\":[", GLOBAL_BUDGET, global.peak, global.used, MOUNT_BUDGET, eviction_hash, fallback_hash); for (codec = 0; codec < CODEC_COUNT; ++codec) { if (codec != 0) printf(","); printf("{\"codec\":%u,\"hits\":%" PRIu64 ",\"misses\":%" PRIu64 ",\"bypasses\":%" PRIu64 ",\"evictions\":%" PRIu64 ",\"reclaims\":%" PRIu64 ",\"resident_bytes\":%zu}", codec, metrics[codec].hits, metrics[codec].misses, metrics[codec].bypasses, metrics[codec].evictions, metrics[codec].reclaims, metrics[codec].resident_bytes); } printf("]}\n"); return (0); }