1*1bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2c0346845SJens Wiklander /* 3c0346845SJens Wiklander * Copyright (c) 2014, Linaro Limited 4c0346845SJens Wiklander * All rights reserved. 5c0346845SJens Wiklander * 6c0346845SJens Wiklander * Redistribution and use in source and binary forms, with or without 7c0346845SJens Wiklander * modification, are permitted provided that the following conditions are met: 8c0346845SJens Wiklander * 9c0346845SJens Wiklander * 1. Redistributions of source code must retain the above copyright notice, 10c0346845SJens Wiklander * this list of conditions and the following disclaimer. 11c0346845SJens Wiklander * 12c0346845SJens Wiklander * 2. Redistributions in binary form must reproduce the above copyright notice, 13c0346845SJens Wiklander * this list of conditions and the following disclaimer in the documentation 14c0346845SJens Wiklander * and/or other materials provided with the distribution. 15c0346845SJens Wiklander * 16c0346845SJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17c0346845SJens Wiklander * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18c0346845SJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19c0346845SJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20c0346845SJens Wiklander * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21c0346845SJens Wiklander * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22c0346845SJens Wiklander * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23c0346845SJens Wiklander * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24c0346845SJens Wiklander * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25c0346845SJens Wiklander * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26c0346845SJens Wiklander * POSSIBILITY OF SUCH DAMAGE. 27c0346845SJens Wiklander */ 28c0346845SJens Wiklander #include <stdlib.h> 29c0346845SJens Wiklander #include <string.h> 30c0346845SJens Wiklander #include <kernel/handle.h> 31c0346845SJens Wiklander 32c0346845SJens Wiklander /* 33c0346845SJens Wiklander * Define the initial capacity of the database. It should be a low number 34c0346845SJens Wiklander * multiple of 2 since some databases a likely to only use a few handles. 35c0346845SJens Wiklander * Since the algorithm is to doubles up when growing it shouldn't cause a 36c0346845SJens Wiklander * noticable overhead on large databases. 37c0346845SJens Wiklander */ 38c0346845SJens Wiklander #define HANDLE_DB_INITIAL_MAX_PTRS 4 39c0346845SJens Wiklander 40c0346845SJens Wiklander void handle_db_destroy(struct handle_db *db) 41c0346845SJens Wiklander { 42c0346845SJens Wiklander if (db) { 43c0346845SJens Wiklander free(db->ptrs); 44c0346845SJens Wiklander db->ptrs = NULL; 45c0346845SJens Wiklander db->max_ptrs = 0; 46c0346845SJens Wiklander } 47c0346845SJens Wiklander } 48c0346845SJens Wiklander 49c0346845SJens Wiklander int handle_get(struct handle_db *db, void *ptr) 50c0346845SJens Wiklander { 51c0346845SJens Wiklander size_t n; 52c0346845SJens Wiklander void *p; 53c0346845SJens Wiklander size_t new_max_ptrs; 54c0346845SJens Wiklander 55c0346845SJens Wiklander if (!db || !ptr) 56c0346845SJens Wiklander return -1; 57c0346845SJens Wiklander 58c0346845SJens Wiklander /* Try to find an empty location */ 59c0346845SJens Wiklander for (n = 0; n < db->max_ptrs; n++) { 60c0346845SJens Wiklander if (!db->ptrs[n]) { 61c0346845SJens Wiklander db->ptrs[n] = ptr; 62c0346845SJens Wiklander return n; 63c0346845SJens Wiklander } 64c0346845SJens Wiklander } 65c0346845SJens Wiklander 66c0346845SJens Wiklander /* No location available, grow the ptrs array */ 67c0346845SJens Wiklander if (db->max_ptrs) 68c0346845SJens Wiklander new_max_ptrs = db->max_ptrs * 2; 69c0346845SJens Wiklander else 70c0346845SJens Wiklander new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; 71c0346845SJens Wiklander p = realloc(db->ptrs, new_max_ptrs * sizeof(void *)); 72c0346845SJens Wiklander if (!p) 73c0346845SJens Wiklander return -1; 74c0346845SJens Wiklander db->ptrs = p; 75c0346845SJens Wiklander memset(db->ptrs + db->max_ptrs, 0, 76c0346845SJens Wiklander (new_max_ptrs - db->max_ptrs) * sizeof(void *)); 77c0346845SJens Wiklander db->max_ptrs = new_max_ptrs; 78c0346845SJens Wiklander 79c0346845SJens Wiklander /* Since n stopped at db->max_ptrs there is an empty location there */ 80c0346845SJens Wiklander db->ptrs[n] = ptr; 81c0346845SJens Wiklander return n; 82c0346845SJens Wiklander } 83c0346845SJens Wiklander 84c0346845SJens Wiklander void *handle_put(struct handle_db *db, int handle) 85c0346845SJens Wiklander { 86c0346845SJens Wiklander void *p; 87c0346845SJens Wiklander 88c0346845SJens Wiklander if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) 89c0346845SJens Wiklander return NULL; 90c0346845SJens Wiklander 91c0346845SJens Wiklander p = db->ptrs[handle]; 92c0346845SJens Wiklander db->ptrs[handle] = NULL; 93c0346845SJens Wiklander return p; 94c0346845SJens Wiklander } 95c0346845SJens Wiklander 96c0346845SJens Wiklander void *handle_lookup(struct handle_db *db, int handle) 97c0346845SJens Wiklander { 98c0346845SJens Wiklander if (!db || handle < 0 || (size_t)handle >= db->max_ptrs) 99c0346845SJens Wiklander return NULL; 100c0346845SJens Wiklander 101c0346845SJens Wiklander return db->ptrs[handle]; 102c0346845SJens Wiklander } 103