cache.cpp revision 8e2e6c9f8f2157e3ec6599f87343bdc453734c4c
/* $Id$ */
/** @file
* IPRT - Object cache
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/spinlock.h>
/**
* Create a cache for objects.
*
* @returns iprt status code.
* @param ppObjCache Where to store the pointer to the created cache.
* @param cElements Number of elements the cache can hold.
* 0 if unlimited size.
* @param cbElement Size of one element in bytes
* @param fProt Protection flags for protecting cache against concurrent access
* from different threads.
* RTOBJCACHE_PROTECT_REQUESTER to protect the request function.
* RTOBJCACHE_PROTECT_INSERT to protect the insert function.
*/
RTDECL(int) RTCacheCreate(PRTOBJCACHE *ppCache, uint32_t cElements, size_t cbElement, uint32_t fProt)
{
int rc = VINF_SUCCESS;
|| !cbElement
|| (fProt & ~RTOBJCACHE_PROTECT_VALID))
return VERR_INVALID_PARAMETER;
if (cElements > 0)
if (!pCacheNew)
return VERR_NO_MEMORY;
if (fProt & RTOBJCACHE_PROTECT_REQUEST)
{
if (RT_FAILURE(rc))
{
return rc;
}
}
if (fProt & RTOBJCACHE_PROTECT_INSERT)
{
if (RT_FAILURE(rc))
{
return rc;
}
}
/* Initialize array if cache is limited. */
{
pCacheNew->u.defined.cElementsInCache = 0;
pCacheNew->u.defined.cNextObjRead = 0;
pCacheNew->u.defined.cNextFreeSlotWrite = 0;
}
else
{
/* Unlimited cache - Create dummy element. */
if (!pDummy)
{
/* Cleanup. */
return VERR_NO_MEMORY;
}
}
if (RT_SUCCESS(rc))
return rc;
}
/**
* Destroy a cache freeing allocated memory.
*
* @returns iprt status code.
* @param pCache Pointer to the cache.
*/
{
/* Free all objects left in cache. */
{
while (pHdr)
{
}
}
else
{
{
pCache->u.defined.cNextObjRead++;
}
}
return VINF_SUCCESS;
}
/**
* Request an object from the cache.
*
* @returns iprt status
* VERR_CACHE_EMPTY if cache is not unlimited and there is no object left in cache.
* @param pCache Pointer to the cache to get an object from.
* @param ppObj Where to store the pointer to the object.
*/
{
{
{
}
else
{
/* We have to create a new cached object. - We can leave the spinlock safely here. */
if (!pObjNew)
return VERR_NO_MEMORY;
}
}
else
{
if (pCache->u.defined.cElementsInCache > 0)
{
pCache->u.defined.cNextObjRead++;
}
else
{
return VERR_CACHE_EMPTY;
}
}
return VINF_SUCCESS;
}
/**
* Insert an object into the cache.
*
* @returns iprt status code.
* VERR_CACHE_FULL if cache is not unlimited and there is no free entry left in cache.
* @param pCache Pointer to the cache.
* @param pObj Pointer to the object to insert.
*/
{
int rc = VINF_SUCCESS;
{
}
else
{
else
{
pCache->u.defined.cNextFreeSlotWrite++;
}
}
return rc;
}