kent: simplify structure

This commit is contained in:
anna 2021-07-31 15:58:29 +02:00
parent 8b3a5fd68d
commit fc63785ca6
Signed by: fef
GPG key ID: EC22E476DC2D3D84
5 changed files with 18 additions and 57 deletions

View file

@ -5,40 +5,21 @@
#include <ardix/atom.h> #include <ardix/atom.h>
#include <ardix/types.h> #include <ardix/types.h>
struct kent;
/**
* A collection of housekeeping callbacks for kents.
* This is implemented by every module using kents.
*/
struct kent_ops {
/**
* Destroy this kent and release all allocated resources.
* This is called when the refcount value reaches 0.
*
* @param kent: The kent to be destroyed.
*/
void (*destroy)(struct kent *kent);
};
/** /**
* struct kent: Kernel Entity * struct kent: Kernel Entity
* *
* This is basically a primitive ripoff of the kobject system in Linux, except * Kernel entities form a tree structure of reference counters and are meant to
* there is no representation in a virtual filesystem and it is only really used * be embedded into structures with dynamic lifetime. The reference count is
* to keeping track of hierarchial reference counting. * incremented and decremented using the `kent_get()` and `kent_put()` functions
* * respectively, and when the count reaches zero the `destroy` callback is
* The main purpose of kents is to provide a basic common abstraction layer for * invoked. This callback is responsible for performing any cleanup work
* all modules and submodules of the Ardix kernel. kents are arranged in a tree * required and releasing resources attached to the structure. Additionally,
* structure, and use an atomic reference counter to keep track of when it is * the parent kent's reference count is decremented as well.
* safe to destroy them. This structure is meant to be embedded into bigger
* structs and then cast out of when a reference to this one is passed to one of
* the
*/ */
struct kent { struct kent {
struct kent *parent; struct kent *parent;
atom_t refcount; atom_t refcount;
struct kent_ops *operations; void (*destroy)(struct kent *kent);
}; };
extern struct kent *kent_root; extern struct kent *kent_root;

View file

@ -17,10 +17,6 @@ static void devices_destroy(struct kent *kent)
free(kent); free(kent);
} }
struct kent_ops devices_kent_ops = {
.destroy = &devices_destroy,
};
/** Initialize the devices subsystem. */ /** Initialize the devices subsystem. */
int devices_init(void) int devices_init(void)
{ {
@ -32,7 +28,7 @@ int devices_init(void)
return -ENOMEM; return -ENOMEM;
devices_kent->parent = kent_root; devices_kent->parent = kent_root;
devices_kent->operations = &devices_kent_ops; devices_kent->destroy = devices_destroy;
return kent_init(devices_kent); return kent_init(devices_kent);
} }
@ -43,17 +39,13 @@ static void device_destroy(struct kent *kent)
free(dev); free(dev);
} }
struct kent_ops device_kent_ops = {
.destroy = &device_destroy,
};
int device_init(struct device *dev) int device_init(struct device *dev)
{ {
if (devices_kent == NULL) if (devices_kent == NULL)
return -ENOENT; return -ENOENT;
if (dev->kent.operations == NULL) if (dev->kent.destroy == NULL)
dev->kent.operations = &device_kent_ops; dev->kent.destroy = device_destroy;
if (dev->kent.parent == NULL) if (dev->kent.parent == NULL)
dev->kent.parent = devices_kent; dev->kent.parent = devices_kent;

View file

@ -15,10 +15,6 @@ static void dmabuf_destroy(struct kent *kent)
free(buf); free(buf);
} }
static struct kent_ops dmabuf_kent_ops = {
.destroy = &dmabuf_destroy,
};
struct dmabuf *dmabuf_create(struct device *dev, size_t len) struct dmabuf *dmabuf_create(struct device *dev, size_t len)
{ {
int err = 0; int err = 0;
@ -27,7 +23,7 @@ struct dmabuf *dmabuf_create(struct device *dev, size_t len)
return NULL; return NULL;
buf->kent.parent = &dev->kent; buf->kent.parent = &dev->kent;
buf->kent.operations = &dmabuf_kent_ops; buf->kent.destroy = dmabuf_destroy;
err = kent_init(&buf->kent); err = kent_init(&buf->kent);
if (err) { if (err) {

View file

@ -8,10 +8,6 @@
#include <errno.h> #include <errno.h>
#include <stddef.h> #include <stddef.h>
static struct kent_ops kent_root_ops = {
.destroy = NULL,
};
struct kent _kent_root; struct kent _kent_root;
struct kent *kent_root = NULL; struct kent *kent_root = NULL;
@ -22,7 +18,7 @@ int kent_root_init(void)
kent_root = &_kent_root; kent_root = &_kent_root;
kent_root->parent = NULL; kent_root->parent = NULL;
kent_root->operations = &kent_root_ops; kent_root->destroy = NULL;
atom_init(&kent_root->refcount); atom_init(&kent_root->refcount);
kent_get(kent_root); kent_get(kent_root);
@ -31,7 +27,7 @@ int kent_root_init(void)
int kent_init(struct kent *kent) int kent_init(struct kent *kent)
{ {
if (kent->parent == NULL || kent->operations == NULL) if (kent->parent == NULL || kent->destroy == NULL)
return -EFAULT; return -EFAULT;
kent_get(kent->parent); kent_get(kent->parent);
@ -51,7 +47,7 @@ void kent_put(struct kent *kent)
struct kent *parent = kent->parent; struct kent *parent = kent->parent;
if (atom_put(&kent->refcount) == 0) { if (atom_put(&kent->refcount) == 0) {
kent->operations->destroy(kent); kent->destroy(kent);
if (parent != NULL) if (parent != NULL)
kent_put(parent); kent_put(parent);

View file

@ -18,17 +18,13 @@ extern uint32_t _estack;
static struct task *_sched_tasktab[CONFIG_SCHED_MAXTASK]; static struct task *_sched_tasktab[CONFIG_SCHED_MAXTASK];
struct task *_sched_current_task; struct task *_sched_current_task;
static void sched_kent_destroy(struct kent *kent) static void task_destroy(struct kent *kent)
{ {
struct task *task = container_of(kent, struct task, kent); struct task *task = container_of(kent, struct task, kent);
_sched_tasktab[task->pid] = NULL; _sched_tasktab[task->pid] = NULL;
free(task); free(task);
} }
static struct kent_ops sched_kent_ops = {
.destroy = sched_kent_destroy,
};
int sched_init(void) int sched_init(void)
{ {
int i; int i;
@ -38,7 +34,7 @@ int sched_init(void)
return -ENOMEM; return -ENOMEM;
_sched_current_task->kent.parent = kent_root; _sched_current_task->kent.parent = kent_root;
_sched_current_task->kent.operations = &sched_kent_ops; _sched_current_task->kent.destroy = task_destroy;
i = kent_init(&_sched_current_task->kent); i = kent_init(&_sched_current_task->kent);
if (i == 0) { if (i == 0) {
_sched_current_task->sp = &_sstack; _sched_current_task->sp = &_sstack;
@ -121,7 +117,7 @@ struct task *sched_fork(struct task *parent)
goto err_maxtask; goto err_maxtask;
child->kent.parent = &parent->kent; child->kent.parent = &parent->kent;
child->kent.operations = &sched_kent_ops; child->kent.destroy = task_destroy;
if (kent_init(&child->kent) != 0) if (kent_init(&child->kent) != 0)
goto err_kent; goto err_kent;