e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Copyright (c) 2001, Stanford University
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * All rights reserved
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * See the file LICENSE.txt for information on redistributing this software.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_threads.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_hash.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_mem.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_error.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync#include <iprt/list.h>
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define CR_MAXUINT ((GLuint) 0xFFFFFFFF)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync#define CR_HASH_ID_MIN ((GLuint)1)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync#define CR_HASH_ID_MAX CR_MAXUINT
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define CR_NUM_BUCKETS 1047
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct FreeElemRec {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTLISTNODE Node;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint min;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint max;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} FreeElem;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
6da9a3ab01fd6e1c285c7c2a79ac831390e03bb4vboxsyncstruct CRHashIdPool {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTLISTNODE freeList;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync GLuint min;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync GLuint max;
6da9a3ab01fd6e1c285c7c2a79ac831390e03bb4vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct CRHashNode {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned long key;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync void *data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync struct CRHashNode *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} CRHashNode;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstruct CRHashTable {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int num_elements;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *buckets[CR_NUM_BUCKETS];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashIdPool *idPool;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmutex mutex;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsyncCRHashIdPool *crAllocHashIdPoolEx( GLuint min, GLuint max )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync CRHashIdPool *pool;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync FreeElem *elem;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync if (min < CR_HASH_ID_MIN || max > CR_HASH_ID_MAX || min >= max)
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync {
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync crWarning("invalid min man vals");
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync return NULL;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync }
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync pool = (CRHashIdPool *) crCalloc(sizeof(CRHashIdPool));
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync elem = (FreeElem *) crCalloc(sizeof(FreeElem));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListInit(&pool->freeList);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync elem->min = min;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync elem->max = max;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListAppend(&pool->freeList, &elem->Node);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync pool->min = min;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync pool->max = max;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return pool;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsyncCRHashIdPool *crAllocHashIdPool( void )
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync{
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync return crAllocHashIdPoolEx( CR_HASH_ID_MIN, CR_HASH_ID_MAX );
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync}
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync
e85b92d4df013df97a72864a412eb94eb3f70acevboxsyncvoid crFreeHashIdPool( CRHashIdPool *pool )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync FreeElem *i, *next;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEachSafe(&pool->freeList, i, next, FreeElem, Node)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(i);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(pool);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync#ifdef DEBUG_misha
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsyncstatic void crHashIdPoolDbgCheckConsistency(CRHashIdPool *pool)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync{
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *i;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync GLuint min = 0;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* null is a special case, it is always treated as allocated */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(!crHashIdPoolIsIdFree(pool, 0));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* first ensure entries have correct values */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEach(&pool->freeList, i, FreeElem, Node)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync Assert(i->min >= pool->min);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync Assert(i->max <= pool->max);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(i->min < i->max);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* now ensure entries do not intersect */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* and that they are sorted */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEach(&pool->freeList, i, FreeElem, Node)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(min < i->min);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync min = i->max;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync}
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsyncstatic void crHashIdPoolDbgCheckUsed( const CRHashIdPool *pool, GLuint start, GLuint count, GLboolean fUsed )
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync{
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync GLuint i;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CRASSERT(count);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync CRASSERT(start >= pool->min);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync CRASSERT(start + count <= pool->max);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CRASSERT(start + count > start);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync for (i = 0; i < count; ++i)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(!fUsed == !!crHashIdPoolIsIdFree( pool, start + i ));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync}
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync# define CR_HASH_IDPOOL_DBG_CHECK_USED(_p, _start, _count, _used) do { \
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync crHashIdPoolDbgCheckConsistency((_p)); \
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync crHashIdPoolDbgCheckUsed( (_p), (_start), (_count), (_used) ); \
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync } while (0)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync# define CR_HASH_IDPOOL_DBG_CHECK_CONSISTENCY(_p) do { crHashIdPoolDbgCheckConsistency((_p)); } while (0)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync#else
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync# define CR_HASH_IDPOOL_DBG_CHECK_USED(_p, _start, _count, _used) do { } while (0)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync# define CR_HASH_IDPOOL_DBG_CHECK_CONSISTENCY(_p) do { } while (0)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync#endif
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Allocate a block of <count> IDs. Return index of first one.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Return 0 if we fail.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e85b92d4df013df97a72864a412eb94eb3f70acevboxsyncGLuint crHashIdPoolAllocBlock( CRHashIdPool *pool, GLuint count )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *f, *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint ret;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(count > 0);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEachSafe(&pool->freeList, f, next, FreeElem, Node)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(f->max > f->min);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->max - f->min >= (GLuint) count)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* found a sufficiently large enough block */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ret = f->min;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f->min += count;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (f->min == f->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListNodeRemove(&f->Node);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(f);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, ret, count, GL_TRUE);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return ret;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* failed to find free block */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync crWarning("crHashIdPoolAllocBlock failed");
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_CONSISTENCY(pool);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Free a block of <count> IDs starting at <first>.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e85b92d4df013df97a72864a412eb94eb3f70acevboxsyncvoid crHashIdPoolFreeBlock( CRHashIdPool *pool, GLuint first, GLuint count )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *f;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync GLuint last;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync GLuint newMax;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *cur, *curNext;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* null is a special case, it is always treated as allocated */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (!first)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(!crHashIdPoolIsIdFree(pool, 0));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync ++first;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync --count;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (!count)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync last = first + count;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CRASSERT(count > 0);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CRASSERT(last > first);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync CRASSERT(first >= pool->min);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync CRASSERT(last <= pool->max);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* the id list is sorted, first find a place to insert */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEach(&pool->freeList, f, FreeElem, Node)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(f->max > f->min);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->max < first)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync continue;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->min > last)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* we are here because first is > than prevEntry->max
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync * otherwise the previous loop iterations should handle that */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *elem = (FreeElem *) crCalloc(sizeof(FreeElem));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync elem->min = first;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync elem->max = last;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListNodeInsertBefore(&f->Node, &elem->Node);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, first, count, GL_FALSE);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* now we have f->min <= last and f->max >= first,
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync * so we have either intersection */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->min > first)
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync f->min = first; /* first is guaranteed not to touch any prev regions */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync newMax = last;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->max >= last)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, first, count, GL_FALSE);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync for (cur = RTListNodeGetNext(&f->Node, FreeElem, Node),
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync curNext = RT_FROM_MEMBER(cur->Node.pNext, FreeElem, Node);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync !RTListNodeIsDummy(&pool->freeList, cur, FreeElem, Node);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync cur = curNext,
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync curNext = RT_FROM_MEMBER((cur)->Node.pNext, FreeElem, Node) )
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (cur->min > last)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync newMax = cur->max;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListNodeRemove(&cur->Node);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync crFree(cur);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (newMax >= last)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync f->max = newMax;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, first, count, GL_FALSE);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* we are here because either the list is empty or because all list rande elements have smaller values */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync f = (FreeElem *) crCalloc(sizeof(FreeElem));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync f->min = first;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync f->max = last;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListAppend(&pool->freeList, &f->Node);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, first, count, GL_FALSE);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Mark the given Id as being allocated.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e85b92d4df013df97a72864a412eb94eb3f70acevboxsyncGLboolean crHashIdPoolAllocId( CRHashIdPool *pool, GLuint id )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *f, *next;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (!id)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* null is a special case, it is always treated as allocated */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(!crHashIdPoolIsIdFree(pool, 0));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return GL_FALSE;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync// Assert(id != 2);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEachSafe(&pool->freeList, f, next, FreeElem, Node)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->max <= id)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync continue;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->min > id)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, id, 1, GL_TRUE);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return GL_FALSE;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync /* f->min <= id && f->max > id */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (id > f->min)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (id + 1 < f->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *elem = (FreeElem *) crCalloc(sizeof(FreeElem));
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync elem->min = id + 1;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync elem->max = f->max;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListNodeInsertAfter(&f->Node, &elem->Node);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync f->max = id;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, id, 1, GL_TRUE);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync else
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync Assert(id == f->min);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (id + 1 < f->max)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync f->min = id + 1;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, id, 1, GL_TRUE);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListNodeRemove(&f->Node);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync crFree(f);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, id, 1, GL_TRUE);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, id, 1, GL_TRUE);
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return GL_TRUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* if we get here, the ID was already allocated - that's OK */
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync CR_HASH_IDPOOL_DBG_CHECK_USED(pool, id, 1, GL_TRUE);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync return GL_FALSE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Determine if the given id is free. Return GL_TRUE if so.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e85b92d4df013df97a72864a412eb94eb3f70acevboxsyncGLboolean crHashIdPoolIsIdFree( const CRHashIdPool *pool, GLuint id )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync FreeElem *f;
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync CRASSERT(id <= pool->max);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync RTListForEach(&pool->freeList, f, FreeElem, Node)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->max <= id)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync continue;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync if (f->min > id)
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return GL_FALSE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return GL_TRUE;
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync }
fc930724d0ba1ec3d2ae3f27c5c019e0e8d828e5vboxsync return GL_FALSE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
bff361262f6f9bda1094fc5f754259b8e0404718vboxsyncvoid crHashIdWalkKeys( CRHashIdPool *pool, CRHashIdWalkKeys walkFunc , void *data)
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync{
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync FreeElem *prev = NULL, *f;
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync RTListForEach(&pool->freeList, f, FreeElem, Node)
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync {
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync if (prev)
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync {
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync Assert(prev->max < f->min);
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync walkFunc(prev->max+1, f->min - prev->max, data);
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync }
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync else if (f->min > pool->min)
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync {
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync walkFunc(pool->min, f->min - pool->min, data);
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync }
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync prev = f;
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync }
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync Assert(prev->max <= pool->max);
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync if (prev->max < pool->max)
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync {
4252e037570a3c8d943552edb7858c9889aaca1dvboxsync walkFunc(prev->max+1, pool->max - prev->max, data);
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync }
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync}
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsyncCRHashTable *crAllocHashtableEx( GLuint min, GLuint max )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashTable *hash = (CRHashTable *) crCalloc( sizeof( CRHashTable )) ;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync hash->num_elements = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0 ; i < CR_NUM_BUCKETS ; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync hash->buckets[i] = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync hash->idPool = crAllocHashIdPoolEx( min, max );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crInitMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return hash;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsyncCRHashTable *crAllocHashtable( void )
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync{
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync return crAllocHashtableEx(CR_HASH_ID_MIN, CR_HASH_ID_MAX);
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync}
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crFreeHashtable( CRHashTable *hash, CRHashtableCallback deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync CRHashNode *entry, *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !hash) return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( i = 0; i < CR_NUM_BUCKETS; i++ )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync entry = hash->buckets[i];
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync while (entry)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync next = entry->next;
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync /* Clear the key in case crHashtableDelete() is called
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync * from this callback.
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync */
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync entry->key = 0;
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync if (deleteFunc && entry->data)
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync {
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync (*deleteFunc)(entry->data);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync crFree(entry);
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync entry = next;
a71e6c1227f7f096f49c60514542b47e168c4ea4vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFreeHashIdPool( hash->idPool );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFreeMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( hash );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
19316fa5e707a23324c91b47aebf8697362428b3vboxsyncvoid crHashtableLock(CRHashTable *h)
19316fa5e707a23324c91b47aebf8697362428b3vboxsync{
19316fa5e707a23324c91b47aebf8697362428b3vboxsync#ifdef CHROMIUM_THREADSAFE
19316fa5e707a23324c91b47aebf8697362428b3vboxsync crLockMutex(&h->mutex);
19316fa5e707a23324c91b47aebf8697362428b3vboxsync#endif
19316fa5e707a23324c91b47aebf8697362428b3vboxsync}
19316fa5e707a23324c91b47aebf8697362428b3vboxsync
19316fa5e707a23324c91b47aebf8697362428b3vboxsyncvoid crHashtableUnlock(CRHashTable *h)
19316fa5e707a23324c91b47aebf8697362428b3vboxsync{
19316fa5e707a23324c91b47aebf8697362428b3vboxsync#ifdef CHROMIUM_THREADSAFE
19316fa5e707a23324c91b47aebf8697362428b3vboxsync crUnlockMutex(&h->mutex);
19316fa5e707a23324c91b47aebf8697362428b3vboxsync#endif
19316fa5e707a23324c91b47aebf8697362428b3vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsyncvoid crHashtableWalkUnlocked( CRHashTable *hash, CRHashtableWalkCallback walkFunc , void *dataPtr2)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *entry, *next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i < CR_NUM_BUCKETS; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = hash->buckets[i];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (entry)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* save next ptr here, in case walkFunc deletes this entry */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync next = entry->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (entry->data && walkFunc) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (*walkFunc)( entry->key, entry->data, dataPtr2 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync}
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsyncvoid crHashtableWalk( CRHashTable *hash, CRHashtableWalkCallback walkFunc , void *dataPtr2)
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync{
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync if (!hash)
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync return;
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync#ifdef CHROMIUM_THREADSAFE
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync crLockMutex(&hash->mutex);
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync#endif
bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19vboxsync crHashtableWalkUnlocked(hash, walkFunc , dataPtr2);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&hash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic unsigned int crHash( unsigned long key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return key % CR_NUM_BUCKETS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableAdd( CRHashTable *h, unsigned long key, void *data )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *node = (CRHashNode *) crCalloc( sizeof( CRHashNode ) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync node->key = key;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync node->data = data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync node->next = h->buckets[crHash( key )];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync h->buckets[ crHash( key ) ] = node;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync h->num_elements++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashIdPoolAllocId (h->idPool, key);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
ebc248f21b276416f76e20da3add001aff9fc30avboxsyncGLboolean crHashtableAllocRegisterKey( CRHashTable *h, GLuint key)
ebc248f21b276416f76e20da3add001aff9fc30avboxsync{
ebc248f21b276416f76e20da3add001aff9fc30avboxsync GLboolean fAllocated;
ebc248f21b276416f76e20da3add001aff9fc30avboxsync#ifdef CHROMIUM_THREADSAFE
ebc248f21b276416f76e20da3add001aff9fc30avboxsync crLockMutex(&h->mutex);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync#endif
ebc248f21b276416f76e20da3add001aff9fc30avboxsync fAllocated = crHashIdPoolAllocId (h->idPool, key);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync#ifdef CHROMIUM_THREADSAFE
ebc248f21b276416f76e20da3add001aff9fc30avboxsync crUnlockMutex(&h->mutex);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync#endif
ebc248f21b276416f76e20da3add001aff9fc30avboxsync return fAllocated;
ebc248f21b276416f76e20da3add001aff9fc30avboxsync}
ebc248f21b276416f76e20da3add001aff9fc30avboxsync
bff361262f6f9bda1094fc5f754259b8e0404718vboxsyncvoid crHashtableWalkKeys( CRHashTable *h, CRHashIdWalkKeys walkFunc , void *data)
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync{
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync#ifdef CHROMIUM_THREADSAFE
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync crLockMutex(&h->mutex);
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync#endif
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync crHashIdWalkKeys(h->idPool, walkFunc , data);
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync#ifdef CHROMIUM_THREADSAFE
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync crUnlockMutex(&h->mutex);
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync#endif
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync}
bff361262f6f9bda1094fc5f754259b8e0404718vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLuint crHashtableAllocKeys( CRHashTable *h, GLsizei range)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint res;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync res = crHashIdPoolAllocBlock (h->idPool, range);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync#ifdef DEBUG_misha
ebc248f21b276416f76e20da3add001aff9fc30avboxsync Assert(res);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync for (i = 0; i < range; ++i)
ebc248f21b276416f76e20da3add001aff9fc30avboxsync {
ebc248f21b276416f76e20da3add001aff9fc30avboxsync void *search = crHashtableSearch( h, res+i );
ebc248f21b276416f76e20da3add001aff9fc30avboxsync Assert(!search);
ebc248f21b276416f76e20da3add001aff9fc30avboxsync }
ebc248f21b276416f76e20da3add001aff9fc30avboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return res;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableDelete( CRHashTable *h, unsigned long key, CRHashtableCallback deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int index = crHash( key );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *temp, *beftemp = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( temp = h->buckets[index]; temp; temp = temp->next )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->key == key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync beftemp = temp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync if ( temp )
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync {
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync if ( beftemp )
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync beftemp->next = temp->next;
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync else
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync h->buckets[index] = temp->next;
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync h->num_elements--;
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync if (temp->data && deleteFunc) {
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync (*deleteFunc)( temp->data );
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync crFree( temp );
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync }
4bc0cdd759dbf2c1cd20c28ab29be65e86bf0a90vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashIdPoolFreeBlock( h->idPool, key, 1 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableDeleteBlock( CRHashTable *h, unsigned long key, GLsizei range, CRHashtableCallback deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* XXX optimize someday */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLuint i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i < (GLuint)range; i++) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashtableDelete( h, key, deleteFunc );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid *crHashtableSearch( const CRHashTable *h, unsigned long key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int index = crHash( key );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *temp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex((CRmutex *)&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( temp = h->buckets[index]; temp; temp = temp->next )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->key == key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex((CRmutex *)&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !temp )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return temp->data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crHashtableReplace( CRHashTable *h, unsigned long key, void *data,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashtableCallback deleteFunc)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int index = crHash( key );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *temp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( temp = h->buckets[index]; temp; temp = temp->next )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->key == key )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( !temp )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crHashtableAdd( h, key, data );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( temp->data && deleteFunc )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (*deleteFunc)( temp->data );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync temp->data = data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&h->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncunsigned int crHashtableNumElements( const CRHashTable *h)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (h)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return h->num_elements;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Determine if the given key is used. Return GL_TRUE if so.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLboolean crHashtableIsKeyUsed( const CRHashTable *h, GLuint id )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (GLboolean) !crHashIdPoolIsIdFree( h->idPool, id);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLboolean crHashtableGetDataKey(CRHashTable *pHash, void *pData, unsigned long *pKey)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRHashNode *entry;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLboolean rc = GL_FALSE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!pHash)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&pHash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i<CR_NUM_BUCKETS && !rc; i++)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = pHash->buckets[i];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (entry)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (entry->data == pData) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pKey)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pKey = entry->key;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = GL_TRUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync entry = entry->next;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&pHash->mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}