VirtualBox

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


Ignore:
Timestamp:
Jun 23, 2013 4:10:25 PM (11 years ago)
Author:
vboxsync
Message:

reorged the allocex bits in ring3.

File:
1 edited

Legend:

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

    r46729 r46739  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Memory Allocation, Extended Alloc and Free Functions for Ring-3, posix.
     3 * IPRT - Memory Allocation, Extended Alloc Workers, posix.
    44 */
    55
     
    3535#include <iprt/assert.h>
    3636#include <iprt/string.h>
    37 #include "internal/magics.h"
     37#include "../allocex.h"
    3838
    3939#include <sys/mman.h>
    4040
    4141
    42 /*******************************************************************************
    43 *   Structures and Typedefs                                                    *
    44 *******************************************************************************/
    45 /**
    46  * Heading for extended memory allocations in ring-3.
    47  */
    48 typedef struct RTMEMHDRR3
     42DECLHIDDEN(int) rtMemAllocEx16BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    4943{
    50     /** Magic (RTMEMHDR_MAGIC). */
    51     uint32_t    u32Magic;
    52     /** Block flags (RTMEMALLOCEX_FLAGS_*). */
    53     uint32_t    fFlags;
    54     /** The actual size of the block, header not included. */
    55     uint32_t    cb;
    56     /** The requested allocation size. */
    57     uint32_t    cbReq;
    58 } RTMEMHDRR3;
    59 /** Pointer to a ring-3 extended memory header. */
    60 typedef RTMEMHDRR3 *PRTMEMHDRR3;
     44    AssertReturn(cbAlloc < _64K, NULL);
     45
     46    /*
     47     * Try with every possible address hint since the possible range is very limited.
     48     */
     49    int       fProt     = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
     50    uintptr_t uAddr     = 0x1000;
     51    uintptr_t uAddrLast = _64K - uAddr - cbAlloc;
     52    while (uAddr <= uAddrLast)
     53    {
     54        void *pv = mmap((void *)uAddr, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     55        if (pv && (uintptr_t)pv <= uAddrLast)
     56        {
     57            *ppv = pv;
     58            return VINF_SUCCESS;
     59        }
     60
     61        if (pv)
     62        {
     63            munmap(pv, cbAlloc);
     64            pv = NULL;
     65        }
     66        uAddr += _4K;
     67    }
     68
     69    return VERR_NO_MEMORY;
     70}
    6171
    6272
    63 /**
    64  * Allocates memory with upper boundrary.
    65  *
    66  * @returns Pointer to mmap allocation.
    67  * @param   cbAlloc             Number of bytes to alloacate.
    68  * @param   fFlags              Allocation flags.
    69  */
    70 static void *rtMemAllocExAllocLow(size_t cbAlloc, uint32_t fFlags)
     73DECLHIDDEN(int) rtMemAllocEx32BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    7174{
    72     int   fProt = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
    73     void *pv    = NULL;
    74     if (fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH)
     75    int     fProt = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
     76#if ARCH_BITS == 32
     77    void   *pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     78    if (pv)
    7579    {
    76         AssertReturn(cbAlloc < _64K, NULL);
    77 
    78         /*
    79          * Try with every possible address hint since the possible range is very limited.
    80          */
    81         uintptr_t uAddr     = fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH ? 0x1000  : _1M;
    82         uintptr_t uAddrLast = _64K - uAddr - cbAlloc;
    83         while (uAddr <= uAddrLast)
    84         {
    85             pv = mmap((void *)uAddr, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    86             if (pv && (uintptr_t)pv <= uAddrLast)
    87                 break;
    88             if (pv)
    89             {
    90                 munmap(pv, cbAlloc);
    91                 pv = NULL;
    92             }
    93             uAddr += _4K;
    94         }
     80        *ppv = pv;
     81        return VINF_SUCCESS;
    9582    }
    96     else
    97     {
    98 #if ARCH_BITS == 32
    99         pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     83    return VERR_NO_MEMORY;
    10084
    10185#elif defined(RT_OS_LINUX)
    10286# ifdef MAP_32BIT
    103         pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
    104         if (pv)
    105             return pv;
     87    void *pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
     88    if (pv)
     89    {
     90        *ppv = pv;
     91        return VINF_SUCCESS;
     92    }
    10693# endif
    10794
    108         /** @todo On linux, we need an accurate hint. Since I don't need this branch of
    109          *        the code right now, I won't bother starting to parse
    110          *        /proc/curproc/mmap right now... */
    111         pv = NULL;
     95    /** @todo On linux, we need an accurate hint. Since I don't need this branch of
     96     *        the code right now, I won't bother starting to parse
     97     *        /proc/curproc/mmap right now... */
    11298#else
    113         pv = NULL;
    11499#endif
    115     }
    116     return pv;
     100    return VERR_NOT_SUPPORTED;
    117101}
    118102
    119103
    120 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW
     104DECLHIDDEN(void) rtMemFreeExYyBitReach(void *pv, size_t cb, uint32_t fFlags)
    121105{
    122     /*
    123      * Validate and adjust input.
    124      */
    125     AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
    126     AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
    127     AssertReturn(RT_IS_POWER_OF_TWO(cbAlignment), VERR_INVALID_PARAMETER);
    128     AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
     106    munmap(pv, cb);
     107}
    129108
    130     if (fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX)
    131         return VERR_NOT_SUPPORTED;
    132 
    133     /*
    134      * Align the request.
    135      */
    136     size_t cbAligned = cb;
    137     if (cbAlignment)
    138         cbAligned = RT_ALIGN_Z(cb, cbAlignment);
    139     else
    140         cbAligned = RT_ALIGN_Z(cb, sizeof(uint64_t));
    141     AssertMsgReturn(cbAligned >= cb && cbAligned <= ~(size_t)0, ("cbAligned=%#zx cb=%#zx", cbAligned, cb),
    142                     VERR_INVALID_PARAMETER);
    143 
    144     /*
    145      * Allocate the requested memory.
    146      */
    147     void *pv;
    148     if (fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH))
    149         pv = rtMemAllocExAllocLow(cbAligned + sizeof(RTMEMHDRR3), fFlags);
    150     else if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    151     {
    152         pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
    153         if ((fFlags & RTMEMALLOCEX_FLAGS_ZEROED) && pv)
    154             RT_BZERO(pv, cbAligned + sizeof(RTMEMHDRR3));
    155     }
    156     else if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
    157         pv = RTMemAllocZ(cbAligned + sizeof(RTMEMHDRR3));
    158     else
    159         pv = RTMemAlloc(cbAligned + sizeof(RTMEMHDRR3));
    160     if (!pv)
    161         return VERR_NO_MEMORY;
    162 
    163     /*
    164      * Fill in the header and return.
    165      */
    166     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv;
    167     pHdr->u32Magic  = RTMEMHDR_MAGIC;
    168     pHdr->fFlags    = fFlags;
    169     pHdr->cb        = cbAligned;
    170     pHdr->cbReq     = cb;
    171 
    172     *ppv = pHdr + 1;
    173     return VINF_SUCCESS;
    174 }
    175 RT_EXPORT_SYMBOL(RTMemAllocExTag);
    176 
    177 
    178 RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW
    179 {
    180     if (!pv)
    181         return;
    182     AssertPtr(pv);
    183 
    184     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv - 1;
    185     AssertMsg(pHdr->u32Magic == RTMEMHDR_MAGIC, ("pHdr->u32Magic=%RX32 pv=%p cb=%#x\n", pHdr->u32Magic, pv, cb));
    186     pHdr->u32Magic = RTMEMHDR_MAGIC_DEAD;
    187     Assert(pHdr->cbReq == cb);
    188 
    189     if (pHdr->fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH))
    190         munmap(pHdr, pHdr->cb + sizeof(*pHdr));
    191     else if (pHdr->fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    192         RTMemExecFree(pHdr, pHdr->cb + sizeof(*pHdr));
    193     else
    194         RTMemFree(pHdr);
    195 }
    196 RT_EXPORT_SYMBOL(RTMemFreeEx);
    197 
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