VirtualBox

Changeset 33269 in vbox for trunk/src/VBox/Runtime/r3/posix


Ignore:
Timestamp:
Oct 20, 2010 3:42:28 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66829
Message:

IPRT: A quick replacement of the RTMemPage* and RTMemExec* APIs on posix. (Turned out to be a bit more work than expected because of the electric fence heap and init dependencies.)

Location:
trunk/src/VBox/Runtime/r3/posix
Files:
2 added
1 edited
1 moved

Legend:

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

    r33145 r33269  
    3535#include <iprt/string.h>
    3636
    37 #include <stdlib.h>
    38 #ifndef RT_OS_FREEBSD /* Deprecated on FreeBSD */
    39 # include <malloc.h>
    40 #endif
    4137#include <errno.h>
    4238#include <sys/mman.h>
    43 
    44 
    45 /*******************************************************************************
    46 *   Defined Constants And Macros                                               *
    47 *******************************************************************************/
    48 #if !defined(RT_USE_MMAP_EXEC) && (defined(RT_OS_LINUX))
    49 # define RT_USE_MMAP_EXEC
    50 #endif
    51 
    52 #if !defined(RT_USE_MMAP_PAGE) && 0 /** @todo mmap is too slow for full scale EF setup. */
    53 # define RT_USE_MMAP_PAGE
    54 #endif
    55 
    56 
    57 /*******************************************************************************
    58 *   Structures and Typedefs                                                    *
    59 *******************************************************************************/
    60 #ifdef RT_USE_MMAP_EXEC
    61 /**
    62  * RTMemExecAlloc() header used when using mmap for allocating the memory.
    63  */
    64 typedef struct RTMEMEXECHDR
    65 {
    66     /** Magic number (RTMEMEXECHDR_MAGIC). */
    67     size_t      uMagic;
    68     /** The size we requested from mmap. */
    69     size_t      cb;
    70 # if ARCH_BITS == 32
    71     uint32_t    Alignment[2];
    72 # endif
    73 } RTMEMEXECHDR, *PRTMEMEXECHDR;
    74 
    75 /** Magic for RTMEMEXECHDR. */
    76 # define RTMEMEXECHDR_MAGIC (~(size_t)0xfeedbabe)
    77 
    78 #endif  /* RT_USE_MMAP_EXEC */
    79 
    80 
    81 
    82 RTDECL(void *) RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW
    83 {
    84     AssertMsg(cb, ("Allocating ZERO bytes is really not a good idea! Good luck with the next assertion!\n"));
    85 
    86 #ifdef RT_USE_MMAP_EXEC
    87     /*
    88      * Use mmap to get low memory.
    89      */
    90     size_t cbAlloc = RT_ALIGN_Z(cb + sizeof(RTMEMEXECHDR), PAGE_SIZE);
    91     void *pv = mmap(NULL, cbAlloc, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS
    92 # if defined(RT_ARCH_AMD64) && defined(MAP_32BIT)
    93                     | MAP_32BIT
    94 # endif
    95                     , -1, 0);
    96     AssertMsgReturn(pv != MAP_FAILED, ("errno=%d cb=%#zx\n", errno, cb), NULL);
    97     PRTMEMEXECHDR pHdr = (PRTMEMEXECHDR)pv;
    98     pHdr->uMagic = RTMEMEXECHDR_MAGIC;
    99     pHdr->cb = cbAlloc;
    100     pv = pHdr + 1;
    101 
    102 #else
    103     /*
    104      * Allocate first.
    105      */
    106     cb = RT_ALIGN_Z(cb, 32);
    107     void *pv = NULL;
    108     int rc = posix_memalign(&pv, 32, cb);
    109     AssertMsg(!rc && pv, ("posix_memalign(%zd) failed!!! rc=%d\n", cb, rc));
    110     if (pv && !rc)
    111     {
    112         /*
    113          * Add PROT_EXEC flag to the page.
    114          *
    115          * This is in violation of the SuS where I think it saith that mprotect() shall
    116          * only be used with mmap()'ed memory. Works on linux and OS/2 LIBC v0.6.
    117          */
    118         memset(pv, 0xcc, cb);
    119         void   *pvProt = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
    120         size_t  cbProt = ((uintptr_t)pv & PAGE_OFFSET_MASK) + cb;
    121         cbProt = RT_ALIGN_Z(cbProt, PAGE_SIZE);
    122         rc = mprotect(pvProt, cbProt, PROT_READ | PROT_WRITE | PROT_EXEC);
    123         if (rc)
    124         {
    125             AssertMsgFailed(("mprotect(%p, %#zx,,) -> rc=%d, errno=%d\n", pvProt, cbProt, rc, errno));
    126             free(pv);
    127             pv = NULL;
    128         }
    129     }
    130 #endif
    131     return pv;
    132 }
    133 
    134 
    135 RTDECL(void)    RTMemExecFree(void *pv) RT_NO_THROW
    136 {
    137     if (pv)
    138     {
    139 #ifdef RT_USE_MMAP_EXEC
    140         PRTMEMEXECHDR pHdr = (PRTMEMEXECHDR)pv - 1;
    141         AssertMsgReturnVoid(RT_ALIGN_P(pHdr, PAGE_SIZE) == pHdr, ("pHdr=%p pv=%p\n", pHdr, pv));
    142         AssertMsgReturnVoid(pHdr->uMagic == RTMEMEXECHDR_MAGIC, ("pHdr=%p(uMagic=%#zx) pv=%p\n", pHdr, pHdr->uMagic, pv));
    143         int rc = munmap(pHdr, pHdr->cb);
    144         AssertMsg(!rc, ("munmap -> %d errno=%d\n", rc, errno)); NOREF(rc);
    145 #else
    146         free(pv);
    147 #endif
    148     }
    149 }
    150 
    151 
    152 RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW
    153 {
    154 #ifdef RT_USE_MMAP_PAGE
    155     size_t  cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
    156     void   *pv = mmap(NULL, cbAligned, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    157     AssertMsgReturn(pv != MAP_FAILED, ("errno=%d cb=%#zx\n", errno, cb), NULL);
    158     return pv;
    159 
    160 #else
    161 # if defined(RT_OS_FREEBSD) /** @todo huh? we're using posix_memalign in the next function... */
    162     void *pv;
    163     int rc = posix_memalign(&pv, PAGE_SIZE, RT_ALIGN_Z(cb, PAGE_SIZE));
    164     if (!rc)
    165         return pv;
    166     return NULL;
    167 # else /* !RT_OS_FREEBSD */
    168     return memalign(PAGE_SIZE, cb);
    169 # endif
    170 #endif
    171 }
    172 
    173 
    174 RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW
    175 {
    176 #ifdef RT_USE_MMAP_PAGE
    177     size_t  cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
    178     void   *pv = mmap(NULL, cbAligned, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    179     AssertMsgReturn(pv != MAP_FAILED, ("errno=%d cb=%#zx\n", errno, cb), NULL);
    180     return pv;
    181 
    182 #else
    183     void *pv;
    184     int rc = posix_memalign(&pv, PAGE_SIZE, RT_ALIGN_Z(cb, PAGE_SIZE));
    185     if (!rc)
    186     {
    187         RT_BZERO(pv, RT_ALIGN_Z(cb, PAGE_SIZE));
    188         return pv;
    189     }
    190     return NULL;
    191 #endif
    192 }
    193 
    194 
    195 RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW
    196 {
    197     if (pv)
    198     {
    199         Assert(!((uintptr_t)pv & PAGE_OFFSET_MASK));
    200 
    201 #ifdef RT_USE_MMAP_PAGE
    202         size_t cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
    203         int rc = munmap(pv, cbAligned);
    204         AssertMsg(!rc, ("munmap(%p, %#zx) -> %d errno=%d\n", pv, cbAligned, rc, errno)); NOREF(rc);
    205 #else
    206         free(pv);
    207 #endif
    208     }
    209 }
    21039
    21140
  • trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp

    r28800 r33269  
    3737#include <iprt/lockvalidator.h>
    3838
     39#include "internal/mem.h"
    3940#include "internal/strict.h"
    4041
     
    7980    bool volatile       fEverHadSignallers;
    8081#endif
     82    /** The creation flags. */
     83    uint32_t            fFlags;
    8184};
    8285
     
    100103RTDECL(int)  RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)
    101104{
    102     AssertReturn(!(fFlags & ~RTSEMEVENT_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
     105    AssertReturn(!(fFlags & ~(RTSEMEVENT_FLAGS_NO_LOCK_VAL | RTSEMEVENT_FLAGS_BOOTSTRAP_HACK)), VERR_INVALID_PARAMETER);
     106    Assert(!(fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK) || (fFlags & RTSEMEVENT_FLAGS_NO_LOCK_VAL));
    103107
    104108    /*
     
    106110     */
    107111    int rc;
    108     struct RTSEMEVENTINTERNAL *pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(struct RTSEMEVENTINTERNAL));
     112    struct RTSEMEVENTINTERNAL *pThis;
     113    if (!(fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK))
     114        pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(*pThis));
     115    else
     116        pThis = (struct RTSEMEVENTINTERNAL *)rtMemBaseAlloc(sizeof(*pThis));
    109117    if (pThis)
    110118    {
     
    132140                        pthread_condattr_destroy(&CondAttr);
    133141
    134                         ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
    135                         ASMAtomicXchgU32(&pThis->cWaiters, 0);
     142                        ASMAtomicWriteU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
     143                        ASMAtomicWriteU32(&pThis->cWaiters, 0);
     144                        pThis->fFlags = fFlags;
    136145#ifdef RTSEMEVENT_STRICT
    137146                        if (!pszNameFmt)
     
    166175
    167176        rc = RTErrConvertFromErrno(rc);
    168         RTMemFree(pThis);
     177        if (!(fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK))
     178            RTMemFree(pThis);
     179        else
     180            rtMemBaseFree(pThis);
    169181    }
    170182    else
     
    193205    for (int i = 30; i > 0; i--)
    194206    {
    195         ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_UNINITIALIZED);
     207        ASMAtomicWriteU32(&pThis->u32State, EVENT_STATE_UNINITIALIZED);
    196208        rc = pthread_cond_destroy(&pThis->Cond);
    197209        if (rc != EBUSY)
     
    229241    RTLockValidatorRecSharedDelete(&pThis->Signallers);
    230242#endif
    231     RTMemFree(pThis);
     243    if (!(pThis->fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK))
     244        RTMemFree(pThis);
     245    else
     246        rtMemBaseFree(pThis);
    232247    return VINF_SUCCESS;
    233248}
     
    268283    if (pThis->u32State == EVENT_STATE_NOT_SIGNALED)
    269284    {
    270         ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_SIGNALED);
     285        ASMAtomicWriteU32(&pThis->u32State, EVENT_STATE_SIGNALED);
    271286        rc = pthread_cond_signal(&pThis->Cond);
    272287        AssertMsg(!rc, ("Failed to signal event sem %p, rc=%d.\n", hEventSem, rc));
     
    330345            if (pThis->u32State == EVENT_STATE_SIGNALED)
    331346            {
    332                 ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
     347                ASMAtomicWriteU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
    333348                ASMAtomicDecU32(&pThis->cWaiters);
    334349                rc = pthread_mutex_unlock(&pThis->Mutex);
     
    345360            /* wait */
    346361#ifdef RTSEMEVENT_STRICT
    347             RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     362            RTTHREAD hThreadSelf = !(pThis->fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK)
     363                                 ? RTThreadSelfAutoAdopt()
     364                                 : RTThreadSelf();
    348365            if (pThis->fEverHadSignallers)
    349366            {
     
    416433            if (pThis->u32State == EVENT_STATE_SIGNALED)
    417434            {
    418                 ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
     435                ASMAtomicWriteU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
    419436                ASMAtomicDecU32(&pThis->cWaiters);
    420437                rc = pthread_mutex_unlock(&pThis->Mutex);
     
    439456            /* wait */
    440457#ifdef RTSEMEVENT_STRICT
    441             RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     458            RTTHREAD hThreadSelf = !(pThis->fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK)
     459                                 ? RTThreadSelfAutoAdopt()
     460                                 : RTThreadSelf();
    442461            if (pThis->fEverHadSignallers)
    443462            {
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