handletable.cpp revision c9968c45b31bd2bf5bb6feb365f86ffba15241d7
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * IPRT - Handle Tables.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
9019681d4e9b8399b951793a9dd92b63c195e0eevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * available from http://www.virtualbox.org. This file is free software;
92a27575521748a392dcd1b996fce55b87411a00vboxsync * you can redistribute it and/or modify it under the terms of the GNU
92a27575521748a392dcd1b996fce55b87411a00vboxsync * General Public License (GPL) as published by the Free Software
92a27575521748a392dcd1b996fce55b87411a00vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
92a27575521748a392dcd1b996fce55b87411a00vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
92a27575521748a392dcd1b996fce55b87411a00vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
92a27575521748a392dcd1b996fce55b87411a00vboxsync * The contents of this file may alternatively be used under the terms
92a27575521748a392dcd1b996fce55b87411a00vboxsync * of the Common Development and Distribution License Version 1.0
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * VirtualBox OSE distribution, in which case the provisions of the
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * CDDL are applicable instead of those of the GPL.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * You may elect to license modified versions of this file under the
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * terms and conditions of either the GPL or the CDDL or both.
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * additional information or have any questions.
10cdf5733351fdcd857d439ca32189e812f18682vboxsync/*******************************************************************************
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync* Header Files *
10cdf5733351fdcd857d439ca32189e812f18682vboxsync*******************************************************************************/
10cdf5733351fdcd857d439ca32189e812f18682vboxsyncRTDECL(int) RTHandleTableCreateEx(PRTHANDLETABLE phHandleTable, uint32_t fFlags, uint32_t uBase, uint32_t cMax,
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * Validate input.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync AssertPtrReturn(phHandleTable, VERR_INVALID_POINTER);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync AssertPtrNullReturn(pfnRetain, VERR_INVALID_POINTER);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync AssertReturn(!(fFlags & ~RTHANDLETABLE_FLAGS_MASK), VERR_INVALID_PARAMETER);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync AssertReturn(UINT32_MAX - cMax >= uBase, VERR_INVALID_PARAMETER);
cd9e4940318086a06a68bf301960563dcb72b939vboxsync * Adjust the cMax value so it is a multiple of the 2nd level tables.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync cMax = ((cMax + RTHT_LEVEL2_ENTRIES - 1) / RTHT_LEVEL2_ENTRIES) * RTHT_LEVEL2_ENTRIES;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Allocate the structure, include the 1st level lookup table
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * if it's below the threshold size.
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync cb = RT_ALIGN(cb, sizeof(void *)) + cLevel1 * sizeof(void *);
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync * Initialize it.
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync pThis->papvLevel1 = (void **)((uint8_t *)pThis + RT_ALIGN(sizeof(*pThis), sizeof(void *)));
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync pThis->cLevel1 = cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD ? cLevel1 : 0;
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncRTDECL(int) RTHandleTableCreate(PRTHANDLETABLE phHandleTable)
360c39d88dfa26b17181b57ebafdb24c2a113c63vboxsync return RTHandleTableCreateEx(phHandleTable, RTHANDLETABLE_FLAGS_LOCKED, 1, 65534, NULL, NULL);
360c39d88dfa26b17181b57ebafdb24c2a113c63vboxsyncRTDECL(int) RTHandleTableDestroy(RTHANDLETABLE hHandleTable, PFNRTHANDLETABLEDELETE pfnDelete, void *pvUser)
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync * Validate input, quitely ignore the NIL handle.
7b213bb002950f9fcf809f605cc584fa543481advboxsync AssertReturn(pThis->u32Magic == RTHANDLETABLE_MAGIC, VERR_INVALID_HANDLE);
7b213bb002950f9fcf809f605cc584fa543481advboxsync AssertPtrNullReturn(pfnDelete, VERR_INVALID_POINTER);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Mark the thing as invalid / deleted.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Then kill the lock.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ASMAtomicWriteU32(&pThis->u32Magic, ~RTHANDLETABLE_MAGIC);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Walk all the tables looking for used handles.
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync for (i1 = 0; cLeft > 0 && i1 < pThis->cLevel1; i1++)
b49952fd6cae765238f4760c700c5ef797a56092vboxsync PRTHTENTRYCTX paTable = (PRTHTENTRYCTX)pThis->papvLevel1[i1];
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync for (i = 0; i < RTHT_LEVEL2_ENTRIES; i++)
f9e9ec581188b7f7645e3dea5bafa77cfcec31efvboxsync pfnDelete(hHandleTable, pThis->uBase + i + i1 * RTHT_LEVEL2_ENTRIES,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync for (i1 = 0; cLeft > 0 && i1 < pThis->cLevel1; i1++)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync PRTHTENTRY paTable = (PRTHTENTRY)pThis->papvLevel1[i1];
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync for (i = 0; i < RTHT_LEVEL2_ENTRIES; i++)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync pfnDelete(hHandleTable, pThis->uBase + i + i1 * RTHT_LEVEL2_ENTRIES,
c7a92d481aced08517570d43bf75e2a9f3a8aaeavboxsync * Free the memory.