X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/bc34fd00d2e81fbc890bb2060ed6693454a230bf..baca54322c66983205edecd2ebb00d997878be50:/lunaix-os/kernel/ds/lru.c diff --git a/lunaix-os/kernel/ds/lru.c b/lunaix-os/kernel/ds/lru.c index ebabeef..08083b1 100644 --- a/lunaix-os/kernel/ds/lru.c +++ b/lunaix-os/kernel/ds/lru.c @@ -4,13 +4,15 @@ struct llist_header zone_lead = { .next = &zone_lead, .prev = &zone_lead }; struct lru_zone* -lru_new_zone() +lru_new_zone(evict_cb try_evict_cb) { - struct lru_zone* zone = valloc(sizeof(struct lru_zone)); + struct lru_zone* zone = vzalloc(sizeof(struct lru_zone)); if (!zone) { return NULL; } + zone->try_evict = try_evict_cb; + llist_init_head(&zone->lead_node); llist_append(&zone_lead, &zone->zones); @@ -25,9 +27,21 @@ lru_use_one(struct lru_zone* zone, struct lru_node* node) } llist_prepend(&zone->lead_node, &node->lru_nodes); + zone->objects++; +} + +static void +__do_evict(struct lru_zone* zone, struct llist_header* elem) +{ + llist_delete(elem); + if (!zone->try_evict(container_of(elem, struct lru_node, lru_nodes))) { + llist_append(&zone->lead_node, elem); + } else { + zone->objects--; + } } -struct lru_node* +void lru_evict_one(struct lru_zone* zone) { struct llist_header* tail = zone->lead_node.prev; @@ -35,15 +49,26 @@ lru_evict_one(struct lru_zone* zone) return; } - llist_delete(tail); + __do_evict(zone, tail); +} - return container_of(tail, struct lru_node, lru_nodes); +void +lru_evict_half(struct lru_zone* zone) +{ + int target = (int)(zone->objects / 2); + struct llist_header* tail = zone->lead_node.prev; + while (tail != &zone->lead_node && target > 0) { + __do_evict(zone, tail); + tail = tail->prev; + target--; + } } void -lru_remove(struct lru_node* node) +lru_remove(struct lru_zone* zone, struct lru_node* node) { if (node->lru_nodes.next && node->lru_nodes.prev) { llist_delete(&node->lru_nodes); } + zone->objects--; } \ No newline at end of file