1/* 2 * Copyright 2016, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(D61_BSD) 11 */ 12 13#include <stdio.h> 14#include <assert.h> 15#include <errno.h> 16#include <data_struct/coat.h> 17 18void coat_init(coat_t *t, int start, int end) { 19 assert(t); 20 assert(start != 0); /* zero idx is reserved. */ 21 cpool_init(&t->pool, start, end); 22 cvector_init(&t->table); 23} 24 25void coat_release(coat_t *t) { 26 assert(t); 27 size_t count = cvector_count(&t->table); 28 for (int i = 0; i < count; i++) { 29 cvector_item_t obj = cvector_get(&t->table, i); 30 if (!obj) continue; 31 if (t->oat_delete) { 32 t->oat_delete(t, obj); 33 } 34 } 35 cvector_free(&t->table); 36 cpool_release(&t->pool); 37} 38 39int coat_alloc(coat_t *t, uint32_t arg[COAT_ARGS], cvector_item_t *out_obj) { 40 assert(t); 41 42 // Allocate new ID. 43 int id = cpool_alloc(&t->pool); 44 if (!id || id == COAT_INVALID_ID) { 45 goto error; 46 } 47 48 // Potentially expand ID table vector. 49 while (cvector_count(&t->table) <= id) { 50 if (t->oat_expand) { 51 t->oat_expand(&t->table); 52 continue; 53 } 54 // Defaults to adding NULL pointers to fill ID table. 55 cvector_add(&t->table, (cvector_item_t) NULL); 56 } 57 58 cvector_item_t obj = cvector_get(&t->table, id); 59 if (!obj && t->oat_create) { 60 // Create object structure and store it. 61 obj = t->oat_create(t, id, arg); 62 if (!obj) { 63 goto error; 64 } 65 cvector_set(&t->table, id, obj); 66 } 67 68 if (out_obj) { 69 (*out_obj) = obj; 70 } 71 72 return id; 73 74error: 75 if (id) cpool_free(&t->pool, id); 76 return COAT_INVALID_ID; 77} 78 79cvector_item_t coat_get(coat_t *t, int id) { 80 if (!t || id < t->pool.start || id >= t->pool.end || id >= cvector_count(&t->table)) { 81 return (cvector_item_t) NULL; 82 } 83 return cvector_get(&t->table, id); 84} 85 86int coat_free(coat_t *t, int id) { 87 assert(t); 88 if (cpool_check(&t->pool, id)) { 89 // Free but should have been allocated. 90 return -EBADF; 91 } 92 if (t->oat_delete) { 93 cvector_item_t obj = coat_get(t, id); 94 if (!obj) { 95 // No such object. 96 return -EBADF; 97 } 98 t->oat_delete(t, obj); 99 } 100 cvector_set(&t->table, id, (cvector_item_t) NULL); 101 cpool_free(&t->pool, id); 102 return 0; 103} 104