VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/alloc-ef.cpp@ 40532

Last change on this file since 40532 was 39443, checked in by vboxsync, 13 years ago

Introduced RTThreadSleepNoLog for spinlocking in the electric fence heap. (Caused trouble with all logging enabled.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 22.0 KB
Line 
1/* $Id: alloc-ef.cpp 39443 2011-11-28 15:01:21Z vboxsync $ */
2/** @file
3 * IPRT - Memory Allocation, electric fence.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "alloc-ef.h"
32#include <iprt/mem.h>
33#include <iprt/log.h>
34#include <iprt/asm.h>
35#include <iprt/thread.h>
36#include <VBox/sup.h>
37#include <iprt/err.h>
38#include <errno.h>
39#include <stdio.h>
40#include <stdlib.h>
41
42#include <iprt/alloc.h>
43#include <iprt/assert.h>
44#include <iprt/param.h>
45#include <iprt/string.h>
46
47
48/*******************************************************************************
49* Global Variables *
50*******************************************************************************/
51#ifdef RTALLOC_EFENCE_TRACE
52/** Spinlock protecting the all the block's globals. */
53static volatile uint32_t g_BlocksLock;
54/** Tree tracking the allocations. */
55static AVLPVTREE g_BlocksTree;
56# ifdef RTALLOC_EFENCE_FREE_DELAYED
57/** Tail of the delayed blocks. */
58static volatile PRTMEMBLOCK g_pBlocksDelayHead;
59/** Tail of the delayed blocks. */
60static volatile PRTMEMBLOCK g_pBlocksDelayTail;
61/** Number of bytes in the delay list (includes fences). */
62static volatile size_t g_cbBlocksDelay;
63# endif /* RTALLOC_EFENCE_FREE_DELAYED */
64#endif /* RTALLOC_EFENCE_TRACE */
65/** Array of pointers free watches for. */
66void *gapvRTMemFreeWatch[4] = {NULL, NULL, NULL, NULL};
67/** Enable logging of all freed memory. */
68bool gfRTMemFreeLog = false;
69
70
71/*******************************************************************************
72* Internal Functions *
73*******************************************************************************/
74/**
75 * Complains about something.
76 */
77static void rtmemComplain(const char *pszOp, const char *pszFormat, ...)
78{
79 va_list args;
80 fprintf(stderr, "RTMem error: %s: ", pszOp);
81 va_start(args, pszFormat);
82 vfprintf(stderr, pszFormat, args);
83 va_end(args);
84 RTAssertDoPanic();
85}
86
87/**
88 * Log an event.
89 */
90DECLINLINE(void) rtmemLog(const char *pszOp, const char *pszFormat, ...)
91{
92#if 0
93 va_list args;
94 fprintf(stderr, "RTMem info: %s: ", pszOp);
95 va_start(args, pszFormat);
96 vfprintf(stderr, pszFormat, args);
97 va_end(args);
98#else
99 NOREF(pszOp); NOREF(pszFormat);
100#endif
101}
102
103
104#ifdef RTALLOC_EFENCE_TRACE
105
106/**
107 * Acquires the lock.
108 */
109DECLINLINE(void) rtmemBlockLock(void)
110{
111 unsigned c = 0;
112 while (!ASMAtomicCmpXchgU32(&g_BlocksLock, 1, 0))
113 RTThreadSleepNoLog(((++c) >> 2) & 31);
114}
115
116
117/**
118 * Releases the lock.
119 */
120DECLINLINE(void) rtmemBlockUnlock(void)
121{
122 Assert(g_BlocksLock == 1);
123 ASMAtomicXchgU32(&g_BlocksLock, 0);
124}
125
126
127/**
128 * Creates a block.
129 */
130DECLINLINE(PRTMEMBLOCK) rtmemBlockCreate(RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned,
131 const char *pszTag, void *pvCaller, RT_SRC_POS_DECL)
132{
133 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)malloc(sizeof(*pBlock));
134 if (pBlock)
135 {
136 pBlock->enmType = enmType;
137 pBlock->cbUnaligned = cbUnaligned;
138 pBlock->cbAligned = cbAligned;
139 pBlock->pszTag = pszTag;
140 pBlock->pvCaller = pvCaller;
141 pBlock->iLine = iLine;
142 pBlock->pszFile = pszFile;
143 pBlock->pszFunction = pszFunction;
144 }
145 return pBlock;
146}
147
148
149/**
150 * Frees a block.
151 */
152DECLINLINE(void) rtmemBlockFree(PRTMEMBLOCK pBlock)
153{
154 free(pBlock);
155}
156
157
158/**
159 * Insert a block from the tree.
160 */
161DECLINLINE(void) rtmemBlockInsert(PRTMEMBLOCK pBlock, void *pv)
162{
163 pBlock->Core.Key = pv;
164 rtmemBlockLock();
165 bool fRc = RTAvlPVInsert(&g_BlocksTree, &pBlock->Core);
166 rtmemBlockUnlock();
167 AssertRelease(fRc);
168}
169
170
171/**
172 * Remove a block from the tree and returns it to the caller.
173 */
174DECLINLINE(PRTMEMBLOCK) rtmemBlockRemove(void *pv)
175{
176 rtmemBlockLock();
177 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)RTAvlPVRemove(&g_BlocksTree, pv);
178 rtmemBlockUnlock();
179 return pBlock;
180}
181
182/**
183 * Gets a block.
184 */
185DECLINLINE(PRTMEMBLOCK) rtmemBlockGet(void *pv)
186{
187 rtmemBlockLock();
188 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)RTAvlPVGet(&g_BlocksTree, pv);
189 rtmemBlockUnlock();
190 return pBlock;
191}
192
193/**
194 * Dumps one allocation.
195 */
196static DECLCALLBACK(int) RTMemDumpOne(PAVLPVNODECORE pNode, void *pvUser)
197{
198 PRTMEMBLOCK pBlock = (PRTMEMBLOCK)pNode;
199 fprintf(stderr, "%p %08lx(+%02lx) %p\n",
200 pBlock->Core.Key,
201 (unsigned long)pBlock->cbUnaligned,
202 (unsigned long)(pBlock->cbAligned - pBlock->cbUnaligned),
203 pBlock->pvCaller);
204 NOREF(pvUser);
205 return 0;
206}
207
208/**
209 * Dumps the allocated blocks.
210 * This is something which you should call from gdb.
211 */
212extern "C" void RTMemDump(void);
213void RTMemDump(void)
214{
215 fprintf(stderr, "address size(alg) caller\n");
216 RTAvlPVDoWithAll(&g_BlocksTree, true, RTMemDumpOne, NULL);
217}
218
219# ifdef RTALLOC_EFENCE_FREE_DELAYED
220
221/**
222 * Insert a delayed block.
223 */
224DECLINLINE(void) rtmemBlockDelayInsert(PRTMEMBLOCK pBlock)
225{
226 size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
227 pBlock->Core.pRight = NULL;
228 pBlock->Core.pLeft = NULL;
229 rtmemBlockLock();
230 if (g_pBlocksDelayHead)
231 {
232 g_pBlocksDelayHead->Core.pLeft = (PAVLPVNODECORE)pBlock;
233 pBlock->Core.pRight = (PAVLPVNODECORE)g_pBlocksDelayHead;
234 g_pBlocksDelayHead = pBlock;
235 }
236 else
237 {
238 g_pBlocksDelayTail = pBlock;
239 g_pBlocksDelayHead = pBlock;
240 }
241 g_cbBlocksDelay += cbBlock;
242 rtmemBlockUnlock();
243}
244
245/**
246 * Removes a delayed block.
247 */
248DECLINLINE(PRTMEMBLOCK) rtmemBlockDelayRemove(void)
249{
250 PRTMEMBLOCK pBlock = NULL;
251 rtmemBlockLock();
252 if (g_cbBlocksDelay > RTALLOC_EFENCE_FREE_DELAYED)
253 {
254 pBlock = g_pBlocksDelayTail;
255 if (pBlock)
256 {
257 g_pBlocksDelayTail = (PRTMEMBLOCK)pBlock->Core.pLeft;
258 if (pBlock->Core.pLeft)
259 pBlock->Core.pLeft->pRight = NULL;
260 else
261 g_pBlocksDelayHead = NULL;
262 g_cbBlocksDelay -= RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
263 }
264 }
265 rtmemBlockUnlock();
266 return pBlock;
267}
268
269# endif /* RTALLOC_EFENCE_FREE_DELAYED */
270
271#endif /* RTALLOC_EFENCE_TRACE */
272
273
274/**
275 * Internal allocator.
276 */
277RTDECL(void *) rtR3MemAlloc(const char *pszOp, RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned,
278 const char *pszTag, void *pvCaller, RT_SRC_POS_DECL)
279{
280 /*
281 * Sanity.
282 */
283 if ( RT_ALIGN_Z(RTALLOC_EFENCE_SIZE, PAGE_SIZE) != RTALLOC_EFENCE_SIZE
284 && RTALLOC_EFENCE_SIZE <= 0)
285 {
286 rtmemComplain(pszOp, "Invalid E-fence size! %#x\n", RTALLOC_EFENCE_SIZE);
287 return NULL;
288 }
289 if (!cbUnaligned)
290 {
291#if 0
292 rtmemComplain(pszOp, "Request of ZERO bytes allocation!\n");
293 return NULL;
294#else
295 cbAligned = cbUnaligned = 1;
296#endif
297 }
298
299#ifndef RTALLOC_EFENCE_IN_FRONT
300 /* Alignment decreases fence accuracy, but this is at least partially
301 * counteracted by filling and checking the alignment padding. When the
302 * fence is in front then then no extra alignment is needed. */
303 cbAligned = RT_ALIGN_Z(cbAligned, RTALLOC_EFENCE_ALIGNMENT);
304#endif
305
306#ifdef RTALLOC_EFENCE_TRACE
307 /*
308 * Allocate the trace block.
309 */
310 PRTMEMBLOCK pBlock = rtmemBlockCreate(enmType, cbUnaligned, cbAligned, pszTag, pvCaller, RT_SRC_POS_ARGS);
311 if (!pBlock)
312 {
313 rtmemComplain(pszOp, "Failed to allocate trace block!\n");
314 return NULL;
315 }
316#endif
317
318 /*
319 * Allocate a block with page alignment space + the size of the E-fence.
320 */
321 size_t cbBlock = RT_ALIGN_Z(cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
322 void *pvBlock = RTMemPageAlloc(cbBlock);
323 if (pvBlock)
324 {
325 /*
326 * Calc the start of the fence and the user block
327 * and then change the page protection of the fence.
328 */
329#ifdef RTALLOC_EFENCE_IN_FRONT
330 void *pvEFence = pvBlock;
331 void *pv = (char *)pvEFence + RTALLOC_EFENCE_SIZE;
332# ifdef RTALLOC_EFENCE_NOMAN_FILLER
333 memset((char *)pv + cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER, cbBlock - RTALLOC_EFENCE_SIZE - cbUnaligned);
334# endif
335#else
336 void *pvEFence = (char *)pvBlock + (cbBlock - RTALLOC_EFENCE_SIZE);
337 void *pv = (char *)pvEFence - cbAligned;
338# ifdef RTALLOC_EFENCE_NOMAN_FILLER
339 memset(pvBlock, RTALLOC_EFENCE_NOMAN_FILLER, cbBlock - RTALLOC_EFENCE_SIZE - cbAligned);
340 memset((char *)pv + cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER, cbAligned - cbUnaligned);
341# endif
342#endif
343
344#ifdef RTALLOC_EFENCE_FENCE_FILLER
345 memset(pvEFence, RTALLOC_EFENCE_FENCE_FILLER, RTALLOC_EFENCE_SIZE);
346#endif
347 int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_NONE);
348 if (!rc)
349 {
350#ifdef RTALLOC_EFENCE_TRACE
351 rtmemBlockInsert(pBlock, pv);
352#endif
353 if (enmType == RTMEMTYPE_RTMEMALLOCZ)
354 memset(pv, 0, cbUnaligned);
355#ifdef RTALLOC_EFENCE_FILLER
356 else
357 memset(pv, RTALLOC_EFENCE_FILLER, cbUnaligned);
358#endif
359
360 rtmemLog(pszOp, "returns %p (pvBlock=%p cbBlock=%#x pvEFence=%p cbUnaligned=%#x)\n", pv, pvBlock, cbBlock, pvEFence, cbUnaligned);
361 return pv;
362 }
363 rtmemComplain(pszOp, "RTMemProtect failed, pvEFence=%p size %d, rc=%d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc);
364 RTMemPageFree(pvBlock, cbBlock);
365 }
366 else
367 rtmemComplain(pszOp, "Failed to allocated %lu (%lu) bytes.\n", (unsigned long)cbBlock, (unsigned long)cbUnaligned);
368
369#ifdef RTALLOC_EFENCE_TRACE
370 rtmemBlockFree(pBlock);
371#endif
372 return NULL;
373}
374
375
376/**
377 * Internal free.
378 */
379RTDECL(void) rtR3MemFree(const char *pszOp, RTMEMTYPE enmType, void *pv, void *pvCaller, RT_SRC_POS_DECL)
380{
381 NOREF(enmType); RT_SRC_POS_NOREF();
382
383 /*
384 * Simple case.
385 */
386 if (!pv)
387 return;
388
389 /*
390 * Check watch points.
391 */
392 for (unsigned i = 0; i < RT_ELEMENTS(gapvRTMemFreeWatch); i++)
393 if (gapvRTMemFreeWatch[i] == pv)
394 RTAssertDoPanic();
395
396#ifdef RTALLOC_EFENCE_TRACE
397 /*
398 * Find the block.
399 */
400 PRTMEMBLOCK pBlock = rtmemBlockRemove(pv);
401 if (pBlock)
402 {
403 if (gfRTMemFreeLog)
404 RTLogPrintf("RTMem %s: pv=%p pvCaller=%p cbUnaligned=%#x\n", pszOp, pv, pvCaller, pBlock->cbUnaligned);
405
406# ifdef RTALLOC_EFENCE_NOMAN_FILLER
407 /*
408 * Check whether the no man's land is untouched.
409 */
410# ifdef RTALLOC_EFENCE_IN_FRONT
411 void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned,
412 RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbUnaligned,
413 RTALLOC_EFENCE_NOMAN_FILLER);
414# else
415 /* Alignment must match allocation alignment in rtMemAlloc(). */
416 void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned,
417 pBlock->cbAligned - pBlock->cbUnaligned,
418 RTALLOC_EFENCE_NOMAN_FILLER);
419 if (pvWrong)
420 RTAssertDoPanic();
421 pvWrong = ASMMemIsAll8((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK),
422 RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbAligned,
423 RTALLOC_EFENCE_NOMAN_FILLER);
424# endif
425 if (pvWrong)
426 RTAssertDoPanic();
427# endif
428
429# ifdef RTALLOC_EFENCE_FREE_FILL
430 /*
431 * Fill the user part of the block.
432 */
433 memset(pv, RTALLOC_EFENCE_FREE_FILL, pBlock->cbUnaligned);
434# endif
435
436# if defined(RTALLOC_EFENCE_FREE_DELAYED) && RTALLOC_EFENCE_FREE_DELAYED > 0
437 /*
438 * We're doing delayed freeing.
439 * That means we'll expand the E-fence to cover the entire block.
440 */
441 int rc = RTMemProtect(pv, pBlock->cbAligned, RTMEM_PROT_NONE);
442 if (RT_SUCCESS(rc))
443 {
444 /*
445 * Insert it into the free list and process pending frees.
446 */
447 rtmemBlockDelayInsert(pBlock);
448 while ((pBlock = rtmemBlockDelayRemove()) != NULL)
449 {
450 pv = pBlock->Core.Key;
451# ifdef RTALLOC_EFENCE_IN_FRONT
452 void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE;
453# else
454 void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
455# endif
456 size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE;
457 rc = RTMemProtect(pvBlock, cbBlock, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
458 if (RT_SUCCESS(rc))
459 RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE);
460 else
461 rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvBlock, cbBlock, rc);
462 rtmemBlockFree(pBlock);
463 }
464 }
465 else
466 rtmemComplain(pszOp, "Failed to expand the efence of pv=%p cb=%d, rc=%d.\n", pv, pBlock, rc);
467
468# else /* !RTALLOC_EFENCE_FREE_DELAYED */
469
470 /*
471 * Turn of the E-fence and free it.
472 */
473# ifdef RTALLOC_EFENCE_IN_FRONT
474 void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE;
475 void *pvEFence = pvBlock;
476# else
477 void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK);
478 void *pvEFence = (char *)pv + pBlock->cb;
479# endif
480 int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
481 if (RT_SUCCESS(rc))
482 RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE);
483 else
484 rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc);
485 rtmemBlockFree(pBlock);
486
487# endif /* !RTALLOC_EFENCE_FREE_DELAYED */
488 }
489 else
490 rtmemComplain(pszOp, "pv=%p not found! Incorrect free!\n", pv);
491
492#else /* !RTALLOC_EFENCE_TRACE */
493
494 /*
495 * We have no size tracking, so we're not doing any freeing because
496 * we cannot if the E-fence is after the block.
497 * Let's just expand the E-fence to the first page of the user bit
498 * since we know that it's around.
499 */
500 int rc = RTMemProtect((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), PAGE_SIZE, RTMEM_PROT_NONE);
501 if (RT_FAILURE(rc))
502 rtmemComplain(pszOp, "RTMemProtect(%p, PAGE_SIZE, RTMEM_PROT_NONE) -> %d\n", (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), rc);
503#endif /* !RTALLOC_EFENCE_TRACE */
504}
505
506
507/**
508 * Internal realloc.
509 */
510RTDECL(void *) rtR3MemRealloc(const char *pszOp, RTMEMTYPE enmType, void *pvOld, size_t cbNew,
511 const char *pszTag, void *pvCaller, RT_SRC_POS_DECL)
512{
513 /*
514 * Allocate new and copy.
515 */
516 if (!pvOld)
517 return rtR3MemAlloc(pszOp, enmType, cbNew, cbNew, pszTag, pvCaller, RT_SRC_POS_ARGS);
518 if (!cbNew)
519 {
520 rtR3MemFree(pszOp, RTMEMTYPE_RTMEMREALLOC, pvOld, pvCaller, RT_SRC_POS_ARGS);
521 return NULL;
522 }
523
524#ifdef RTALLOC_EFENCE_TRACE
525
526 /*
527 * Get the block, allocate the new, copy the data, free the old one.
528 */
529 PRTMEMBLOCK pBlock = rtmemBlockGet(pvOld);
530 if (pBlock)
531 {
532 void *pvRet = rtR3MemAlloc(pszOp, enmType, cbNew, cbNew, pszTag, pvCaller, RT_SRC_POS_ARGS);
533 if (pvRet)
534 {
535 memcpy(pvRet, pvOld, RT_MIN(cbNew, pBlock->cbUnaligned));
536 rtR3MemFree(pszOp, RTMEMTYPE_RTMEMREALLOC, pvOld, pvCaller, RT_SRC_POS_ARGS);
537 }
538 return pvRet;
539 }
540 else
541 rtmemComplain(pszOp, "pvOld=%p was not found!\n", pvOld);
542 return NULL;
543
544#else /* !RTALLOC_EFENCE_TRACE */
545
546 rtmemComplain(pszOp, "Not supported if RTALLOC_EFENCE_TRACE isn't defined!\n");
547 return NULL;
548
549#endif /* !RTALLOC_EFENCE_TRACE */
550}
551
552
553
554
555RTDECL(void *) RTMemEfTmpAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
556{
557 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
558}
559
560
561RTDECL(void *) RTMemEfTmpAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
562{
563 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
564}
565
566
567RTDECL(void) RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW
568{
569 if (pv)
570 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), RT_SRC_POS_ARGS);
571}
572
573
574RTDECL(void *) RTMemEfAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
575{
576 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
577}
578
579
580RTDECL(void *) RTMemEfAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
581{
582 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
583}
584
585
586RTDECL(void *) RTMemEfAllocVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
587{
588 size_t cbAligned;
589 if (cbUnaligned >= 16)
590 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
591 else
592 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
593 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
594}
595
596
597RTDECL(void *) RTMemEfAllocZVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
598{
599 size_t cbAligned;
600 if (cbUnaligned >= 16)
601 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
602 else
603 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
604 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
605}
606
607
608RTDECL(void *) RTMemEfRealloc(void *pvOld, size_t cbNew, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
609{
610 return rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, pszTag, ASMReturnAddress(), RT_SRC_POS_ARGS);
611}
612
613
614RTDECL(void) RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW
615{
616 if (pv)
617 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), RT_SRC_POS_ARGS);
618}
619
620
621RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
622{
623 void *pvDst = RTMemEfAlloc(cb, pszTag, RT_SRC_POS_ARGS);
624 if (pvDst)
625 memcpy(pvDst, pvSrc, cb);
626 return pvDst;
627}
628
629
630RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW
631{
632 void *pvDst = RTMemEfAlloc(cbSrc + cbExtra, pszTag, RT_SRC_POS_ARGS);
633 if (pvDst)
634 {
635 memcpy(pvDst, pvSrc, cbSrc);
636 memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
637 }
638 return pvDst;
639}
640
641
642
643
644/*
645 *
646 * The NP (no position) versions.
647 *
648 */
649
650
651
652RTDECL(void *) RTMemEfTmpAllocNP(size_t cb, const char *pszTag) RT_NO_THROW
653{
654 return rtR3MemAlloc("TmpAlloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
655}
656
657
658RTDECL(void *) RTMemEfTmpAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW
659{
660 return rtR3MemAlloc("TmpAllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
661}
662
663
664RTDECL(void) RTMemEfTmpFreeNP(void *pv) RT_NO_THROW
665{
666 if (pv)
667 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
668}
669
670
671RTDECL(void *) RTMemEfAllocNP(size_t cb, const char *pszTag) RT_NO_THROW
672{
673 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
674}
675
676
677RTDECL(void *) RTMemEfAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW
678{
679 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
680}
681
682
683RTDECL(void *) RTMemEfAllocVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW
684{
685 size_t cbAligned;
686 if (cbUnaligned >= 16)
687 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
688 else
689 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
690 return rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), NULL, 0, NULL);
691}
692
693
694RTDECL(void *) RTMemEfAllocZVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW
695{
696 size_t cbAligned;
697 if (cbUnaligned >= 16)
698 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
699 else
700 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
701 return rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), NULL, 0, NULL);
702}
703
704
705RTDECL(void *) RTMemEfReallocNP(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW
706{
707 return rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, pszTag, ASMReturnAddress(), NULL, 0, NULL);
708}
709
710
711RTDECL(void) RTMemEfFreeNP(void *pv) RT_NO_THROW
712{
713 if (pv)
714 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, ASMReturnAddress(), NULL, 0, NULL);
715}
716
717
718RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW
719{
720 void *pvDst = RTMemEfAlloc(cb, pszTag, NULL, 0, NULL);
721 if (pvDst)
722 memcpy(pvDst, pvSrc, cb);
723 return pvDst;
724}
725
726
727RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW
728{
729 void *pvDst = RTMemEfAlloc(cbSrc + cbExtra, pszTag, NULL, 0, NULL);
730 if (pvDst)
731 {
732 memcpy(pvDst, pvSrc, cbSrc);
733 memset((uint8_t *)pvDst + cbSrc, 0, cbExtra);
734 }
735 return pvDst;
736}
737
Note: See TracBrowser for help on using the repository browser.

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