VirtualBox

Changeset 33951 in vbox


Ignore:
Timestamp:
Nov 10, 2010 10:14:46 PM (14 years ago)
Author:
vboxsync
Message:

Additions/WINNT/Graphics: replace spinlock in XPDM VBVA channel handling with a lockless algorithm

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp

    r33890 r33951  
    659659typedef struct _VBVADISP_CHANNELCONTEXT
    660660{
    661     struct _VBVAHOSTCMD * pFirstCmd;
    662     struct _VBVAHOSTCMD * pLastCmd;
    663     VBOXVCMNSPIN_LOCK pSynchLock;
    664 #ifdef DEBUG
    665     int cCmds;
    666 #endif
     661    /** The generic command handler builds up a list of commands - in reverse
     662     * order! - here */
     663    VBVAHOSTCMD *pCmd;
    667664    bool bValid;
    668665}VBVADISP_CHANNELCONTEXT;
    669 
    670 #ifdef DEBUG
    671 void dbgCheckListLocked(const VBVADISP_CHANNELCONTEXT *pList, struct _VBVAHOSTCMD * pCmd)
    672 {
    673     int counter = 0;
    674     for(struct _VBVAHOSTCMD * pCur = pList->pFirstCmd; pCur; pCur=pCur->u.pNext)
    675     {
    676         Assert(pCur != pCmd);
    677         if(pCur == pList->pLastCmd)
    678         {
    679             Assert(pCur->u.pNext == NULL);
    680         }
    681         if(pCur->u.pNext == NULL)
    682         {
    683             Assert(pCur == pList->pLastCmd);
    684         }
    685         counter++;
    686     }
    687 
    688     Assert(counter == pList->cCmds);
    689 }
    690 
    691 void dbgCheckList(PVBOXVIDEO_COMMON pCommon, VBVADISP_CHANNELCONTEXT *pList, struct _VBVAHOSTCMD * pCmd)
    692 {
    693     VBOXVCMNIRQL oldIrql;
    694     VBoxVideoCmnSpinLockAcquire(commonToPrimaryExt(pCommon), &pList->pSynchLock, &oldIrql);
    695 
    696     dbgCheckListLocked(pList, pCmd);
    697 
    698     VBoxVideoCmnSpinLockRelease(commonToPrimaryExt(pCommon), &pList->pSynchLock, oldIrql);
    699 }
    700 
    701 #define DBG_CHECKLIST_LOCKED(_pl, pc) dbgCheckListLocked(_pl, pc)
    702 #define DBG_CHECKLIST(_pv, _pl, pc) dbgCheckList(_pv, _pl, pc)
    703 
    704 #else
    705 #define DBG_CHECKLIST_LOCKED(_pl, pc) do{}while(0)
    706 #define DBG_CHECKLIST(_pv, _pl, pc) do{}while(0)
    707 #endif
    708 
    709666
    710667typedef struct _VBVA_CHANNELCONTEXTS
     
    759716}
    760717
     718/** Reverses a NULL-terminated linked list of VBVAHOSTCMD structures. */
     719static VBVAHOSTCMD *vboxVBVAReverseList(VBVAHOSTCMD *pList)
     720{
     721    VBVAHOSTCMD *pFirst = NULL;
     722    while (pList)
     723    {
     724        VBVAHOSTCMD *pNext = pList;
     725        pList = pList->u.pNext;
     726        pNext->u.pNext = pFirst;
     727        pFirst = pNext;
     728    }
     729    return pFirst;
     730}
     731
    761732DECLCALLBACK(int) hgsmiHostCmdRequest (HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, uint32_t iDevice, struct _VBVAHOSTCMD ** ppCmd)
    762733{
     
    779750        if(pDispContext)
    780751        {
    781             UCHAR oldIrql;
    782             VBoxVideoCmnSpinLockAcquire(commonToPrimaryExt(pCommon), &pDispContext->pSynchLock, &oldIrql);
    783 
    784             DBG_CHECKLIST_LOCKED(pDispContext, NULL);
    785 
    786             *ppCmd = pDispContext->pFirstCmd;
    787             pDispContext->pFirstCmd = NULL;
    788             pDispContext->pLastCmd = NULL;
    789 #ifdef DEBUG
    790             pDispContext->cCmds = 0;
    791 #endif
    792             VBoxVideoCmnSpinLockRelease(commonToPrimaryExt(pCommon), &pDispContext->pSynchLock, oldIrql);
    793 
    794             DBG_CHECKLIST(pCommon, pDispContext, NULL);
     752            VBVAHOSTCMD *pCmd;
     753            do
     754                pCmd = pDispContext->pCmd;
     755            while (!ASMAtomicCmpXchgPtr(&pDispContext->pCmd, NULL, pCmd));
     756            *ppCmd = vboxVBVAReverseList(pCmd);
    795757
    796758            return VINF_SUCCESS;
     
    860822                        default:
    861823                        {
    862                             DBG_CHECKLIST(pCallbacks->pCommon, pHandler, pCur);
    863824                            Assert(u16ChannelInfo==VBVAHG_EVENT);
    864825                            Assert(!pCur->u.Data);
     
    886847                }
    887848
    888                 DBG_CHECKLIST(pCallbacks->pCommon, pHandler, pFirst);
    889 
    890849                /* we do not support lists currently */
    891850                Assert(pFirst == pLast);
     
    898857                {
    899858                    Assert(pLast);
    900                     UCHAR oldIrql;
    901                     VBoxVideoCmnSpinLockAcquire(commonToPrimaryExt(pCallbacks->pCommon),
    902                                                 &pHandler->pSynchLock,
    903                                                 &oldIrql);
    904 
    905                     DBG_CHECKLIST_LOCKED(pHandler, pFirst);
    906 
    907                     if(pHandler->pLastCmd)
     859                    VBVAHOSTCMD *pCmd;
     860                    do
    908861                    {
    909                         pHandler->pLastCmd->u.pNext = pFirst;
    910                         Assert(pHandler->pFirstCmd);
     862                        pCmd = pHandler->pCmd;
     863                        pFirst->u.pNext = pCmd;
    911864                    }
    912                     else
    913                     {
    914                         Assert(!pHandler->pFirstCmd);
    915                         pHandler->pFirstCmd = pFirst;
    916                     }
    917                     pHandler->pLastCmd = pLast;
    918 #ifdef DEBUG
    919                     pHandler->cCmds++;
    920 #endif
    921                     DBG_CHECKLIST_LOCKED(pHandler, NULL);
    922 
    923                     VBoxVideoCmnSpinLockRelease(commonToPrimaryExt(pCallbacks->pCommon),
    924                                                 &pHandler->pSynchLock,
    925                                                 oldIrql);
     865                    while (!ASMAtomicCmpXchgPtr(&pHandler->pCmd, pFirst, pCmd));
    926866                }
    927867                else
     
    977917        Assert(!pDispContext->bValid);
    978918#endif
    979         Assert(!pDispContext->pFirstCmd);
    980         Assert(!pDispContext->pLastCmd);
     919        Assert(!pDispContext->pCmd);
    981920        if(!pDispContext->bValid)
    982921        {
    983922            pDispContext->bValid = true;
    984             pDispContext->pFirstCmd = NULL;
    985             pDispContext->pLastCmd= NULL;
    986 #ifdef DEBUG
    987             pDispContext->cCmds = 0;
    988 #endif
    989 
    990             VBoxVideoCmnSpinLockCreate(commonToPrimaryExt(pCommon), &pDispContext->pSynchLock);
     923            pDispContext->pCmd = NULL;
    991924
    992925            int rc = VINF_SUCCESS;
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