VirtualBox

Changeset 23396 in vbox


Ignore:
Timestamp:
Sep 28, 2009 5:25:54 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
52926
Message:

Runteim/Aio-posix: Respect AIO_LISTIO_MAX for aio_suspend too. Should fix another darwin issue

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp

    r23364 r23396  
    6464# define AIO_LISTIO_MAX UINT32_MAX
    6565#endif
     66
     67#if 0 /* Only used for debugging */
     68# undef AIO_LISTIO_MAX
     69# define AIO_LISTIO_MAX 16
     70#endif
     71
     72/** Invalid entry in the waiting array. */
     73#define RTFILEAIOCTX_WAIT_ENTRY_INVALID (~0U)
    6674
    6775/*******************************************************************************
     
    128136     * the operation. */
    129137    RTSEMEVENT            SemEventCancel;
    130     /** Number of elements in the waiting list. */
    131     unsigned              cReqsWait;
     138    /** Head of submitted elements waiting to get into the array. */
     139    PRTFILEAIOREQINTERNAL pReqsWaitHead;
     140    /** Tail of submitted elements waiting to get into the array. */
     141    PRTFILEAIOREQINTERNAL pReqsWaitTail;
     142    /** Maximum number of elements in the waiting array. */
     143    unsigned              cReqsWaitMax;
    132144    /** First free slot in the waiting list. */
    133145    unsigned              iFirstFree;
    134146    /** List of requests we are currently waiting on.
    135      * Size depends on cMaxRequests. */
     147     * Size depends on cMaxRequests and AIO_LISTIO_MAX. */
    136148    volatile PRTFILEAIOREQINTERNAL apReqs[1];
    137149} RTFILEAIOCTXINTERNAL, *PRTFILEAIOCTXINTERNAL;
     
    188200                                                                                     NULL);
    189201
    190             while (pReqHead)
     202            while (  (pCtxInt->iFirstFree < pCtxInt->cReqsWaitMax)
     203                   && pReqHead)
    191204            {
    192205                pCtxInt->apReqs[pCtxInt->iFirstFree] = pReqHead;
     
    198211                pCtxInt->apReqs[pCtxInt->iFirstFree]->pPrev = NULL;
    199212                pCtxInt->iFirstFree++;
    200                 Assert(pCtxInt->iFirstFree <= pCtxInt->cMaxRequests);
     213
     214                Assert(   (pCtxInt->iFirstFree <= pCtxInt->cMaxRequests)
     215                       && (pCtxInt->iFirstFree <= pCtxInt->cReqsWaitMax));
     216            }
     217
     218            /* Append the rest to the wait list. */
     219            if (pReqHead)
     220            {
     221                if (!pCtxInt->pReqsWaitHead)
     222                {
     223                    Assert(!pCtxInt->pReqsWaitTail);
     224                    pCtxInt->pReqsWaitHead = pReqHead;
     225                    pReqHead->pPrev = NULL;
     226                }
     227                else
     228                {
     229                    AssertPtr(pCtxInt->pReqsWaitTail);
     230
     231                    pCtxInt->pReqsWaitTail->pNext = pReqHead;
     232                    pReqHead->pPrev = pCtxInt->pReqsWaitTail;
     233                }
     234
     235                /* Update tail. */
     236                while (pReqHead->pNext)
     237                    pReqHead = pReqHead->pNext;
     238
     239                pCtxInt->pReqsWaitTail = pReqHead;
     240                pCtxInt->pReqsWaitTail->pNext = NULL;
    201241            }
    202242        }
     
    206246        if (pReqToCancel)
    207247        {
    208             /* Put it out of the waiting list. */
    209             pCtxInt->apReqs[pReqToCancel->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree];
    210             pCtxInt->apReqs[pReqToCancel->iWaitingList]->iWaitingList = pReqToCancel->iWaitingList;
     248            /* The request can be in the array waiting for completion or still in the list because it is full. */
     249            if (pReqToCancel->iWaitingList != RTFILEAIOCTX_WAIT_ENTRY_INVALID)
     250            {
     251                /* Put it out of the waiting list. */
     252                pCtxInt->apReqs[pReqToCancel->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree];
     253                pCtxInt->apReqs[pReqToCancel->iWaitingList]->iWaitingList = pReqToCancel->iWaitingList;
     254            }
     255            else
     256            {
     257                /* Unlink from the waiting list. */
     258                PRTFILEAIOREQINTERNAL pPrev = pReqToCancel->pPrev;
     259                PRTFILEAIOREQINTERNAL pNext = pReqToCancel->pNext;
     260
     261                if (pNext)
     262                    pNext->pPrev = pPrev;
     263                else
     264                {
     265                    /* We canceled the tail. */
     266                    pCtxInt->pReqsWaitTail = pPrev;
     267                }
     268
     269                if (pPrev)
     270                    pPrev->pNext = pNext;
     271                else
     272                {
     273                    /* We canceled the head. */
     274                    pCtxInt->pReqsWaitHead = pNext;
     275                }
     276            }
     277
    211278            ASMAtomicDecS32(&pCtxInt->cRequests);
    212279            RTSemEventSignal(pCtxInt->SemEventCancel);
     
    282349        return VERR_NO_MEMORY;
    283350
    284     pReqInt->pCtxInt  = NULL;
    285     pReqInt->u32Magic = RTFILEAIOREQ_MAGIC;
     351    pReqInt->pCtxInt      = NULL;
     352    pReqInt->u32Magic     = RTFILEAIOREQ_MAGIC;
     353    pReqInt->iWaitingList = RTFILEAIOCTX_WAIT_ENTRY_INVALID;
    286354    RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
    287355
     
    447515{
    448516    PRTFILEAIOCTXINTERNAL pCtxInt;
     517    unsigned cReqsWaitMax;
     518
    449519    AssertPtrReturn(phAioCtx, VERR_INVALID_POINTER);
    450520
     
    452522        return VERR_OUT_OF_RANGE;
    453523
     524    cReqsWaitMax = RT_MIN(cAioReqsMax, AIO_LISTIO_MAX);
     525
    454526    pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ(  sizeof(RTFILEAIOCTXINTERNAL)
    455                                                  + cAioReqsMax * sizeof(PRTFILEAIOREQINTERNAL));
     527                                                 + cReqsWaitMax * sizeof(PRTFILEAIOREQINTERNAL));
    456528    if (RT_UNLIKELY(!pCtxInt))
    457529        return VERR_NO_MEMORY;
     
    467539    pCtxInt->u32Magic     = RTFILEAIOCTX_MAGIC;
    468540    pCtxInt->cMaxRequests = cAioReqsMax;
     541    pCtxInt->cReqsWaitMax = cReqsWaitMax;
    469542    *phAioCtx = (RTFILEAIOCTX)pCtxInt;
    470543
     
    780853            /* Requests finished. */
    781854            unsigned iReqCurr = 0;
    782             int cDone = 0;
     855            unsigned cDone = 0;
    783856
    784857            /* Remove completed requests from the waiting list. */
    785             while (iReqCurr < pCtxInt->iFirstFree)
     858            while (   (iReqCurr < pCtxInt->iFirstFree)
     859                   && (cDone < cReqs))
    786860            {
    787861                PRTFILEAIOREQINTERNAL pReq = pCtxInt->apReqs[iReqCurr];
     
    798872                    }
    799873                    else
     874                    {
     875#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
     876                        pReq->Rc = RTErrConvertFromErrno(errno);
     877#else
    800878                        pReq->Rc = RTErrConvertFromErrno(rcReq);
     879#endif
     880                    }
    801881
    802882                    /* Mark the request as finished. */
     
    804884                    cDone++;
    805885
    806                     /*
    807                      * Move the last entry into the current position to avoid holes
    808                      * but only if it is not the last element already.
    809                      */
    810                     if (pReq->iWaitingList < pCtxInt->iFirstFree - 1)
     886                    /* If there are other entries waiting put the head into the now free entry. */
     887                    if (pCtxInt->pReqsWaitHead)
    811888                    {
    812                         pCtxInt->apReqs[pReq->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree];
    813                         pCtxInt->apReqs[pReq->iWaitingList]->iWaitingList = pReq->iWaitingList;
    814                         pCtxInt->apReqs[pCtxInt->iFirstFree] = NULL;
     889                        PRTFILEAIOREQINTERNAL pReqInsert = pCtxInt->pReqsWaitHead;
     890
     891                        pCtxInt->pReqsWaitHead = pReqInsert->pNext;
     892                        if (!pCtxInt->pReqsWaitHead)
     893                        {
     894                            /* List is empty now. Clear tail too. */
     895                            pCtxInt->pReqsWaitTail = NULL;
     896                        }
     897
     898                        pReqInsert->iWaitingList = pReq->iWaitingList;
     899                        pCtxInt->apReqs[pReqInsert->iWaitingList] = pReqInsert;
     900                        iReqCurr++;
    815901                    }
    816902                    else
    817                         pCtxInt->iFirstFree--;
     903                    {
     904                        /*
     905                         * Move the last entry into the current position to avoid holes
     906                         * but only if it is not the last element already.
     907                         */
     908                        if (pReq->iWaitingList < pCtxInt->iFirstFree - 1)
     909                        {
     910                            pCtxInt->apReqs[pReq->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree];
     911                            pCtxInt->apReqs[pReq->iWaitingList]->iWaitingList = pReq->iWaitingList;
     912                            pCtxInt->apReqs[pCtxInt->iFirstFree] = NULL;
     913                        }
     914                        else
     915                            pCtxInt->iFirstFree--;
     916                    }
    818917
    819918                    /* Put the request into the completed list. */
    820919                    pahReqs[cRequestsCompleted++] = pReq;
     920                    pReq->iWaitingList = RTFILEAIOCTX_WAIT_ENTRY_INVALID;
    821921                }
    822922                else
     
    824924            }
    825925
     926            AssertMsg(   (cDone <= cMinReqs)
     927                      && (cDone <= cReqs), ("Overflow cReqs=%u cMinReqs=%u cDone=%u\n",
     928                                            cReqs, cMinReqs, cDone));
    826929            cReqs    -= cDone;
    827930            cMinReqs -= cDone;
Note: See TracChangeset for help on using the changeset viewer.

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