#include "earray.h" #include #include 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); }