X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/ec4ff182252b6d7b3cb81f4fa783c5348a6c30fd..d0e3d2eb32f32869bb54b5724e19780c83fb592b:/lunaix-os/kernel/lrud.c diff --git a/lunaix-os/kernel/lrud.c b/lunaix-os/kernel/lrud.c index 0395e42..137cfa6 100644 --- a/lunaix-os/kernel/lrud.c +++ b/lunaix-os/kernel/lrud.c @@ -3,16 +3,18 @@ #include #include #include +#include +#include #include static struct llist_header zone_lead = { .next = &zone_lead, .prev = &zone_lead }; DEFINE_SPINLOCK_OPS(struct lru_zone*, lock); - +static DEFINE_SPINLOCK(zone_list_lock); static void -__do_evict_lockless(struct lru_zone* zone, struct llist_header* elem) +__do_evict_nolock(struct lru_zone* zone, struct llist_header* elem) { llist_delete(elem); if (!zone->try_evict(container_of(elem, struct lru_node, lru_nodes))) { @@ -28,12 +30,16 @@ __do_evict_lockless(struct lru_zone* zone, struct llist_header* elem) } static void -__lru_evict_all_lockness(struct lru_zone* zone) +__lru_evict_all_nolock(struct lru_zone* zone) { - struct llist_header* tail = zone->lead_node.prev; - while (tail != &zone->lead_node) { - __do_evict_lockless(zone, tail); + struct llist_header* tail, *curr; + + tail = zone->lead_node.prev; + while (tail != &zone->lead_node) + { + curr = tail; tail = tail->prev; + __do_evict_nolock(zone, curr); } } @@ -49,9 +55,12 @@ lru_new_zone(const char* name, evict_cb try_evict_cb) strncpy(zone->name, name, sizeof(zone->name) - 1); llist_init_head(&zone->lead_node); - llist_append(&zone_lead, &zone->zones); spinlock_init(&zone->lock); + spinlock_acquire(&zone_list_lock); + llist_append(&zone_lead, &zone->zones); + spinlock_release(&zone_list_lock); + return zone; } @@ -60,10 +69,12 @@ lru_free_zone(struct lru_zone* zone) { lock(zone); - __lru_evict_all_lockness(zone); + __lru_evict_all_nolock(zone); - if (llist_empty(&zone->lead_node)) { + if (llist_empty(&zone->lead_node)) + { llist_delete(&zone->zones); + unlock(zone); vfree(zone); return; } @@ -107,24 +118,31 @@ lru_evict_one(struct lru_zone* zone) struct llist_header* tail = zone->lead_node.prev; if (tail == &zone->lead_node) { - return; + goto done; } - __do_evict_lockless(zone, tail); + __do_evict_nolock(zone, tail); +done: unlock(zone); } void lru_evict_half(struct lru_zone* zone) { + int target; + struct llist_header *tail, *curr; + lock(zone); - int target = (int)(zone->objects / 2); - struct llist_header* tail = zone->lead_node.prev; + target = (int)(zone->objects / 2); + tail = zone->lead_node.prev; + while (tail != &zone->lead_node && target > 0) { - __do_evict_lockless(zone, tail); + curr = tail; tail = tail->prev; + + __do_evict_nolock(zone, curr); target--; } @@ -138,7 +156,7 @@ lru_evict_all(struct lru_zone* zone) { lock(zone); - __lru_evict_all_lockness(zone); + __lru_evict_all_nolock(zone); zone->evict_stats.n_full++; @@ -148,16 +166,48 @@ lru_evict_all(struct lru_zone* zone) void lru_remove(struct lru_zone* zone, struct lru_node* node) { - lock(zone); + if (llist_empty(&node->lru_nodes)) + return; - if (node->lru_nodes.next && node->lru_nodes.prev) { - llist_delete(&node->lru_nodes); - } + lock(zone); + + llist_delete(&node->lru_nodes); zone->objects--; unlock(zone); } + +static void +__lru_pool_daemon() +{ + struct lru_zone *pos, *n; + + while (true) + { + spinlock_acquire(&zone_list_lock); + + // TODO add a watermark check before doing eviction + llist_for_each(pos, n, &zone_lead, zones) { + lru_evict_half(pos); + } + + spinlock_release(&zone_list_lock); + + kthread_sleep(10); + } +} + +static void +__lru_pool_init() +{ + // TODO make sure other are thread-safe first + + // kthread_spawn((ptr_t)__lru_pool_daemon); +} +owloysius_fetch_init(__lru_pool_init, on_postboot) + + static void __twimap_read_lru_pool(struct twimap* map) {