diff options
Diffstat (limited to 'src/kernel/lib/earray.c')
-rw-r--r-- | src/kernel/lib/earray.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/kernel/lib/earray.c b/src/kernel/lib/earray.c new file mode 100644 index 0000000..a17e823 --- /dev/null +++ b/src/kernel/lib/earray.c @@ -0,0 +1,156 @@ +#include "earray.h" + +#include <mem/mem.h> +#include <core/sys.h> + +void earray_init(struct earray *array) { + int i; + + if (array->data != 0) return; + + array->ref_vect_len = array->ref_vect_init_len; + array->elements = 0; + array->mutex = MUTEX_UNLOCKED; + + array->data = kmalloc(array->ref_vect_len * sizeof(void***)); + + for (i = 0; i < array->ref_vect_len; i++) { + array->data[i] = 0; + } +} + +void earray_free(struct earray *array) { + int i; + + mutex_lock(&array->mutex); + + for (i = 0; i < array->ref_vect_len; i++) { + if (array->data[i] != 0) kfree(array->data[i]); + } + kfree(array->data); + array->data = 0; + + //no need to unlock, the structure is never to be used again +} + +int earray_add(struct earray *array, void *ptr) { + if (ptr == 0) return -1; + + mutex_lock(&array->mutex); + + int i, j; + + for (i = 0; i < array->ref_vect_len; i++) { + if (array->data[i] == 0) { + // Allocate here + array->data[i] = kmalloc(array->vect_len * sizeof(void**)); + array->data[i][0] = ptr; + for (j = 1; j < array->vect_len; j++) array->data[i][j] = 0; + + j = i * array->vect_len; //ret val + + if (array->elements <= j) array->elements = j + 1; + + mutex_unlock(&array->mutex); + return j; + } else { + // Look for free space + for (j = 0; j < array->vect_len; j++) { + if (array->data[i][j] == 0) { + array->data[i][j] = ptr; + + j = i * array->vect_len + j; // ret val + if (array->elements <= j) array->elements = j + 1; + + mutex_unlock(&array->mutex); + return j; + } + } + } + } + // Nothing was allocated, we need MORE SPACE + void ***new_data = kmalloc(array->ref_vect_len + array->ref_vect_init_len); + for (i = 0; i < array->ref_vect_len; i++) { + new_data[i] = array->data[i]; + } + new_data[array->ref_vect_len] = kmalloc(array->vect_len * sizeof(void**)); + new_data[array->ref_vect_len][0] = ptr; + j = array->ref_vect_len * array->vect_len; // j = return value + for (i = 1; i < array->vect_len; i++) { + new_data[array->ref_vect_len][i] = 0; + } + for (i = array->ref_vect_len + 1; i < array->ref_vect_len + array->ref_vect_init_len; i++) { + new_data[i] = 0; + } + kfree(array->data); + array->data = new_data; + array->ref_vect_len += array->ref_vect_init_len; + + ASSERT(j >= array->elements); + array->elements = j + 1; + + mutex_unlock(&array->mutex); + return j; + +} + +void *earray_at(struct earray *array, int num) { + mutex_lock(&array->mutex); + + int i = num / array->vect_len, j = num % array->vect_len; + if (i >= array->ref_vect_len || array->data[i] == 0) return 0; + void* ret = array->data[i][j]; + + mutex_unlock(&array->mutex); + return ret; +} + +void earray_set(struct earray *array, int num, void* ptr) { + mutex_lock(&array->mutex); + + int a = num / array->vect_len, b = num % array->vect_len, i, j; + if (a >= array->ref_vect_len) { + if (ptr == 0) { + mutex_unlock(&array->mutex); + return; + } + int new_vect_len = array->ref_vect_len; + while (a >= array->ref_vect_len) new_vect_len += array->ref_vect_init_len; + + void ***new_data = kmalloc(new_vect_len * sizeof(void***)); + for (i = 0; i < array->ref_vect_len; i++) { + new_data[i] = array->data[i]; + } + for (i = array->ref_vect_len; i < new_vect_len; i++) { + new_data[i] = 0; + } + kfree(array->data); + array->data = new_data; + array->ref_vect_len = new_vect_len; + } + if (ptr == 0) { + if (array->data[a] != 0) { + if (array->data[a][b] != 0) { + array->data[a][b] = 0; + j = 1; + for (i = 0; i < array->vect_len; i++) { + if (array->data[a][i] != 0) j = 0; + } + if (j == 1) { + kfree(array->data[a]); + array->data[a] = 0; + } + } + } + } else { + if (array->data[a] = 0) { + array->data[a] = kmalloc(array->vect_len * sizeof(void**)); + for (i = 0; i < array->vect_len; i++) array->data[a][i] = 0; + } + array->data[a][b] = ptr; + + if (num >= array->elements) array->elements = num + 1; + } + + mutex_unlock(&array->mutex); +} |