VirtualBox

Changeset 60026 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Mar 15, 2016 10:12:36 AM (9 years ago)
Author:
vboxsync
Message:

Storage/BusLogic: Process mailboxes on a dedicated worker thread to not block EMT for too long. Also fixes a problem with encrypted disks where the VM would hang during suspend when asking for the password

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevBusLogic.cpp

    r59252 r60026  
    405405    /** Number of mailboxes ready. */
    406406    volatile uint32_t               cMailboxesReady;
    407     /** Whether a notification to R3 was send. */
    408     volatile bool                   fNotificationSend;
     407    /** Whether a notification to R3 was sent. */
     408    volatile bool                   fNotificationSent;
    409409
    410410#if HC_ARCH_BITS == 64
     
    460460    /** Flag whether we have tasks which need to be processed again. */
    461461    bool volatile                   fRedo;
     462    /** Flag whether the worker thread is sleeping. */
     463    volatile bool                   fWrkThreadSleeping;
     464    /** Flag whether a request from the BIOS is pending which the
     465     * worker thread needs to process. */
     466    volatile bool                   fBiosReqPending;
    462467    /** List of tasks which can be redone. */
    463468    R3PTRTYPE(volatile PBUSLOGICTASKSTATE) pTasksRedoHead;
     469
     470    /** The support driver session handle. */
     471    R3R0PTRTYPE(PSUPDRVSESSION)     pSupDrvSession;
     472    /** Worker thread. */
     473    R3PTRTYPE(PPDMTHREAD)           pThreadWrk;
     474    /** The event semaphore the processing thread waits on. */
     475    SUPSEMEVENT                     hEvtProcess;
    464476
    465477#ifdef LOG_ENABLED
     
    876888    uint8_t         abCDB[12];
    877889} CCBC, *PCCBC;
    878 AssertCompileSize(CCB24, 30);
     890AssertCompileSize(CCBC, 30);
    879891
    880892/* Make sure that the 24-bit/32-bit/common CCB offsets match. */
     
    22422254                {
    22432255                    ASMAtomicIncU32(&pBusLogic->cMailboxesReady);
    2244                     if (!ASMAtomicXchgBool(&pBusLogic->fNotificationSend, true))
     2256                    if (!ASMAtomicXchgBool(&pBusLogic->fNotificationSent, true))
    22452257                    {
    22462258                        /* Send new notification to the queue. */
     
    25532565{
    25542566    int rc;
    2555     PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     2567    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    25562568
    25572569    Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x Port=%#x\n",
    25582570          pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, Port));
    25592571
     2572    /*
     2573     * If there is already a request form the BIOS pending ignore this write
     2574     * because it should not happen.
     2575     */
     2576    if (ASMAtomicReadBool(&pThis->fBiosReqPending))
     2577        return VINF_SUCCESS;
     2578
    25602579    Assert(cb == 1);
    25612580
    2562     rc = vboxscsiWriteRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), (uint8_t)u32);
     2581    rc = vboxscsiWriteRegister(&pThis->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), (uint8_t)u32);
    25632582    if (rc == VERR_MORE_DATA)
    25642583    {
    2565         rc = buslogicR3PrepareBIOSSCSIRequest(pBusLogic);
    2566         AssertRC(rc);
     2584        ASMAtomicXchgBool(&pThis->fBiosReqPending, true);
     2585        /* Send a notifier to the PDM queue that there are pending requests. */
     2586        PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pThis->CTX_SUFF(pNotifierQueue));
     2587        AssertMsg(pItem, ("Allocating item for queue failed\n"));
     2588        PDMQueueInsert(pThis->CTX_SUFF(pNotifierQueue), (PPDMQUEUEITEMCORE)pItem);
     2589        rc = VINF_SUCCESS;
    25672590    }
    25682591    else if (RT_FAILURE(rc))
     
    25792602                                                      uint8_t const *pbSrc, uint32_t *pcTransfers, unsigned cb)
    25802603{
    2581     PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     2604    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    25822605    Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));
    25832606
    2584     int rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), pbSrc, pcTransfers, cb);
     2607    /*
     2608     * If there is already a request form the BIOS pending ignore this write
     2609     * because it should not happen.
     2610     */
     2611    if (ASMAtomicReadBool(&pThis->fBiosReqPending))
     2612        return VINF_SUCCESS;
     2613
     2614    int rc = vboxscsiWriteString(pDevIns, &pThis->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), pbSrc, pcTransfers, cb);
    25852615    if (rc == VERR_MORE_DATA)
    25862616    {
    2587         rc = buslogicR3PrepareBIOSSCSIRequest(pBusLogic);
    2588         AssertRC(rc);
     2617        ASMAtomicXchgBool(&pThis->fBiosReqPending, true);
     2618        /* Send a notifier to the PDM queue that there are pending requests. */
     2619        PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pThis->CTX_SUFF(pNotifierQueue));
     2620        AssertMsg(pItem, ("Allocating item for queue failed\n"));
     2621        PDMQueueInsert(pThis->CTX_SUFF(pNotifierQueue), (PPDMQUEUEITEMCORE)pItem);
    25892622    }
    25902623    else if (RT_FAILURE(rc))
    25912624        AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));
    25922625
    2593     return rc;
     2626    return VINF_SUCCESS;
    25942627}
    25952628
     
    27152748        buslogicR3WarningISCSI(pThis->CTX_SUFF(pDevIns));
    27162749    }
    2717     else
     2750    else if (rc != VERR_VD_DEK_MISSING)
    27182751        buslogicR3WarningUnknown(pThis->CTX_SUFF(pDevIns), rc);
    27192752}
     
    28922925
    28932926    uTargetIdCCB = pTaskState->fIs24Bit ? pTaskState->CommandControlBlockGuest.o.uTargetId : pTaskState->CommandControlBlockGuest.n.uTargetId;
    2894     pTargetDevice = &pBusLogic->aDeviceStates[uTargetIdCCB];
    2895     pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice;
     2927    if (RT_LIKELY(uTargetIdCCB < RT_ELEMENTS(pBusLogic->aDeviceStates)))
     2928    {
     2929        pTargetDevice = &pBusLogic->aDeviceStates[uTargetIdCCB];
     2930        pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice;
    28962931
    28972932#ifdef LOG_ENABLED
    2898     buslogicR3DumpCCBInfo(&pTaskState->CommandControlBlockGuest, pTaskState->fIs24Bit);
     2933        buslogicR3DumpCCBInfo(&pTaskState->CommandControlBlockGuest, pTaskState->fIs24Bit);
    28992934#endif
    29002935
    2901     /* Alloc required buffers. */
    2902     rc = buslogicR3DataBufferAlloc(pTaskState);
    2903     AssertMsgRC(rc, ("Alloc failed rc=%Rrc\n", rc));
    2904 
    2905     rc = buslogicR3SenseBufferAlloc(pTaskState);
    2906     AssertMsgRC(rc, ("Mapping sense buffer failed rc=%Rrc\n", rc));
    2907 
    2908     /* Check if device is present on bus. If not return error immediately and don't process this further. */
    2909     if (!pBusLogic->aDeviceStates[uTargetIdCCB].fPresent)
    2910     {
    2911         buslogicR3DataBufferFree(pTaskState);
    2912 
    2913         if (pTaskState->pbSenseBuffer)
    2914             buslogicR3SenseBufferFree(pTaskState, true);
     2936        /* Alloc required buffers. */
     2937        rc = buslogicR3DataBufferAlloc(pTaskState);
     2938        AssertMsgRC(rc, ("Alloc failed rc=%Rrc\n", rc));
     2939
     2940        rc = buslogicR3SenseBufferAlloc(pTaskState);
     2941        AssertMsgRC(rc, ("Mapping sense buffer failed rc=%Rrc\n", rc));
     2942
     2943        /* Check if device is present on bus. If not return error immediately and don't process this further. */
     2944        if (!pBusLogic->aDeviceStates[uTargetIdCCB].fPresent)
     2945        {
     2946            buslogicR3DataBufferFree(pTaskState);
     2947
     2948            if (pTaskState->pbSenseBuffer)
     2949                buslogicR3SenseBufferFree(pTaskState, true);
     2950
     2951            buslogicR3SendIncomingMailbox(pBusLogic, pTaskState,
     2952                                          BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_SCSI_SELECTION_TIMEOUT,
     2953                                          BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD,
     2954                                          BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITH_ERROR);
     2955
     2956            RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     2957        }
     2958        else
     2959        {
     2960            /* Setup SCSI request. */
     2961            pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->fIs24Bit ? pTaskState->CommandControlBlockGuest.o.uLogicalUnit
     2962                                                                           : pTaskState->CommandControlBlockGuest.n.uLogicalUnit;
     2963
     2964            if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)
     2965                pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_UNKNOWN;
     2966            else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
     2967                pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_FROM_DEVICE;
     2968            else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
     2969                pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_TO_DEVICE;
     2970            else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_NO_DATA)
     2971                pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_NONE;
     2972            else
     2973                AssertMsgFailed(("Invalid data direction type %d\n", pTaskState->CommandControlBlockGuest.c.uDataDirection));
     2974
     2975            pTaskState->PDMScsiRequest.cbCDB                 = pTaskState->CommandControlBlockGuest.c.cbCDB;
     2976            pTaskState->PDMScsiRequest.pbCDB                 = pTaskState->CommandControlBlockGuest.c.abCDB;
     2977            if (pTaskState->DataSeg.cbSeg)
     2978            {
     2979                pTaskState->PDMScsiRequest.cbScatterGather       = pTaskState->DataSeg.cbSeg;
     2980                pTaskState->PDMScsiRequest.cScatterGatherEntries = 1;
     2981                pTaskState->PDMScsiRequest.paScatterGatherHead   = &pTaskState->DataSeg;
     2982            }
     2983            else
     2984            {
     2985                pTaskState->PDMScsiRequest.cbScatterGather       = 0;
     2986                pTaskState->PDMScsiRequest.cScatterGatherEntries = 0;
     2987                pTaskState->PDMScsiRequest.paScatterGatherHead   = NULL;
     2988            }
     2989            pTaskState->PDMScsiRequest.cbSenseBuffer         = buslogicR3ConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.c.cbSenseData);
     2990            pTaskState->PDMScsiRequest.pbSenseBuffer         = pTaskState->pbSenseBuffer;
     2991            pTaskState->PDMScsiRequest.pvUser                = pTaskState;
     2992
     2993            ASMAtomicIncU32(&pTargetDevice->cOutstandingRequests);
     2994            rc = pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTargetDevice->pDrvSCSIConnector, &pTaskState->PDMScsiRequest);
     2995            AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc));
     2996        }
     2997    }
     2998    else
     2999    {
     3000        RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
    29153001
    29163002        buslogicR3SendIncomingMailbox(pBusLogic, pTaskState,
    2917                                     BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_SCSI_SELECTION_TIMEOUT,
    2918                                     BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD,
    2919                                     BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITH_ERROR);
    2920 
    2921         RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
    2922     }
    2923     else
    2924     {
    2925         /* Setup SCSI request. */
    2926         pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->fIs24Bit ? pTaskState->CommandControlBlockGuest.o.uLogicalUnit
    2927                                                                        : pTaskState->CommandControlBlockGuest.n.uLogicalUnit;
    2928 
    2929         if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)
    2930             pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_UNKNOWN;
    2931         else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
    2932             pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_FROM_DEVICE;
    2933         else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
    2934             pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_TO_DEVICE;
    2935         else if (pTaskState->CommandControlBlockGuest.c.uDataDirection == BUSLOGIC_CCB_DIRECTION_NO_DATA)
    2936             pTaskState->PDMScsiRequest.uDataDirection = PDMSCSIREQUESTTXDIR_NONE;
    2937         else
    2938             AssertMsgFailed(("Invalid data direction type %d\n", pTaskState->CommandControlBlockGuest.c.uDataDirection));
    2939 
    2940         pTaskState->PDMScsiRequest.cbCDB                 = pTaskState->CommandControlBlockGuest.c.cbCDB;
    2941         pTaskState->PDMScsiRequest.pbCDB                 = pTaskState->CommandControlBlockGuest.c.abCDB;
    2942         if (pTaskState->DataSeg.cbSeg)
    2943         {
    2944             pTaskState->PDMScsiRequest.cbScatterGather       = pTaskState->DataSeg.cbSeg;
    2945             pTaskState->PDMScsiRequest.cScatterGatherEntries = 1;
    2946             pTaskState->PDMScsiRequest.paScatterGatherHead   = &pTaskState->DataSeg;
    2947         }
    2948         else
    2949         {
    2950             pTaskState->PDMScsiRequest.cbScatterGather       = 0;
    2951             pTaskState->PDMScsiRequest.cScatterGatherEntries = 0;
    2952             pTaskState->PDMScsiRequest.paScatterGatherHead   = NULL;
    2953         }
    2954         pTaskState->PDMScsiRequest.cbSenseBuffer         = buslogicR3ConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.c.cbSenseData);
    2955         pTaskState->PDMScsiRequest.pbSenseBuffer         = pTaskState->pbSenseBuffer;
    2956         pTaskState->PDMScsiRequest.pvUser                = pTaskState;
    2957 
    2958         ASMAtomicIncU32(&pTargetDevice->cOutstandingRequests);
    2959         rc = pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTargetDevice->pDrvSCSIConnector, &pTaskState->PDMScsiRequest);
    2960         AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc));
     3003                                      BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_INVALID_COMMAND_PARAMETER,
     3004                                      BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD,
     3005                                      BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITH_ERROR);
    29613006    }
    29623007
     
    29753020
    29763021    uTargetIdCCB = pTaskState->fIs24Bit ? pTaskState->CommandControlBlockGuest.o.uTargetId : pTaskState->CommandControlBlockGuest.n.uTargetId;
    2977     pTargetDevice = &pBusLogic->aDeviceStates[uTargetIdCCB];
    2978     pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice;
    2979 
    2980     buslogicR3SendIncomingMailbox(pBusLogic, pTaskState,
    2981                                   BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_ABORT_QUEUE_GENERATED,
    2982                                   BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD,
    2983                                   BUSLOGIC_MAILBOX_INCOMING_COMPLETION_ABORTED_NOT_FOUND);
    2984 
    2985     RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     3022    if (RT_LIKELY(uTargetIdCCB < RT_ELEMENTS(pBusLogic->aDeviceStates)))
     3023    {
     3024        pTargetDevice = &pBusLogic->aDeviceStates[uTargetIdCCB];
     3025        pTaskState->CTX_SUFF(pTargetDevice) = pTargetDevice;
     3026
     3027        buslogicR3SendIncomingMailbox(pBusLogic, pTaskState,
     3028                                      BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_ABORT_QUEUE_GENERATED,
     3029                                      BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD,
     3030                                      BUSLOGIC_MAILBOX_INCOMING_COMPLETION_ABORTED_NOT_FOUND);
     3031
     3032        RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     3033    }
     3034    else
     3035    {
     3036        RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     3037
     3038        buslogicR3SendIncomingMailbox(pBusLogic, pTaskState,
     3039                                      BUSLOGIC_MAILBOX_INCOMING_ADAPTER_STATUS_INVALID_COMMAND_PARAMETER,
     3040                                      BUSLOGIC_MAILBOX_INCOMING_DEVICE_STATUS_OPERATION_GOOD,
     3041                                      BUSLOGIC_MAILBOX_INCOMING_COMPLETION_WITH_ERROR);
     3042    }
    29863043
    29873044    return rc;
     
    31113168static DECLCALLBACK(bool) buslogicR3NotifyQueueConsumer(PPDMDEVINS pDevIns, PPDMQUEUEITEMCORE pItem)
    31123169{
    3113     PBUSLOGIC  pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    3114 
    3115     /* Reset notification send flag now. */
    3116     Assert(pBusLogic->fNotificationSend);
    3117     ASMAtomicXchgBool(&pBusLogic->fNotificationSend, false);
    3118     ASMAtomicXchgU32(&pBusLogic->cMailboxesReady, 0); /** @todo Actually not required anymore but to stay compatible with older saved states. */
    3119 
    3120     /* Process mailboxes. */
    3121     int rc;
    3122     do
    3123     {
    3124         rc = buslogicR3ProcessMailboxNext(pBusLogic);
    3125         AssertMsg(RT_SUCCESS(rc) || rc == VERR_NO_DATA, ("Processing mailbox failed rc=%Rrc\n", rc));
    3126     } while (RT_SUCCESS(rc));
     3170    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     3171
     3172    int rc = SUPSemEventSignal(pThis->pSupDrvSession, pThis->hEvtProcess);
     3173    AssertRC(rc);
    31273174
    31283175    return true;
     
    32153262    SSMR3PutU32   (pSSM, pBusLogic->uMailboxOutgoingPositionCurrent);
    32163263    SSMR3PutU32   (pSSM, pBusLogic->cMailboxesReady);
    3217     SSMR3PutBool  (pSSM, pBusLogic->fNotificationSend);
     3264    SSMR3PutBool  (pSSM, pBusLogic->fNotificationSent);
    32183265    SSMR3PutGCPhys(pSSM, pBusLogic->GCPhysAddrMailboxIncomingBase);
    32193266    SSMR3PutU32   (pSSM, pBusLogic->uMailboxIncomingPositionCurrent);
     
    33173364    SSMR3GetU32   (pSSM, &pBusLogic->uMailboxOutgoingPositionCurrent);
    33183365    SSMR3GetU32   (pSSM, (uint32_t *)&pBusLogic->cMailboxesReady);
    3319     SSMR3GetBool  (pSSM, (bool *)&pBusLogic->fNotificationSend);
     3366    SSMR3GetBool  (pSSM, (bool *)&pBusLogic->fNotificationSent);
    33203367    SSMR3GetGCPhys(pSSM, &pBusLogic->GCPhysAddrMailboxIncomingBase);
    33213368    SSMR3GetU32   (pSSM, &pBusLogic->uMailboxIncomingPositionCurrent);
     
    34393486    PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pThis->ILeds);
    34403487    return NULL;
     3488}
     3489
     3490/**
     3491 * The worker thread processing requests from the guest.
     3492 *
     3493 * @returns VBox status code.
     3494 * @param   pDevIns         The device instance.
     3495 * @param   pThread         The thread structure.
     3496 */
     3497static DECLCALLBACK(int) buslogicR3Worker(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
     3498{
     3499    PBUSLOGIC pThis = (PBUSLOGIC)pThread->pvUser;
     3500    int rc = VINF_SUCCESS;
     3501
     3502    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     3503        return VINF_SUCCESS;
     3504
     3505    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     3506    {
     3507        ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, true);
     3508        bool fNotificationSent = ASMAtomicXchgBool(&pThis->fNotificationSent, false);
     3509        if (!fNotificationSent)
     3510        {
     3511            Assert(ASMAtomicReadBool(&pThis->fWrkThreadSleeping));
     3512            rc = SUPSemEventWaitNoResume(pThis->pSupDrvSession, pThis->hEvtProcess, RT_INDEFINITE_WAIT);
     3513            AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc);
     3514            if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING))
     3515                break;
     3516            LogFlowFunc(("Woken up with rc=%Rrc\n", rc));
     3517            ASMAtomicWriteBool(&pThis->fNotificationSent, false);
     3518        }
     3519
     3520        ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, false);
     3521
     3522        /* Check whether there is a BIOS request pending and process it first. */
     3523        if (ASMAtomicReadBool(&pThis->fBiosReqPending))
     3524        {
     3525            rc = buslogicR3PrepareBIOSSCSIRequest(pThis);
     3526            AssertRC(rc);
     3527            ASMAtomicXchgBool(&pThis->fBiosReqPending, false);
     3528        }
     3529        else
     3530        {
     3531            ASMAtomicXchgU32(&pThis->cMailboxesReady, 0); /** @todo Actually not required anymore but to stay compatible with older saved states. */
     3532
     3533            /* Process mailboxes. */
     3534            do
     3535            {
     3536                rc = buslogicR3ProcessMailboxNext(pThis);
     3537                AssertMsg(RT_SUCCESS(rc) || rc == VERR_NO_DATA, ("Processing mailbox failed rc=%Rrc\n", rc));
     3538            } while (RT_SUCCESS(rc));
     3539        }
     3540    } /* While running */
     3541
     3542    return VINF_SUCCESS;
     3543}
     3544
     3545
     3546/**
     3547 * Unblock the worker thread so it can respond to a state change.
     3548 *
     3549 * @returns VBox status code.
     3550 * @param   pDevIns     The device instance.
     3551 * @param   pThread     The send thread.
     3552 */
     3553static DECLCALLBACK(int) buslogicR3WorkerWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
     3554{
     3555    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     3556    return SUPSemEventSignal(pThis->pSupDrvSession, pThis->hEvtProcess);
    34413557}
    34423558
     
    36083724        ASMAtomicWriteBool(&pThis->fSignalIdle, false);
    36093725
    3610         AssertMsg(!pThis->fNotificationSend, ("The PDM Queue should be empty at this point\n"));
     3726        AssertMsg(!pThis->fNotificationSent, ("The PDM Queue should be empty at this point\n"));
    36113727
    36123728        if (pThis->fRedo)
     
    38413957        }
    38423958        pThis->fRedo = false;
     3959    }
     3960
     3961    if (pThis->hEvtProcess != NIL_SUPSEMEVENT)
     3962    {
     3963        SUPSemEventClose(pThis->pSupDrvSession, pThis->hEvtProcess);
     3964        pThis->hEvtProcess = NIL_SUPSEMEVENT;
    38433965    }
    38443966
     
    39824104    if (RT_FAILURE(rc))
    39834105        return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic: cannot create critical section"));
     4106
     4107    /*
     4108     * Create event semaphore and worker thread.
     4109     */
     4110    rc = SUPSemEventCreate(pThis->pSupDrvSession, &pThis->hEvtProcess);
     4111    if (RT_FAILURE(rc))
     4112        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     4113                                   N_("BusLogic: Failed to create SUP event semaphore"));
     4114
     4115    char szDevTag[20];
     4116    RTStrPrintf(szDevTag, sizeof(szDevTag), "BUSLOGIC-%u", iInstance);
     4117
     4118    rc = PDMDevHlpThreadCreate(pDevIns, &pThis->pThreadWrk, pThis, buslogicR3Worker,
     4119                               buslogicR3WorkerWakeUp, 0, RTTHREADTYPE_IO, szDevTag);
     4120    if (RT_FAILURE(rc))
     4121        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     4122                                   N_("BusLogic: Failed to create worker thread %s"), szDevTag);
    39844123
    39854124    /* Initialize per device state. */
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r59875 r60026  
    17151715    GEN_CHECK_OFF(BUSLOGIC, uMailboxOutgoingPositionCurrent);
    17161716    GEN_CHECK_OFF(BUSLOGIC, cMailboxesReady);
    1717     GEN_CHECK_OFF(BUSLOGIC, fNotificationSend);
     1717    GEN_CHECK_OFF(BUSLOGIC, fNotificationSent);
    17181718    GEN_CHECK_OFF(BUSLOGIC, GCPhysAddrMailboxIncomingBase);
    17191719    GEN_CHECK_OFF(BUSLOGIC, uMailboxIncomingPositionCurrent);
     
    17331733    GEN_CHECK_OFF(BUSLOGIC, fSignalIdle);
    17341734    GEN_CHECK_OFF(BUSLOGIC, fRedo);
     1735    GEN_CHECK_OFF(BUSLOGIC, fWrkThreadSleeping);
     1736    GEN_CHECK_OFF(BUSLOGIC, fBiosReqPending);
    17351737    GEN_CHECK_OFF(BUSLOGIC, pTasksRedoHead);
     1738    GEN_CHECK_OFF(BUSLOGIC, pSupDrvSession);
     1739    GEN_CHECK_OFF(BUSLOGIC, hEvtProcess);
     1740# ifdef LOG_ENABLED
     1741    GEN_CHECK_OFF(BUSLOGIC, cInMailboxesReady);
     1742# endif
    17361743#endif /* VBOX_WITH_BUSLOGIC */
    17371744
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