1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, Linaro Limited 4 */ 5 #include <stdlib.h> 6 #include <string.h> 7 #include <kernel/handle.h> 8 9 /* 10 * Define the initial capacity of the database. It should be a low number 11 * multiple of 2 since some databases a likely to only use a few handles. 12 * Since the algorithm is to doubles up when growing it shouldn't cause a 13 * noticable overhead on large databases. 14 */ 15 #define HANDLE_DB_INITIAL_MAX_PTRS 4 16 17 void handle_db_destroy(struct handle_db *db, void (*ptr_destructor)(void *ptr)) 18 { 19 if (db) { 20 if (ptr_destructor) { 21 size_t n = 0; 22 23 for (n = 0; n < db->max_ptrs; n++) 24 if (db->ptrs[n]) 25 ptr_destructor(db->ptrs[n]); 26 } 27 free(db->ptrs); 28 db->ptrs = NULL; 29 db->max_ptrs = 0; 30 } 31 } 32 33 int handle_get(struct handle_db *db, void *ptr) 34 { 35 size_t n; 36 void *p; 37 size_t new_max_ptrs; 38 39 if (!db || !ptr) 40 return -1; 41 42 /* Try to find an empty location */ 43 for (n = 0; n < db->max_ptrs; n++) { 44 if (!db->ptrs[n]) { 45 db->ptrs[n] = ptr; 46 return n; 47 } 48 } 49 50 /* No location available, grow the ptrs array */ 51 if (db->max_ptrs) 52 new_max_ptrs = db->max_ptrs * 2; 53 else 54 new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; 55 p = realloc(db->ptrs, new_max_ptrs * sizeof(void *)); 56 if (!p) 57 return -1; 58 db->ptrs = p; 59 memset(db->ptrs + db->max_ptrs, 0, 60 (new_max_ptrs - db->max_ptrs) * sizeof(void *)); 61 db->max_ptrs = new_max_ptrs; 62 63 /* Since n stopped at db->max_ptrs there is an empty location there */ 64 db->ptrs[n] = ptr; 65 return n; 66 } 67 68 void *handle_put(struct handle_db *db, int handle) 69 { 70 void *p; 71 72 if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) 73 return NULL; 74 75 p = db->ptrs[handle]; 76 db->ptrs[handle] = NULL; 77 return p; 78 } 79 80 void *handle_lookup(struct handle_db *db, int handle) 81 { 82 if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) 83 return NULL; 84 85 return db->ptrs[handle]; 86 } 87