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) 18 { 19 if (db) { 20 free(db->ptrs); 21 db->ptrs = NULL; 22 db->max_ptrs = 0; 23 } 24 } 25 26 int handle_get(struct handle_db *db, void *ptr) 27 { 28 size_t n; 29 void *p; 30 size_t new_max_ptrs; 31 32 if (!db || !ptr) 33 return -1; 34 35 /* Try to find an empty location */ 36 for (n = 0; n < db->max_ptrs; n++) { 37 if (!db->ptrs[n]) { 38 db->ptrs[n] = ptr; 39 return n; 40 } 41 } 42 43 /* No location available, grow the ptrs array */ 44 if (db->max_ptrs) 45 new_max_ptrs = db->max_ptrs * 2; 46 else 47 new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; 48 p = realloc(db->ptrs, new_max_ptrs * sizeof(void *)); 49 if (!p) 50 return -1; 51 db->ptrs = p; 52 memset(db->ptrs + db->max_ptrs, 0, 53 (new_max_ptrs - db->max_ptrs) * sizeof(void *)); 54 db->max_ptrs = new_max_ptrs; 55 56 /* Since n stopped at db->max_ptrs there is an empty location there */ 57 db->ptrs[n] = ptr; 58 return n; 59 } 60 61 void *handle_put(struct handle_db *db, int handle) 62 { 63 void *p; 64 65 if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) 66 return NULL; 67 68 p = db->ptrs[handle]; 69 db->ptrs[handle] = NULL; 70 return p; 71 } 72 73 void *handle_lookup(struct handle_db *db, int handle) 74 { 75 if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) 76 return NULL; 77 78 return db->ptrs[handle]; 79 } 80