aboutsummaryrefslogtreecommitdiff
path: root/kernel/mm/pframe.c
diff options
context:
space:
mode:
authornthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
committernthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
commitc63f340d90800895f007de64b7d2d14624263331 (patch)
tree2c0849fa597dd6da831c8707b6f2603403778d7b /kernel/mm/pframe.c
Created student weenix repository
Diffstat (limited to 'kernel/mm/pframe.c')
-rw-r--r--kernel/mm/pframe.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/kernel/mm/pframe.c b/kernel/mm/pframe.c
new file mode 100644
index 0000000..6eff123
--- /dev/null
+++ b/kernel/mm/pframe.c
@@ -0,0 +1,59 @@
+#include "globals.h"
+
+#include "mm/pframe.h"
+#include "mm/slab.h"
+
+#include "util/debug.h"
+#include "util/string.h"
+
+static slab_allocator_t *pframe_allocator;
+
+void pframe_init()
+{
+ pframe_allocator = slab_allocator_create("pframe", sizeof(pframe_t));
+ KASSERT(pframe_allocator);
+}
+
+/*
+ * Create a pframe and initialize its members appropriately.
+ */
+pframe_t *pframe_create()
+{
+ pframe_t *pf = slab_obj_alloc(pframe_allocator);
+ if (!pf)
+ {
+ return NULL;
+ }
+ memset(pf, 0, sizeof(pframe_t));
+ kmutex_init(&pf->pf_mutex);
+ list_link_init(&pf->pf_link);
+ return pf;
+}
+
+/*
+ * Free the pframe (don't forget to unlock the mutex) and set *pfp = NULL
+ *
+ * The pframe must be locked, its contents not in memory (pf->pf_addr == NULL),
+ * have a pincount of 0, and not be linked into a memory object's list.
+ */
+void pframe_free(pframe_t **pfp)
+{
+ KASSERT(kmutex_owns_mutex(&(*pfp)->pf_mutex));
+ KASSERT(!(*pfp)->pf_addr);
+ KASSERT(!(*pfp)->pf_dirty);
+ KASSERT(!list_link_is_linked(&(*pfp)->pf_link));
+ kmutex_unlock(&(*pfp)->pf_mutex);
+ slab_obj_free(pframe_allocator, *pfp);
+ *pfp = NULL;
+}
+
+/*
+ * Unlock the pframe and set *pfp = NULL
+ */
+void pframe_release(pframe_t **pfp)
+{
+ pframe_t *pf = *pfp;
+ KASSERT(kmutex_owns_mutex(&pf->pf_mutex));
+ *pfp = NULL;
+ kmutex_unlock(&pf->pf_mutex);
+}