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