summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/Makefile2
-rw-r--r--src/kernel/lib/earray.cpp158
-rw-r--r--src/kernel/lib/earray.h35
3 files changed, 194 insertions, 1 deletions
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index a1acc49..1103a7d 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -2,7 +2,7 @@ Out = kernel.elf
Obj = core/loader_.o core/kmain.o core/sys.o \
core/monitor.o task/timer.o \
task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o task/sched.o \
- lib/bitset.o lib/std.o lib/cpp.o \
+ lib/bitset.o lib/std.o lib/cpp.o lib/earray.o \
mem/mem.o mem/paging.o mem/gdt.o mem/_dlmalloc.o mem/seg.o \
linker/elf.o
diff --git a/src/kernel/lib/earray.cpp b/src/kernel/lib/earray.cpp
new file mode 100644
index 0000000..5760822
--- /dev/null
+++ b/src/kernel/lib/earray.cpp
@@ -0,0 +1,158 @@
+#include "earray.h"
+
+#include <mem/mem.h>
+#include <core/sys.h>
+#include <lib/cpp.h>
+
+template <typename T>
+earray<T>::earray(int rvil, int vl) {
+ ref_vect_init_len = rvil;
+ vect_len = vl;
+
+ ref_vect_len = ref_vect_init_len;
+ elements = 0;
+ mutex = MUTEX_UNLOCKED;
+
+ data = (T***)kmalloc(ref_vect_len * sizeof(T**));
+
+ for (int i = 0; i < ref_vect_len; i++) {
+ data[i] = 0;
+ }
+}
+
+template <typename T>
+earray<T>::~earray() {
+ mutex_lock(&mutex);
+
+ for (int i = 0; i < ref_vect_len; i++) {
+ if (data[i] != 0) kfree(data[i]);
+ }
+ kfree(data);
+
+ //no need to unlock, the structure is never to be used again
+}
+
+template <typename T>
+int earray<T>::add(T* ptr) {
+ if (ptr == 0) return -1;
+
+ mutex_lock(&mutex);
+
+ for (int i = 0; i < ref_vect_len; i++) {
+ if (data[i] == 0) {
+ // Allocate here
+ data[i] = (T**)kmalloc(vect_len * sizeof(T*));;
+ data[i][0] = ptr;
+ for (int j = 1; j < vect_len; j++) data[i][j] = 0;
+
+ int ret = i * vect_len;
+
+ if (elements <= ret) elements = ret + 1;
+
+ mutex_unlock(&mutex);
+ return ret;
+ } else {
+ // Look for free space
+ for (int j = 0; j < vect_len; j++) {
+ if (data[i][j] == 0) {
+ data[i][j] = ptr;
+
+ int ret = i * vect_len + j;
+ if (elements <= ret) elements = ret + 1;
+
+ mutex_unlock(&mutex);
+ return ret;
+ }
+ }
+ }
+ }
+ // Nothing was allocated, we need MORE SPACE
+ T ***new_data = (T***)kmalloc((ref_vect_len + ref_vect_init_len) * sizeof(T**));
+ for (int i = 0; i < ref_vect_len; i++) {
+ new_data[i] = data[i];
+ }
+ new_data[ref_vect_len] = (T**)kmalloc(vect_len * sizeof(T*));
+ new_data[ref_vect_len][0] = ptr;
+ int ret = ref_vect_len * vect_len;
+ for (int i = 1; i < vect_len; i++) {
+ new_data[ref_vect_len][i] = 0;
+ }
+ for (int i = ref_vect_len + 1; i < ref_vect_len + ref_vect_init_len; i++) {
+ new_data[i] = 0;
+ }
+ kfree(data);
+ data = new_data;
+ ref_vect_len += ref_vect_init_len;
+
+ ASSERT(ret >= elements);
+ elements = ret + 1;
+
+ mutex_unlock(&mutex);
+ return ret;
+
+}
+
+template <typename T>
+T *earray<T>::at(int num) {
+ mutex_lock(&mutex);
+
+ int i = num / vect_len, j = num % vect_len;
+ if (i >= ref_vect_len || data[i] == 0) {
+ mutex_unlock(&mutex);
+ return 0;
+ }
+ void* ret = data[i][j];
+ mutex_unlock(&mutex);
+ return ret;
+}
+
+template <typename T>
+void earray<T>::set(int num, T* ptr) {
+ mutex_lock(&mutex);
+
+ int a = num / vect_len, b = num % vect_len, i, j;
+ if (a >= ref_vect_len) {
+ if (ptr == 0) {
+ mutex_unlock(&mutex);
+ return;
+ }
+ int new_vect_len = ref_vect_len;
+ while (a >= ref_vect_len) new_vect_len += ref_vect_init_len;
+
+ T ***new_data = (T***)kmalloc(new_vect_len * sizeof(T**));
+ for (i = 0; i < ref_vect_len; i++) {
+ new_data[i] = data[i];
+ }
+ for (i = ref_vect_len; i < new_vect_len; i++) {
+ new_data[i] = 0;
+ }
+ kfree(data);
+ data = new_data;
+ ref_vect_len = new_vect_len;
+ }
+ if (ptr == 0) {
+ if (data[a] != 0) {
+ if (data[a][b] != 0) {
+ data[a][b] = 0;
+ j = 1;
+ for (i = 0; i < vect_len; i++) {
+ if (data[a][i] != 0) j = 0;
+ }
+ if (j == 1) {
+ kfree(data[a]);
+ data[a] = 0;
+ }
+ }
+ }
+ } else {
+ if (data[a] = 0) {
+ data[a] = (T**)kmalloc(vect_len * sizeof(T*));
+ for (i = 0; i < vect_len; i++) data[a][i] = 0;
+ }
+ data[a][b] = ptr;
+
+ if (num >= elements) elements = num + 1;
+ }
+
+ mutex_unlock(&mutex);
+}
diff --git a/src/kernel/lib/earray.h b/src/kernel/lib/earray.h
new file mode 100644
index 0000000..b6d0a55
--- /dev/null
+++ b/src/kernel/lib/earray.h
@@ -0,0 +1,35 @@
+#ifndef DEF_EARRAY_H
+#define DEF_EARRAY_H
+
+#include <sched.h>
+
+/*
+ * This class implements a simple extensible array structure.
+ * An entry with a 0 value is considered free and can be allocated.
+ * The array will free as much space when elements are removed.
+ */
+
+template <typename T>
+struct earray {
+ private:
+ int ref_vect_init_len;
+ int vect_len; // NEVER CHANGE THIS AFTER INITIALISATION!!!!
+
+ int ref_vect_len;
+ int elements;
+ T ***data;
+
+ mutex_t mutex;
+
+ public:
+ earray(int refvectinitlen, int vectlen);
+ ~earray();
+
+ int add(T* ptr); // return element number or -1 if fail
+ T* at(int num); // returns 0 when nothing
+ void set(int num, T* ptr);
+};
+
+
+
+#endif