VirtualBox

Changeset 3362 in kBuild


Ignore:
Timestamp:
Jun 8, 2020 7:28:44 PM (5 years ago)
Author:
bird
Message:

kFsCache: Don't need to lock the whole cache when using kFsCacheObjAddUserData and kFsCacheObjGetUserData. Fixed incorrect debug hack checking that we don't release objects while they are in the path hash structures.

Location:
trunk/src/lib/nt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/nt/kFsCache.c

    r3359 r3362  
    429429                                    ? pCache->auGenerations[       pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
    430430                                    : pCache->auGenerationsMissing[pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    431             pFsObj->abUnused[0] += 1; // for debugging
     431            pFsObj->cPathHashRefs += 1; // for debugging
    432432        }
    433433        else
     
    486486                                    ? pCache->auGenerations[       pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
    487487                                    : pCache->auGenerationsMissing[pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    488             pFsObj->abUnused[0] += 1; // for debugging
     488            pFsObj->cPathHashRefs += 1; // for debugging
    489489        }
    490490        else
     
    593593        pObj->bObjType      = bObjType;
    594594        pObj->fHaveStats    = K_FALSE;
    595         pObj->abUnused[0]   = K_FALSE;
    596         pObj->abUnused[1]   = K_FALSE;
     595        pObj->cPathHashRefs = 0;
     596        pObj->idxUserDataLock = KU8_MAX;
    597597        pObj->fFlags        = pParent->Obj.fFlags & KFSOBJ_F_INHERITED_MASK;
    598598        pObj->pParent       = pParent;
     
    33863386            else
    33873387            {
     3388                pHashEntry->pFsObj->cPathHashRefs -= 1;
    33883389                kFsCacheObjRelease(pCache, pHashEntry->pFsObj);
    33893390                if (pHashEntry->fAbsolute)
     
    34473448            else
    34483449            {
     3450                pHashEntry->pFsObj->cPathHashRefs -= 1;
    34493451                kFsCacheObjRelease(pCache, pHashEntry->pFsObj);
    34503452                if (pHashEntry->fAbsolute)
     
    39003902    KFSCACHE_LOG(("Destroying %s/%s, type=%d, pObj=%p, pszWhere=%s\n",
    39013903                  pObj->pParent ? pObj->pParent->Obj.pszName : "", pObj->pszName, pObj->bObjType, pObj, pszWhere));
    3902     if (pObj->abUnused[1] != 0)
     3904    if (pObj->cPathHashRefs != 0)
    39033905    {
    39043906        fprintf(stderr, "Destroying %s/%s, type=%d, path hash entries: %d!\n", pObj->pParent ? pObj->pParent->Obj.pszName : "",
    3905                 pObj->pszName, pObj->bObjType, pObj->abUnused[0]);
     3907                pObj->pszName, pObj->bObjType, pObj->cPathHashRefs);
    39063908        fflush(stderr);
    39073909        __debugbreak();
     
    40804082{
    40814083    kHlpAssert(cbUserData >= sizeof(*pNew));
    4082     KFSCACHE_LOCK(pCache);
     4084    KFSCACHE_OBJUSERDATA_LOCK(pCache, pObj);
    40834085
    40844086    if (kFsCacheObjGetUserData(pCache, pObj, uKey) == NULL)
     
    40914093            pNew->pNext         = pObj->pUserDataHead;
    40924094            pObj->pUserDataHead = pNew;
    4093             KFSCACHE_UNLOCK(pCache);
     4095            KFSCACHE_OBJUSERDATA_UNLOCK(pCache, pObj);
    40944096            return pNew;
    40954097        }
    40964098    }
    40974099
    4098     KFSCACHE_UNLOCK(pCache);
     4100    KFSCACHE_OBJUSERDATA_UNLOCK(pCache, pObj);
    40994101    return NULL;
    41004102}
     
    41154117    kHlpAssert(pCache->u32Magic == KFSCACHE_MAGIC);
    41164118    kHlpAssert(pObj->u32Magic == KFSOBJ_MAGIC);
    4117     KFSCACHE_LOCK(pCache);
     4119    KFSCACHE_OBJUSERDATA_LOCK(pCache, pObj);
    41184120
    41194121    for (pCur = pObj->pUserDataHead; pCur; pCur = pCur->pNext)
    41204122        if (pCur->uKey == uKey)
    41214123        {
    4122             KFSCACHE_UNLOCK(pCache);
     4124            KFSCACHE_OBJUSERDATA_UNLOCK(pCache, pObj);
    41234125            return pCur;
    41244126        }
    41254127
    4126     KFSCACHE_UNLOCK(pCache);
     4128    KFSCACHE_OBJUSERDATA_UNLOCK(pCache, pObj);
    41274129    return NULL;
    41284130}
    41294131
     4132
     4133/**
     4134 * Determins the idxUserDataLock value.
     4135 *
     4136 * Called by KFSCACHE_OBJUSERDATA_LOCK when idxUserDataLock is set to KU8_MAX.
     4137 *
     4138 * @returns The proper idxUserDataLock value.
     4139 * @param   pCache              The cache.
     4140 * @param   pObj                The object.
     4141 */
     4142KU8 kFsCacheObjGetUserDataLockIndex(PKFSCACHE pCache, PKFSOBJ pObj)
     4143{
     4144    KU8 idxUserDataLock = pObj->idxUserDataLock;
     4145    if (idxUserDataLock == KU8_MAX)
     4146    {
     4147        KFSCACHE_LOCK(pCache);
     4148        idxUserDataLock = pObj->idxUserDataLock;
     4149        if (idxUserDataLock == KU8_MAX)
     4150        {
     4151            idxUserDataLock = pCache->idxUserDataNext++;
     4152            idxUserDataLock %= K_ELEMENTS(pCache->auUserDataLocks);
     4153            pObj->idxUserDataLock = idxUserDataLock;
     4154        }
     4155        KFSCACHE_UNLOCK(pCache);
     4156    }
     4157    return idxUserDataLock;
     4158}
    41304159
    41314160/**
     
    47664795
    47674796#ifdef KFSCACHE_CFG_LOCKING
    4768             InitializeCriticalSection(&pCache->u.CritSect);
     4797            {
     4798                KSIZE idx = K_ELEMENTS(pCache->auUserDataLocks);
     4799                while (idx-- > 0)
     4800                    InitializeCriticalSection(&pCache->auUserDataLocks[idx].CritSect);
     4801                InitializeCriticalSection(&pCache->u.CritSect);
     4802            }
    47694803#endif
    47704804            return pCache;
  • trunk/src/lib/nt/kFsCache.h

    r3359 r3362  
    161161    /** Set if the Stats member is valid, clear if not. */
    162162    KBOOL               fHaveStats;
    163     /** Unused flags. */
    164     KBOOL               abUnused[2];
     163    /** Internal debug field for counting path hash references.
     164     * @internal  */
     165    KU8                 cPathHashRefs;
     166    /** Index into KFSCACHE::auUserData. */
     167    KU8                 idxUserDataLock;
    165168    /** Flags, KFSOBJ_F_XXX. */
    166169    KU32                fFlags;
     
    381384/** @def KFSCACHE_UNLOCK
    382385 *  Counterpart to KFSCACHE_LOCK. */
     386/** @def KFSCACHE_OBJUSERDATA_LOCK
     387 *  Locks the user data list of an object exclusively. */
     388/** @def KFSCACHE_OBJUSERDATA_UNLOCK
     389 *  Counterpart to KFSCACHE_OBJUSERDATA_LOCK. */
    383390#ifdef KFSCACHE_CFG_LOCKING
    384391# define KFSCACHE_LOCK(a_pCache)        EnterCriticalSection(&(a_pCache)->u.CritSect)
    385392# define KFSCACHE_UNLOCK(a_pCache)      LeaveCriticalSection(&(a_pCache)->u.CritSect)
     393# define KFSCACHE_OBJUSERDATA_LOCK(a_pCache, a_pObj) do { \
     394        KU8 idxUserDataLock = (a_pObj)->idxUserDataLock; \
     395        if (idxUserDataLock != KU8_MAX) \
     396        { /* likely */ } \
     397        else \
     398            idxUserDataLock = kFsCacheObjGetUserDataLockIndex(a_pCache, a_pObj); \
     399        idxUserDataLock &= (KU8)(K_ELEMENTS((a_pCache)->auUserDataLocks) - 1); \
     400        EnterCriticalSection(&(a_pCache)->auUserDataLocks[idxUserDataLock].CritSect); \
     401    } while (0)
     402# define KFSCACHE_OBJUSERDATA_UNLOCK(a_pCache, a_pObj) \
     403    LeaveCriticalSection(&(a_pCache)->auUserDataLocks[(a_pObj)->idxUserDataLock & (K_ELEMENTS((a_pCache)->auUserDataLocks) - 1)].CritSect)
    386404#else
    387405# define KFSCACHE_LOCK(a_pCache)        do { } while (0)
    388406# define KFSCACHE_UNLOCK(a_pCache)      do { } while (0)
     407# define KFSCACHE_OBJUSERDATA_LOCK(a_pCache, a_pObj)    do { } while (0)
     408# define KFSCACHE_OBJUSERDATA_UNLOCK(a_pCache, a_pObj)  do { } while (0)
    389409#endif
    390410
     
    456476
    457477#ifdef KFSCACHE_CFG_LOCKING
    458     /** Critical section protecting the cache. */
    459478    union
    460479    {
     
    463482# endif
    464483        KU64                abPadding[2 * 4 + 4 * sizeof(void *)];
    465     } u;
     484    }
     485    /** Critical section protecting the cache. */
     486                        u,
     487    /** Critical section protecting the pUserDataHead of objects.
     488     * @note Array size must be a power of two. */
     489                        auUserDataLocks[8];
     490    /** The next auUserData index. */
     491    KU8                 idxUserDataNext;
    466492#endif
    467493
     
    544570PKFSUSERDATA kFsCacheObjAddUserData(PKFSCACHE pCache, PKFSOBJ pObj, KUPTR uKey, KSIZE cbUserData);
    545571PKFSUSERDATA kFsCacheObjGetUserData(PKFSCACHE pCache, PKFSOBJ pObj, KUPTR uKey);
     572KU8         kFsCacheObjGetUserDataLockIndex(PKFSCACHE pCache, PKFSOBJ pObj);
    546573KBOOL       kFsCacheObjGetFullPathA(PKFSOBJ pObj, char *pszPath, KSIZE cbPath, char chSlash);
    547574KBOOL       kFsCacheObjGetFullPathW(PKFSOBJ pObj, wchar_t *pwszPath, KSIZE cwcPath, wchar_t wcSlash);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette