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