blob: a17e823293922aa2a9e6554ec898e533005354b5 (
plain) (
tree)
|
|
#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);
}
|