aboutsummaryrefslogtreecommitdiff
path: root/common/mem_nodes.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-04-16 19:25:05 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-04-16 19:25:05 +0300
commite71dd2d9fe1cc3a6d074f9c1894e2c5200cecdb1 (patch)
treec698f756f38f0ebe6e549f32e9bc4b7647d40b5d /common/mem_nodes.c
parent4c6be9cb63ff66ce49a6f733c1e00d1889f2c95f (diff)
downloadkmi-e71dd2d9fe1cc3a6d074f9c1894e2c5200cecdb1.tar.gz
kmi-e71dd2d9fe1cc3a6d074f9c1894e2c5200cecdb1.zip
create more general node structure
+ Allow for easier handling of other subsystems that want to use nodes, mainly tcb and possibly dev_mem
Diffstat (limited to 'common/mem_nodes.c')
-rw-r--r--common/mem_nodes.c148
1 files changed, 5 insertions, 143 deletions
diff --git a/common/mem_nodes.c b/common/mem_nodes.c
index 2ab6978..392fa3e 100644
--- a/common/mem_nodes.c
+++ b/common/mem_nodes.c
@@ -4,162 +4,24 @@
#include <apos/string.h>
#include <apos/mem_nodes.h>
-enum block_status { FREE = 0, USED = 1 };
-
-struct block_wrapper {
- enum block_status status;
- struct mem_region n;
-};
-
-struct block_region {
- size_t used_blocks;
-
- struct block_region *av_next;
- struct block_region *av_prev;
-
- struct block_region *next;
- struct block_region *prev;
-};
-
-#define MAX_BLOCKS \
- ((BASE_PAGE_SIZE - sizeof(struct block_region)) / \
- sizeof(struct block_wrapper))
-
-#define block_region(b) \
- ((struct block_region *)((size_t)(b) & ~(BASE_PAGE_SIZE - 1)))
-
-#define block_container(b) container_of(b, struct block_wrapper, n)
-
-#define region_to_array(r) \
- ((struct block_wrapper *)((char *)(r) + sizeof(struct block_region)))
-
-static struct block_region *head = 0;
-static struct block_region *av_head = 0;
-
-static struct block_region *__create_region()
-{
- struct block_region *r =
- (struct block_region *)alloc_page(BASE_PAGE, 0);
- memset(r, FREE, BASE_PAGE_SIZE);
- return r;
-}
+static struct node_root root;
void init_mem_blocks()
{
- head = __create_region();
- av_head = head;
+ init_nodes(&root, sizeof(struct mem_region));
}
void destroy_mem_blocks()
{
- struct block_region *r = head;
- while (r) {
- struct block_region *d = r;
- r = r->prev;
- free_page(MM_O0, (pm_t)d);
- }
-}
-
-static struct mem_region *__find_free_block(struct block_region *h)
-{
- struct block_wrapper *w = region_to_array(h);
- for (size_t i = 0; i < MAX_BLOCKS; ++i) {
- if (w[i].status != FREE)
- continue;
-
- w[i].status = USED;
- return &w[i].n;
- }
-
- return 0;
-}
-
-static void __pop_av_head()
-{
- struct block_region *t = av_head;
- av_head = av_head->av_next;
- if (av_head)
- av_head->av_prev = 0;
-
- t->av_next = 0;
- t->av_prev = 0;
+ destroy_nodes(&root);
}
struct mem_region *get_mem_node()
{
- if (!av_head) {
- av_head = __create_region();
-
- av_head->prev = head;
- head->next = av_head;
-
- head = av_head;
- }
-
- struct mem_region *ret = __find_free_block(av_head);
-
- if (++av_head->used_blocks == MAX_BLOCKS)
- __pop_av_head();
-
- return ret;
-}
-
-static void __push_av_head(struct block_region *r)
-{
- r->av_prev = 0;
- r->av_next = av_head;
- if (av_head)
- av_head->av_prev = r;
-
- av_head = r;
-}
-
-static void __free_block(struct block_region *r)
-{
- struct block_region *av_n = r->av_next;
- struct block_region *av_p = r->av_prev;
-
- if (av_n)
- av_n->av_prev = av_p;
-
- if (av_p)
- av_p->av_next = av_n;
-
- if (r == av_head)
- __pop_av_head();
-
- struct block_region *n = r->next;
- struct block_region *p = r->prev;
-
- if (n)
- n->prev = p;
-
- if (p)
- p->next = n;
-
- if (r == head) {
- if (head->prev) {
- head->next = 0;
- head = head->prev;
- } else
- return;
- }
-
- free_page(BASE_PAGE, (pm_t)r);
+ return (struct mem_region *)get_node(&root);
}
void free_mem_node(struct mem_region *m)
{
- struct block_wrapper *w = block_container(m);
- w->status = FREE;
-
- struct block_region *r = block_region(w);
-
- if (--r->used_blocks == 0) {
- __free_block(r);
- return;
- }
-
- else if (!r->av_next && !r->av_prev)
- __push_av_head(r);
+ free_node(&root, (void *)m);
}