Changeset 46739 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Jun 23, 2013 4:10:25 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/allocex-r3-posix.cpp
r46729 r46739 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Memory Allocation, Extended Alloc and Free Functions for Ring-3, posix.3 * IPRT - Memory Allocation, Extended Alloc Workers, posix. 4 4 */ 5 5 … … 35 35 #include <iprt/assert.h> 36 36 #include <iprt/string.h> 37 #include " internal/magics.h"37 #include "../allocex.h" 38 38 39 39 #include <sys/mman.h> 40 40 41 41 42 /******************************************************************************* 43 * Structures and Typedefs * 44 *******************************************************************************/ 45 /** 46 * Heading for extended memory allocations in ring-3. 47 */ 48 typedef struct RTMEMHDRR3 42 DECLHIDDEN(int) rtMemAllocEx16BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv) 49 43 { 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 } 61 71 62 72 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) 73 DECLHIDDEN(int) rtMemAllocEx32BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv) 71 74 { 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) 75 79 { 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; 95 82 } 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; 100 84 101 85 #elif defined(RT_OS_LINUX) 102 86 # 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 } 106 93 # endif 107 94 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... */ 112 98 #else 113 pv = NULL;114 99 #endif 115 } 116 return pv; 100 return VERR_NOT_SUPPORTED; 117 101 } 118 102 119 103 120 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW 104 DECLHIDDEN(void) rtMemFreeExYyBitReach(void *pv, size_t cb, uint32_t fFlags) 121 105 { 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 } 129 108 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 else140 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 else159 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_THROW179 {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 else194 RTMemFree(pHdr);195 }196 RT_EXPORT_SYMBOL(RTMemFreeEx);197
Note:
See TracChangeset
for help on using the changeset viewer.