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