Changeset 36529 in vbox for trunk/include/iprt
- Timestamp:
- Apr 4, 2011 1:54:13 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 70953
- Location:
- trunk/include/iprt
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cpp/autores.h
r36508 r36529 1 1 /** @file 2 * IPRT - C++ Extensions: resource lifetime management2 * IPRT - C++ Resource Management. 3 3 */ 4 4 … … 29 29 #include <iprt/types.h> 30 30 #include <iprt/assert.h> 31 32 /** 33 * A simple class used to prevent copying and assignment. 34 * 35 * Inherit from this class in order to prevent automatic generation 36 * of the copy constructor and assignment operator in your class. 37 * 38 * @todo Functionality duplicated by iprt::non_copyable. grr! 39 * 40 * @addtogroup grp_rt_cpp_util 41 */ 42 class RTCNonCopyable 43 { 44 protected: 45 RTCNonCopyable() {} 46 ~RTCNonCopyable() {} 47 private: 48 RTCNonCopyable(RTCNonCopyable const &); 49 RTCNonCopyable const &operator=(RTCNonCopyable const &); 50 }; 31 #include <iprt/cpp/utils.h> 32 51 33 52 34 … … 93 75 * 94 76 * The idea of this class is to manage resources which the current code is 95 * responsible for freeing. By wrapping the resource in an RT AutoRes, you77 * responsible for freeing. By wrapping the resource in an RTCAutoRes, you 96 78 * ensure that the resource will be freed when you leave the scope in which 97 * the RT AutoRes is defined, unless you explicitly release the resource.79 * the RTCAutoRes is defined, unless you explicitly release the resource. 98 80 * 99 81 * A typical use case is when a function is allocating a number of resources. 100 82 * If any single allocation fails then all other resources must be freed. If 101 83 * all allocations succeed, then the resources should be returned to the 102 * caller. By placing all allocated resources in RT AutoRes containers, you84 * caller. By placing all allocated resources in RTCAutoRes containers, you 103 85 * ensure that they will be freed on failure, and only have to take care of 104 86 * releasing them when you return them. … … 116 98 */ 117 99 template <class T, void Destruct(T) = RTAutoResDestruct<T>, T NilRes(void) = RTAutoResNil<T> > 118 class RT AutoRes100 class RTCAutoRes 119 101 : public RTCNonCopyable 120 102 { … … 129 111 * @param a_hRes The handle to resource to manage. Defaults to NIL. 130 112 */ 131 RT AutoRes(T a_hRes = NilRes())113 RTCAutoRes(T a_hRes = NilRes()) 132 114 : m_hRes(a_hRes) 133 115 { … … 139 121 * This destroys any resource currently managed by the object. 140 122 */ 141 ~RT AutoRes()123 ~RTCAutoRes() 142 124 { 143 125 if (m_hRes != NilRes()) … … 153 135 * @param a_hRes The handle to the new resource. 154 136 */ 155 RT AutoRes &operator=(T a_hRes)137 RTCAutoRes &operator=(T a_hRes) 156 138 { 157 139 if (m_hRes != NilRes()) -
trunk/include/iprt/cpp/mem.h
r36526 r36529 1 1 /** @file 2 * IPRT - Memory Management and Manipulation.2 * IPRT - C++ Memory Resource Management. 3 3 */ 4 4 5 5 /* 6 * Copyright (C) 2006-201 0Oracle Corporation6 * Copyright (C) 2006-2011 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 */ 25 25 26 #ifndef ___iprt_mem_h 27 #define ___iprt_mem_h 28 29 30 #include <iprt/cdefs.h> 31 #include <iprt/types.h> 32 #ifdef __cplusplus /** @todo remove when spitting. */ 33 # include <iprt/cpp/autores.h> 34 #endif 35 36 37 #ifdef IN_RC 38 # error "There are no RTMem APIs available Guest Context!" 39 #endif 40 41 42 /** @defgroup grp_rt_mem RTMem - Memory Management and Manipulation 43 * @ingroup grp_rt 26 #ifndef ___iprt_cpp_mem_h 27 #define ___iprt_cpp_mem_h 28 29 #include <iprt/cpp/autores.h> 30 #include <iprt/assert.h> 31 #include <iprt/mem.h> 32 33 /** @defgroup grp_rt_cpp_autores_mem C++ Memory Resource Management 34 * @ingroup grp_rt_cpp_autores 44 35 * @{ 45 36 */ 46 37 47 RT_C_DECLS_BEGIN 48 49 /** @def RTMEM_ALIGNMENT 50 * The alignment of the memory blocks returned by RTMemAlloc(), RTMemAllocZ(), 51 * RTMemRealloc(), RTMemTmpAlloc() and RTMemTmpAllocZ() for allocations greater 52 * than RTMEM_ALIGNMENT. 53 * 54 * @note This alignment is not forced if the electric fence is active! 55 */ 56 #define RTMEM_ALIGNMENT 8 57 58 /** @def RTMEM_TAG 59 * The default allocation tag used by the RTMem allocation APIs. 60 * 61 * When not defined before the inclusion of iprt/mem.h or iprt/memobj.h, this 62 * will default to the pointer to the current file name. The memory API will 63 * make of use of this as pointer to a volatile but read-only string. 64 */ 65 #ifndef RTMEM_TAG 66 # define RTMEM_TAG (__FILE__) 67 #endif 68 69 70 /** @name Allocate temporary memory. 71 * @{ */ 72 /** 73 * Allocates temporary memory with default tag. 74 * 75 * Temporary memory blocks are used for not too large memory blocks which 76 * are believed not to stick around for too long. Using this API instead 77 * of RTMemAlloc() not only gives the heap manager room for optimization 78 * but makes the code easier to read. 79 * 80 * @returns Pointer to the allocated memory. 81 * @returns NULL on failure, assertion raised in strict builds. 82 * @param cb Size in bytes of the memory block to allocated. 83 */ 84 #define RTMemTmpAlloc(cb) RTMemTmpAllocTag((cb), RTMEM_TAG) 85 86 /** 87 * Allocates temporary memory with custom tag. 88 * 89 * Temporary memory blocks are used for not too large memory blocks which 90 * are believed not to stick around for too long. Using this API instead 91 * of RTMemAlloc() not only gives the heap manager room for optimization 92 * but makes the code easier to read. 93 * 94 * @returns Pointer to the allocated memory. 95 * @returns NULL on failure, assertion raised in strict builds. 96 * @param cb Size in bytes of the memory block to allocated. 97 * @param pszTag Allocation tag used for statistics and such. 98 */ 99 RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW; 100 101 /** 102 * Allocates zero'd temporary memory with default tag. 103 * 104 * Same as RTMemTmpAlloc() but the memory will be zero'd. 105 * 106 * @returns Pointer to the allocated memory. 107 * @returns NULL on failure, assertion raised in strict builds. 108 * @param cb Size in bytes of the memory block to allocated. 109 */ 110 #define RTMemTmpAllocZ(cb) RTMemTmpAllocZTag((cb), RTMEM_TAG) 111 112 /** 113 * Allocates zero'd temporary memory with custom tag. 114 * 115 * Same as RTMemTmpAlloc() but the memory will be zero'd. 116 * 117 * @returns Pointer to the allocated memory. 118 * @returns NULL on failure, assertion raised in strict builds. 119 * @param cb Size in bytes of the memory block to allocated. 120 * @param pszTag Allocation tag used for statistics and such. 121 */ 122 RTDECL(void *) RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW; 123 124 /** 125 * Free temporary memory. 126 * 127 * @param pv Pointer to memory block. 128 */ 129 RTDECL(void) RTMemTmpFree(void *pv) RT_NO_THROW; 130 131 /** @} */ 132 133 134 /** 135 * Allocates memory with default tag. 136 * 137 * @returns Pointer to the allocated memory. 138 * @returns NULL on failure, assertion raised in strict builds. 139 * @param cb Size in bytes of the memory block to allocated. 140 * @param pszTag Allocation tag used for statistics and such. 141 */ 142 #define RTMemAlloc(cb) RTMemAllocTag((cb), RTMEM_TAG) 143 144 /** 145 * Allocates memory with custom tag. 146 * 147 * @returns Pointer to the allocated memory. 148 * @returns NULL on failure, assertion raised in strict builds. 149 * @param cb Size in bytes of the memory block to allocated. 150 * @param pszTag Allocation tag used for statistics and such. 151 */ 152 RTDECL(void *) RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW; 153 154 /** 155 * Allocates zero'd memory with default tag. 156 * 157 * Instead of memset(pv, 0, sizeof()) use this when you want zero'd 158 * memory. This keeps the code smaller and the heap can skip the memset 159 * in about 0.42% of calls :-). 160 * 161 * @returns Pointer to the allocated memory. 162 * @returns NULL on failure. 163 * @param cb Size in bytes of the memory block to allocated. 164 */ 165 #define RTMemAllocZ(cb) RTMemAllocZTag((cb), RTMEM_TAG) 166 167 /** 168 * Allocates zero'd memory with custom tag. 169 * 170 * Instead of memset(pv, 0, sizeof()) use this when you want zero'd 171 * memory. This keeps the code smaller and the heap can skip the memset 172 * in about 0.42% of calls :-). 173 * 174 * @returns Pointer to the allocated memory. 175 * @returns NULL on failure. 176 * @param cb Size in bytes of the memory block to allocated. 177 * @param pszTag Allocation tag used for statistics and such. 178 */ 179 RTDECL(void *) RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW; 180 181 /** 182 * Wrapper around RTMemAlloc for automatically aligning variable sized 183 * allocations so that the various electric fence heaps works correctly. 184 * 185 * @returns See RTMemAlloc. 186 * @param cbUnaligned The unaligned size. 187 */ 188 #define RTMemAllocVar(cbUnaligned) RTMemAllocVarTag((cbUnaligned), RTMEM_TAG) 189 190 /** 191 * Wrapper around RTMemAllocTag for automatically aligning variable sized 192 * allocations so that the various electric fence heaps works correctly. 193 * 194 * @returns See RTMemAlloc. 195 * @param cbUnaligned The unaligned size. 196 * @param pszTag Allocation tag used for statistics and such. 197 */ 198 RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW; 199 200 /** 201 * Wrapper around RTMemAllocZ for automatically aligning variable sized 202 * allocations so that the various electric fence heaps works correctly. 203 * 204 * @returns See RTMemAllocZ. 205 * @param cbUnaligned The unaligned size. 206 */ 207 #define RTMemAllocZVar(cbUnaligned) RTMemAllocZVarTag((cbUnaligned), RTMEM_TAG) 208 209 /** 210 * Wrapper around RTMemAllocZTag for automatically aligning variable sized 211 * allocations so that the various electric fence heaps works correctly. 212 * 213 * @returns See RTMemAllocZ. 214 * @param cbUnaligned The unaligned size. 215 * @param pszTag Allocation tag used for statistics and such. 216 */ 217 RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW; 218 219 /** 220 * Duplicates a chunk of memory into a new heap block (default tag). 221 * 222 * @returns New heap block with the duplicate data. 223 * @returns NULL if we're out of memory. 224 * @param pvSrc The memory to duplicate. 225 * @param cb The amount of memory to duplicate. 226 */ 227 #define RTMemDup(pvSrc, cb) RTMemDupTag((pvSrc), (cb), RTMEM_TAG) 228 229 /** 230 * Duplicates a chunk of memory into a new heap block (custom tag). 231 * 232 * @returns New heap block with the duplicate data. 233 * @returns NULL if we're out of memory. 234 * @param pvSrc The memory to duplicate. 235 * @param cb The amount of memory to duplicate. 236 * @param pszTag Allocation tag used for statistics and such. 237 */ 238 RTDECL(void *) RTMemDupTag(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW; 239 240 /** 241 * Duplicates a chunk of memory into a new heap block with some additional 242 * zeroed memory (default tag). 243 * 244 * @returns New heap block with the duplicate data. 245 * @returns NULL if we're out of memory. 246 * @param pvSrc The memory to duplicate. 247 * @param cbSrc The amount of memory to duplicate. 248 * @param cbExtra The amount of extra memory to allocate and zero. 249 */ 250 #define RTMemDupEx(pvSrc, cbSrc, cbExtra) RTMemDupExTag((pvSrc), (cbSrc), (cbExtra), RTMEM_TAG) 251 252 /** 253 * Duplicates a chunk of memory into a new heap block with some additional 254 * zeroed memory (default tag). 255 * 256 * @returns New heap block with the duplicate data. 257 * @returns NULL if we're out of memory. 258 * @param pvSrc The memory to duplicate. 259 * @param cbSrc The amount of memory to duplicate. 260 * @param cbExtra The amount of extra memory to allocate and zero. 261 * @param pszTag Allocation tag used for statistics and such. 262 */ 263 RTDECL(void *) RTMemDupExTag(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW; 264 265 /** 266 * Reallocates memory with default tag. 267 * 268 * @returns Pointer to the allocated memory. 269 * @returns NULL on failure. 270 * @param pvOld The memory block to reallocate. 271 * @param cbNew The new block size (in bytes). 272 */ 273 #define RTMemRealloc(pvOld, cbNew) RTMemReallocTag((pvOld), (cbNew), RTMEM_TAG) 274 275 /** 276 * Reallocates memory with custom tag. 277 * 278 * @returns Pointer to the allocated memory. 279 * @returns NULL on failure. 280 * @param pvOld The memory block to reallocate. 281 * @param cbNew The new block size (in bytes). 282 * @param pszTag Allocation tag used for statistics and such. 283 */ 284 RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW; 285 286 /** 287 * Frees memory. 288 * 289 * @param pv Pointer to memory block. 290 */ 291 RTDECL(void) RTMemFree(void *pv) RT_NO_THROW; 292 293 294 295 /** @def RTR0MemAllocEx and RTR0MemAllocExTag flags. 296 * @{ */ 297 /** The returned memory should be zeroed. */ 298 #define RTMEMALLOCEX_FLAGS_ZEROED RT_BIT(0) 299 /** It must be load code into the returned memory block and execute it. */ 300 #define RTMEMALLOCEX_FLAGS_EXEC RT_BIT(1) 301 /** Allocation from any context. 302 * Will return VERR_NOT_SUPPORTED if not supported. */ 303 #define RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC RT_BIT(2) 304 /** Allocate the memory such that it can be freed from any context. 305 * Will return VERR_NOT_SUPPORTED if not supported. */ 306 #define RTMEMALLOCEX_FLAGS_ANY_CTX_FREE RT_BIT(3) 307 /** Allocate and free from any context. 308 * Will return VERR_NOT_SUPPORTED if not supported. */ 309 #define RTMEMALLOCEX_FLAGS_ANY_CTX (RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE) 310 /** Mask of valid flags. */ 311 #define RTMEMALLOCEX_FLAGS_VALID_MASK UINT32_C(0x0000000f) 312 /** @} */ 313 314 /** 315 * Extended heap allocation API, default tag. 316 * 317 * @returns IPRT status code. 318 * @retval VERR_NO_MEMORY if we're out of memory. 319 * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory. 320 * @retval VERR_NOT_SUPPORTED if any of the specified flags are unsupported. 321 * 322 * @param cb The amount of memory to allocate. 323 * @param cbAlignment The alignment requirements. Use 0 to indicate 324 * default alignment. 325 * @param fFlags A combination of the RTMEMALLOCEX_FLAGS_XXX 326 * defines. 327 * @param ppv Where to return the memory. 328 */ 329 #define RTMemAllocEx(cb, cbAlignment, fFlags, ppv) RTMemAllocExTag((cb), (cbAlignment), (fFlags), RTMEM_TAG, (ppv)) 330 331 /** 332 * Extended heap allocation API, custom tag. 333 * 334 * @returns IPRT status code. 335 * @retval VERR_NO_MEMORY if we're out of memory. 336 * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory. 337 * @retval VERR_NOT_SUPPORTED if any of the specified flags are unsupported. 338 * 339 * @param cb The amount of memory to allocate. 340 * @param cbAlignment The alignment requirements. Use 0 to indicate 341 * default alignment. 342 * @param fFlags A combination of the RTMEMALLOCEX_FLAGS_XXX 343 * defines. 344 * @param pszTag The tag. 345 * @param ppv Where to return the memory. 346 */ 347 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW; 348 349 /** 350 * For freeing memory allocated by RTMemAllocEx or RTMemAllocExTag. 351 * 352 * @param pv What to free, NULL is fine. 353 * @param cb The amount of allocated memory. 354 */ 355 RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW; 356 357 358 359 /** 360 * Allocates memory which may contain code (default tag). 361 * 362 * @returns Pointer to the allocated memory. 363 * @returns NULL on failure. 364 * @param cb Size in bytes of the memory block to allocate. 365 */ 366 #define RTMemExecAlloc(cb) RTMemExecAllocTag((cb), RTMEM_TAG) 367 368 /** 369 * Allocates memory which may contain code (custom tag). 370 * 371 * @returns Pointer to the allocated memory. 372 * @returns NULL on failure. 373 * @param cb Size in bytes of the memory block to allocate. 374 * @param pszTag Allocation tag used for statistics and such. 375 */ 376 RTDECL(void *) RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW; 377 378 /** 379 * Free executable/read/write memory allocated by RTMemExecAlloc(). 380 * 381 * @param pv Pointer to memory block. 382 * @param cb The allocation size. 383 */ 384 RTDECL(void) RTMemExecFree(void *pv, size_t cb) RT_NO_THROW; 385 386 #if defined(IN_RING0) && defined(RT_ARCH_AMD64) && defined(RT_OS_LINUX) 387 /** 388 * Donate read+write+execute memory to the exec heap. 389 * 390 * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to 391 * use RTMemExecAlloc on AMD64 Linux/GNU will have to donate some statically 392 * allocated memory in the module if it wishes for GCC generated code to work. 393 * GCC can only generate modules that work in the address range ~2GB to ~0 394 * currently. 395 * 396 * The API only accept one single donation. 397 * 398 * @returns IPRT status code. 399 * @param pvMemory Pointer to the memory block. 400 * @param cb The size of the memory block. 401 */ 402 RTR0DECL(int) RTR0MemExecDonate(void *pvMemory, size_t cb) RT_NO_THROW; 403 404 /** 405 * Allocate read+write+execute memory to the exec heap. 406 * 407 * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to 408 * use RTMemExecAlloc on AMD64 Linux/GNU will have to initialize some allocated 409 * memory in the module range if it wishes for GCC generated code to work. GCC 410 * can only generate modules that work in the address range ~2GB to ~0 currently. 411 * As RTR0MemExecDonate() does not work if CONFIG_DEBUG_SET_MODULE_RONX is 412 * enabled, use a different approach (only very recent Linux kernels). 413 * 414 * The API only accept one single initialization. 415 * 416 * @returns IPRT status code. 417 * @param cb The size of the memory block. 418 */ 419 RTR0DECL(int) RTR0MemExecInit(size_t cb) RT_NO_THROW; 420 #endif /* R0+AMD64+LINUX */ 421 422 /** 423 * Allocate page aligned memory with default tag. 424 * 425 * @returns Pointer to the allocated memory. 426 * @returns NULL if we're out of memory. 427 * @param cb Size of the memory block. Will be rounded up to page size. 428 */ 429 #define RTMemPageAlloc(cb) RTMemPageAllocTag((cb), RTMEM_TAG) 430 431 /** 432 * Allocate page aligned memory with custom tag. 433 * 434 * @returns Pointer to the allocated memory. 435 * @returns NULL if we're out of memory. 436 * @param cb Size of the memory block. Will be rounded up to page size. 437 * @param pszTag Allocation tag used for statistics and such. 438 */ 439 RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW; 440 441 /** 442 * Allocate zero'd page aligned memory with default tag. 443 * 444 * @returns Pointer to the allocated memory. 445 * @returns NULL if we're out of memory. 446 * @param cb Size of the memory block. Will be rounded up to page size. 447 */ 448 #define RTMemPageAllocZ(cb) RTMemPageAllocZTag((cb), RTMEM_TAG) 449 450 /** 451 * Allocate zero'd page aligned memory with custom tag. 452 * 453 * @returns Pointer to the allocated memory. 454 * @returns NULL if we're out of memory. 455 * @param cb Size of the memory block. Will be rounded up to page size. 456 * @param pszTag Allocation tag used for statistics and such. 457 */ 458 RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW; 459 460 /** 461 * Free a memory block allocated with RTMemPageAlloc() or RTMemPageAllocZ(). 462 * 463 * @param pv Pointer to the block as it was returned by the allocation function. 464 * NULL will be ignored. 465 * @param cb The allocation size. Will be rounded up to page size. 466 * Ignored if @a pv is NULL. 467 */ 468 RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW; 469 470 /** Page level protection flags for RTMemProtect(). 471 * @{ 472 */ 473 /** No access at all. */ 474 #define RTMEM_PROT_NONE 0 475 /** Read access. */ 476 #define RTMEM_PROT_READ 1 477 /** Write access. */ 478 #define RTMEM_PROT_WRITE 2 479 /** Execute access. */ 480 #define RTMEM_PROT_EXEC 4 481 /** @} */ 482 483 /** 484 * Change the page level protection of a memory region. 485 * 486 * @returns iprt status code. 487 * @param pv Start of the region. Will be rounded down to nearest page boundary. 488 * @param cb Size of the region. Will be rounded up to the nearest page boundary. 489 * @param fProtect The new protection, a combination of the RTMEM_PROT_* defines. 490 */ 491 RTDECL(int) RTMemProtect(void *pv, size_t cb, unsigned fProtect) RT_NO_THROW; 492 493 /** 494 * Goes thru some pains to make sure the specified memory block is thoroughly 495 * scrambled. 496 * 497 * @param pv The start of the memory block. 498 * @param cb The size of the memory block. 499 * @param cMinPasses The minimum number of passes to make. 500 */ 501 RTDECL(void) RTMemWipeThoroughly(void *pv, size_t cb, size_t cMinPasses) RT_NO_THROW; 502 503 #ifdef IN_RING0 504 505 /** 506 * Allocates physical contiguous memory (below 4GB). 507 * The allocation is page aligned and the content is undefined. 508 * 509 * @returns Pointer to the memory block. This is page aligned. 510 * @param pPhys Where to store the physical address. 511 * @param cb The allocation size in bytes. This is always 512 * rounded up to PAGE_SIZE. 513 */ 514 RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb) RT_NO_THROW; 515 516 /** 517 * Frees memory allocated ysing RTMemContAlloc(). 518 * 519 * @param pv Pointer to return from RTMemContAlloc(). 520 * @param cb The cb parameter passed to RTMemContAlloc(). 521 */ 522 RTR0DECL(void) RTMemContFree(void *pv, size_t cb) RT_NO_THROW; 523 524 /** 525 * Copy memory from an user mode buffer into a kernel buffer. 526 * 527 * @retval VINF_SUCCESS on success. 528 * @retval VERR_ACCESS_DENIED on error. 529 * 530 * @param pvDst The kernel mode destination address. 531 * @param R3PtrSrc The user mode source address. 532 * @param cb The number of bytes to copy. 533 */ 534 RTR0DECL(int) RTR0MemUserCopyFrom(void *pvDst, RTR3PTR R3PtrSrc, size_t cb); 535 536 /** 537 * Copy memory from a kernel buffer into a user mode one. 538 * 539 * @retval VINF_SUCCESS on success. 540 * @retval VERR_ACCESS_DENIED on error. 541 * 542 * @param R3PtrDst The user mode destination address. 543 * @param pvSrc The kernel mode source address. 544 * @param cb The number of bytes to copy. 545 */ 546 RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb); 547 548 /** 549 * Tests if the specified address is in the user addressable range. 550 * 551 * This function does not check whether the memory at that address is accessible 552 * or anything of that sort, only if the address it self is in the user mode 553 * range. 554 * 555 * @returns true if it's in the user addressable range. false if not. 556 * @param R3Ptr The user mode pointer to test. 557 * 558 * @remarks Some systems may have overlapping kernel and user address ranges. 559 * One prominent example of this is the x86 version of Mac OS X. Use 560 * RTR0MemAreKrnlAndUsrDifferent() to check. 561 */ 562 RTR0DECL(bool) RTR0MemUserIsValidAddr(RTR3PTR R3Ptr); 563 564 /** 565 * Tests if the specified address is in the kernel mode range. 566 * 567 * This function does not check whether the memory at that address is accessible 568 * or anything of that sort, only if the address it self is in the kernel mode 569 * range. 570 * 571 * @returns true if it's in the kernel range. false if not. 572 * @param pv The alleged kernel mode pointer. 573 * 574 * @remarks Some systems may have overlapping kernel and user address ranges. 575 * One prominent example of this is the x86 version of Mac OS X. Use 576 * RTR0MemAreKrnlAndUsrDifferent() to check. 577 */ 578 RTR0DECL(bool) RTR0MemKernelIsValidAddr(void *pv); 579 580 /** 581 * Are user mode and kernel mode address ranges distinctly different. 582 * 583 * This determines whether RTR0MemKernelIsValidAddr and RTR0MemUserIsValidAddr 584 * can be used for deciding whether some arbitrary address is a user mode or a 585 * kernel mode one. 586 * 587 * @returns true if they are, false if not. 588 */ 589 RTR0DECL(bool) RTR0MemAreKrnlAndUsrDifferent(void); 590 591 #endif /* IN_RING0 */ 592 593 594 /** @name Electrical Fence Version of some APIs. 595 * @{ 596 */ 597 598 /** 599 * Same as RTMemTmpAllocTag() except that it's fenced. 600 * 601 * @returns Pointer to the allocated memory. 602 * @returns NULL on failure. 603 * @param cb Size in bytes of the memory block to allocate. 604 * @param pszTag Allocation tag used for statistics and such. 605 */ 606 RTDECL(void *) RTMemEfTmpAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 607 608 /** 609 * Same as RTMemTmpAllocZTag() except that it's fenced. 610 * 611 * @returns Pointer to the allocated memory. 612 * @returns NULL on failure. 613 * @param cb Size in bytes of the memory block to allocate. 614 * @param pszTag Allocation tag used for statistics and such. 615 */ 616 RTDECL(void *) RTMemEfTmpAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 617 618 /** 619 * Same as RTMemTmpFree() except that it's for fenced memory. 620 * 621 * @param pv Pointer to memory block. 622 */ 623 RTDECL(void) RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW; 624 625 /** 626 * Same as RTMemAllocTag() except that it's fenced. 627 * 628 * @returns Pointer to the allocated memory. Free with RTMemEfFree(). 629 * @returns NULL on failure. 630 * @param cb Size in bytes of the memory block to allocate. 631 * @param pszTag Allocation tag used for statistics and such. 632 */ 633 RTDECL(void *) RTMemEfAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 634 635 /** 636 * Same as RTMemAllocZTag() except that it's fenced. 637 * 638 * @returns Pointer to the allocated memory. 639 * @returns NULL on failure. 640 * @param cb Size in bytes of the memory block to allocate. 641 * @param pszTag Allocation tag used for statistics and such. 642 */ 643 RTDECL(void *) RTMemEfAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 644 645 /** 646 * Same as RTMemAllocVarTag() except that it's fenced. 647 * 648 * @returns Pointer to the allocated memory. Free with RTMemEfFree(). 649 * @returns NULL on failure. 650 * @param cbUnaligned Size in bytes of the memory block to allocate. 651 * @param pszTag Allocation tag used for statistics and such. 652 */ 653 RTDECL(void *) RTMemEfAllocVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 654 655 /** 656 * Same as RTMemAllocZVarTag() except that it's fenced. 657 * 658 * @returns Pointer to the allocated memory. 659 * @returns NULL on failure. 660 * @param cbUnaligned Size in bytes of the memory block to allocate. 661 * @param pszTag Allocation tag used for statistics and such. 662 */ 663 RTDECL(void *) RTMemEfAllocZVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 664 665 /** 666 * Same as RTMemReallocTag() except that it's fenced. 667 * 668 * @returns Pointer to the allocated memory. 669 * @returns NULL on failure. 670 * @param pvOld The memory block to reallocate. 671 * @param cbNew The new block size (in bytes). 672 * @param pszTag Allocation tag used for statistics and such. 673 */ 674 RTDECL(void *) RTMemEfRealloc(void *pvOld, size_t cbNew, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 675 676 /** 677 * Free memory allocated by any of the RTMemEf* allocators. 678 * 679 * @param pv Pointer to memory block. 680 */ 681 RTDECL(void) RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW; 682 683 /** 684 * Same as RTMemDupTag() except that it's fenced. 685 * 686 * @returns New heap block with the duplicate data. 687 * @returns NULL if we're out of memory. 688 * @param pvSrc The memory to duplicate. 689 * @param cb The amount of memory to duplicate. 690 * @param pszTag Allocation tag used for statistics and such. 691 */ 692 RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 693 694 /** 695 * Same as RTMemEfDupExTag except that it's fenced. 696 * 697 * @returns New heap block with the duplicate data. 698 * @returns NULL if we're out of memory. 699 * @param pvSrc The memory to duplicate. 700 * @param cbSrc The amount of memory to duplicate. 701 * @param cbExtra The amount of extra memory to allocate and zero. 702 * @param pszTag Allocation tag used for statistics and such. 703 */ 704 RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW; 705 706 /** @def RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF 707 * Define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF to enable electric fence new and 708 * delete operators for classes which uses the RTMEMEF_NEW_AND_DELETE_OPERATORS 709 * macro. 710 */ 711 /** @def RTMEMEF_NEW_AND_DELETE_OPERATORS 712 * Defines the electric fence new and delete operators for a class when 713 * RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF is define. 714 */ 715 #if defined(RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF) && !defined(RTMEM_NO_WRAP_SOME_NEW_AND_DELETE_TO_EF) 716 # if defined(RT_EXCEPTIONS_ENABLED) 717 # define RTMEMEF_NEW_AND_DELETE_OPERATORS() \ 718 void *operator new(size_t cb) throw(std::bad_alloc) \ 719 { \ 720 void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 721 if (RT_UNLIKELY(!pv)) \ 722 throw std::bad_alloc(); \ 723 return pv; \ 724 } \ 725 void *operator new(size_t cb, const std::nothrow_t ¬hrow_constant) throw() \ 726 { \ 727 NOREF(nothrow_constant); \ 728 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 729 } \ 730 void *operator new[](size_t cb) throw(std::bad_alloc) \ 731 { \ 732 void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 733 if (RT_UNLIKELY(!pv)) \ 734 throw std::bad_alloc(); \ 735 return pv; \ 736 } \ 737 void *operator new[](size_t cb, const std::nothrow_t ¬hrow_constant) throw() \ 738 { \ 739 NOREF(nothrow_constant); \ 740 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 741 } \ 742 \ 743 void operator delete(void *pv) throw() \ 744 { \ 745 RTMemEfFree(pv, RT_SRC_POS); \ 746 } \ 747 void operator delete(void *pv, const std::nothrow_t ¬hrow_constant) throw() \ 748 { \ 749 NOREF(nothrow_constant); \ 750 RTMemEfFree(pv, RT_SRC_POS); \ 751 } \ 752 void operator delete[](void *pv) throw() \ 753 { \ 754 RTMemEfFree(pv, RT_SRC_POS); \ 755 } \ 756 void operator delete[](void *pv, const std::nothrow_t ¬hrow_constant) throw() \ 757 { \ 758 NOREF(nothrow_constant); \ 759 RTMemEfFree(pv, RT_SRC_POS); \ 760 } \ 761 \ 762 typedef int UsingElectricNewAndDeleteOperators 763 # else 764 # define RTMEMEF_NEW_AND_DELETE_OPERATORS() \ 765 void *operator new(size_t cb) \ 766 { \ 767 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 768 } \ 769 void *operator new(size_t cb, const std::nothrow_t ¬hrow_constant) \ 770 { \ 771 NOREF(nothrow_constant); \ 772 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 773 } \ 774 void *operator new[](size_t cb) \ 775 { \ 776 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 777 } \ 778 void *operator new[](size_t cb, const std::nothrow_t ¬hrow_constant) \ 779 { \ 780 NOREF(nothrow_constant); \ 781 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \ 782 } \ 783 \ 784 void operator delete(void *pv) \ 785 { \ 786 RTMemEfFree(pv, RT_SRC_POS); \ 787 } \ 788 void operator delete(void *pv, const std::nothrow_t ¬hrow_constant) \ 789 { \ 790 NOREF(nothrow_constant); \ 791 RTMemEfFree(pv, RT_SRC_POS); \ 792 } \ 793 void operator delete[](void *pv) \ 794 { \ 795 RTMemEfFree(pv, RT_SRC_POS); \ 796 } \ 797 void operator delete[](void *pv, const std::nothrow_t ¬hrow_constant) \ 798 { \ 799 NOREF(nothrow_constant); \ 800 RTMemEfFree(pv, RT_SRC_POS); \ 801 } \ 802 \ 803 typedef int UsingElectricNewAndDeleteOperators 804 # endif 805 #else 806 # define RTMEMEF_NEW_AND_DELETE_OPERATORS() \ 807 typedef int UsingDefaultNewAndDeleteOperators 808 #endif 809 #ifdef DOXYGEN_RUNNING 810 # define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF 811 #endif 812 813 /** @def RTMEM_WRAP_TO_EF_APIS 814 * Define RTMEM_WRAP_TO_EF_APIS to wrap RTMem APIs to RTMemEf APIs. 815 */ 816 #if defined(RTMEM_WRAP_TO_EF_APIS) && defined(IN_RING3) && !defined(RTMEM_NO_WRAP_TO_EF_APIS) 817 # define RTMemTmpAllocTag(cb, pszTag) RTMemEfTmpAlloc((cb), (pszTag), RT_SRC_POS) 818 # define RTMemTmpAllocZTag(cb, pszTag) RTMemEfTmpAllocZ((cb), (pszTag), RT_SRC_POS) 819 # define RTMemTmpFree(pv) RTMemEfTmpFree((pv), RT_SRC_POS) 820 # define RTMemAllocTag(cb, pszTag) RTMemEfAlloc((cb), (pszTag), RT_SRC_POS) 821 # define RTMemAllocZTag(cb, pszTag) RTMemEfAllocZ((cb), (pszTag), RT_SRC_POS) 822 # define RTMemAllocVarTag(cbUnaligned, pszTag) RTMemEfAllocVar((cbUnaligned), (pszTag), RT_SRC_POS) 823 # define RTMemAllocZVarTag(cbUnaligned, pszTag) RTMemEfAllocZVar((cbUnaligned), (pszTag), RT_SRC_POS) 824 # define RTMemReallocTag(pvOld, cbNew, pszTag) RTMemEfRealloc((pvOld), (cbNew), (pszTag), RT_SRC_POS) 825 # define RTMemFree(pv) RTMemEfFree((pv), RT_SRC_POS) 826 # define RTMemDupTag(pvSrc, cb, pszTag) RTMemEfDup((pvSrc), (cb), (pszTag), RT_SRC_POS) 827 # define RTMemDupExTag(pvSrc, cbSrc, cbExtra, pszTag) RTMemEfDupEx((pvSrc), (cbSrc), (cbExtra), (pszTag), RT_SRC_POS) 828 #endif 829 #ifdef DOXYGEN_RUNNING 830 # define RTMEM_WRAP_TO_EF_APIS 831 #endif 832 833 /** 834 * Fenced drop-in replacement for RTMemTmpAllocTag. 835 * @copydoc RTMemTmpAllocTag 836 */ 837 RTDECL(void *) RTMemEfTmpAllocNP(size_t cb, const char *pszTag) RT_NO_THROW; 838 839 /** 840 * Fenced drop-in replacement for RTMemTmpAllocZTag. 841 * @copydoc RTMemTmpAllocZTag 842 */ 843 RTDECL(void *) RTMemEfTmpAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW; 844 845 /** 846 * Fenced drop-in replacement for RTMemTmpFreeTag. 847 * @copydoc RTMemTmpFreeTag 848 */ 849 RTDECL(void) RTMemEfTmpFreeNP(void *pv) RT_NO_THROW; 850 851 /** 852 * Fenced drop-in replacement for RTMemAllocTag. 853 * @copydoc RTMemAllocTag 854 */ 855 RTDECL(void *) RTMemEfAllocNP(size_t cb, const char *pszTag) RT_NO_THROW; 856 857 /** 858 * Fenced drop-in replacement for RTMemAllocZTag. 859 * @copydoc RTMemAllocZTag 860 */ 861 RTDECL(void *) RTMemEfAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW; 862 863 /** 864 * Fenced drop-in replacement for RTMemAllocVarTag 865 * @copydoc RTMemAllocVarTag 866 */ 867 RTDECL(void *) RTMemEfAllocVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW; 868 869 /** 870 * Fenced drop-in replacement for RTMemAllocZVarTag. 871 * @copydoc RTMemAllocZVarTag 872 */ 873 RTDECL(void *) RTMemEfAllocZVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW; 874 875 /** 876 * Fenced drop-in replacement for RTMemReallocTag. 877 * @copydoc RTMemReallocTag 878 */ 879 RTDECL(void *) RTMemEfReallocNP(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW; 880 881 /** 882 * Fenced drop-in replacement for RTMemFree. 883 * @copydoc RTMemFree 884 */ 885 RTDECL(void) RTMemEfFreeNP(void *pv) RT_NO_THROW; 886 887 /** 888 * Fenced drop-in replacement for RTMemDupExTag. 889 * @copydoc RTMemDupExTag 890 */ 891 RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW; 892 893 /** 894 * Fenced drop-in replacement for RTMemDupExTag. 895 * @copydoc RTMemDupExTag 896 */ 897 RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW; 898 899 /** @} */ 900 901 RT_C_DECLS_END 902 903 904 #ifdef __cplusplus /** @todo Split this out into iprt/cpp/mem.h! */ 905 # include <iprt/assert.h> 906 907 /** 908 * Template function wrapping RTMemFree to get the correct Destruct 909 * signature for RTAutoRes. 38 /** 39 * Template function wrapping RTMemFree to get the correct a_fnDestruct 40 * signature for RTCAutoRes. 910 41 * 911 42 * We can't use a more complex template here, because the g++ on RHEL 3 … … 916 47 */ 917 48 template <class T> 918 inline void RT MemAutoDestructor(T *aMem) RT_NO_THROW49 inline void RTCMemAutoDestructor(T *aMem) RT_NO_THROW 919 50 { 920 51 RTMemFree(aMem); … … 923 54 924 55 /** 925 * RT MemAutoPtr allocator which uses RTMemTmpAlloc().56 * RTCMemAutoPtr allocator which uses RTMemTmpAlloc(). 926 57 * 927 58 * @returns Allocated memory on success, NULL on failure. … … 929 60 * @param cbNew The amount of memory to allocate (in bytes). 930 61 */ 931 inline void *RT MemTmpAutoAllocator(void *pvOld, size_t cbNew) RT_NO_THROW62 inline void *RTCMemTmpAutoAllocator(void *pvOld, size_t cbNew) RT_NO_THROW 932 63 { 933 64 AssertReturn(!pvOld, NULL); … … 937 68 938 69 /** 939 * Template function wrapping RTMemTmpFree to get the correct Destruct940 * signature for RT AutoRes.70 * Template function wrapping RTMemTmpFree to get the correct a_fnDestruct 71 * signature for RTCAutoRes. 941 72 * 942 73 * We can't use a more complex template here, because the g++ on RHEL 3 … … 947 78 */ 948 79 template <class T> 949 inline void RT MemTmpAutoDestructor(T *aMem) RT_NO_THROW80 inline void RTCMemTmpAutoDestructor(T *aMem) RT_NO_THROW 950 81 { 951 82 RTMemTmpFree(aMem); … … 954 85 955 86 /** 956 * Template function wrapping RTMemEfFree to get the correct Destruct957 * signature for RT AutoRes.87 * Template function wrapping RTMemEfFree to get the correct a_fnDestruct 88 * signature for RTCAutoRes. 958 89 * 959 90 * We can't use a more complex template here, because the g++ on RHEL 3 … … 964 95 */ 965 96 template <class T> 966 inline void RT MemEfAutoFree(T *aMem) RT_NO_THROW97 inline void RTCMemEfAutoFree(T *aMem) RT_NO_THROW 967 98 { 968 99 RTMemEfFreeNP(aMem); … … 972 103 /** 973 104 * Template function wrapping NULL to get the correct NilRes signature 974 * for RT AutoRes.105 * for RTCAutoRes. 975 106 * 976 107 * @tparam T The data type that's being managed. … … 978 109 */ 979 110 template <class T> 980 inline T * RTMemAutoNil(void) RT_NO_THROW111 inline T *RTCMemAutoNil(void) RT_NO_THROW 981 112 { 982 113 return (T *)(NULL); … … 995 126 * you hand it. 996 127 * 997 * @tparam T The data type to manage allocations for. 998 * @tparam Destruct The function to be used to free the resource. 999 * This will default to RTMemFree. 1000 * @tparam Allocator The function to be used to allocate or reallocate 1001 * the managed memory. 1002 * This is standard realloc() like stuff, so it's possible 1003 * to support simple allocation without actually having 1004 * to support reallocating memory if that's a problem. 1005 * This will default to RTMemRealloc. 128 * @tparam T The data type to manage allocations for. 129 * @tparam a_fnDestruct The function to be used to free the resource. 130 * This will default to RTMemFree. 131 * @tparam a_fnAllocator The function to be used to allocate or reallocate 132 * the managed memory. 133 * This is standard realloc() like stuff, so it's 134 * possible to support simple allocation without 135 * actually having to support reallocating memory if 136 * that's a problem. This will default to 137 * RTMemRealloc. 1006 138 */ 1007 139 template <class T, 1008 void Destruct(T *) = RTMemAutoDestructor<T>,140 void a_fnDestruct(T *) = RTCMemAutoDestructor<T>, 1009 141 # if defined(RTMEM_WRAP_TO_EF_APIS) && !defined(RTMEM_NO_WRAP_TO_EF_APIS) 1010 void * Allocator(void *, size_t, const char *) = RTMemEfReallocNP142 void *a_fnAllocator(void *, size_t, const char *) = RTMemEfReallocNP 1011 143 # else 1012 void * Allocator(void *, size_t, const char *) = RTMemReallocTag144 void *a_fnAllocator(void *, size_t, const char *) = RTMemReallocTag 1013 145 # endif 1014 146 > 1015 class RT MemAutoPtr1016 : public RT AutoRes<T *, Destruct, RTMemAutoNil<T> >147 class RTCMemAutoPtr 148 : public RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> > 1017 149 { 1018 150 public: … … 1022 154 * @param aPtr Memory pointer to manage. Defaults to NULL. 1023 155 */ 1024 RT MemAutoPtr(T *aPtr = NULL)1025 : RT AutoRes<T *, Destruct, RTMemAutoNil<T> >(aPtr)156 RTCMemAutoPtr(T *aPtr = NULL) 157 : RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >(aPtr) 1026 158 { 1027 159 } … … 1034 166 * the allocation. Defaults to false. 1035 167 */ 1036 RT MemAutoPtr(size_t a_cElements, bool a_fZeroed = false)1037 : RT AutoRes<T *, Destruct, RTMemAutoNil<T> >((T *)Allocator(NULL, a_cElements * sizeof(T), RTMEM_TAG))168 RTCMemAutoPtr(size_t a_cElements, bool a_fZeroed = false) 169 : RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >((T *)a_fnAllocator(NULL, a_cElements * sizeof(T), RTMEM_TAG)) 1038 170 { 1039 171 if (a_fZeroed && RT_LIKELY(this->get() != NULL)) … … 1046 178 * @param aPtr Memory pointer to manage. 1047 179 */ 1048 RT MemAutoPtr &operator=(T *aPtr)1049 { 1050 this->RT AutoRes<T *, Destruct, RTMemAutoNil<T> >::operator=(aPtr);180 RTCMemAutoPtr &operator=(T *aPtr) 181 { 182 this->RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >::operator=(aPtr); 1051 183 return *this; 1052 184 } … … 1097 229 { 1098 230 this->reset(NULL); 1099 T *pNewMem = (T *) Allocator(NULL, a_cElements * sizeof(T), RTMEM_TAG);231 T *pNewMem = (T *)a_fnAllocator(NULL, a_cElements * sizeof(T), RTMEM_TAG); 1100 232 if (a_fZeroed && RT_LIKELY(pNewMem != NULL)) 1101 233 memset(pNewMem, '\0', a_cElements * sizeof(T)); … … 1119 251 * allocate. The size of the allocation is the number of 1120 252 * elements times the size of the data type - this is 1121 * currently what's passed down to the Allocator.253 * currently what's passed down to the a_fnAllocator. 1122 254 * This defaults to 1. 1123 255 */ 1124 256 bool realloc(size_t a_cElements = 1) 1125 257 { 1126 T *aNewValue = (T *) Allocator(this->get(), a_cElements * sizeof(T), RTMEM_TAG);258 T *aNewValue = (T *)a_fnAllocator(this->get(), a_cElements * sizeof(T), RTMEM_TAG); 1127 259 if (RT_LIKELY(aNewValue != NULL)) 1128 260 this->release(); … … 1133 265 }; 1134 266 1135 1136 #endif /* __cplusplus */ 1137 1138 1139 /** @} */ 1140 267 /** @} */ 1141 268 1142 269 #endif -
trunk/include/iprt/cpp/utils.h
r36508 r36529 35 35 36 36 /** 37 * A simple class used to prevent copying and assignment. 38 * 39 * Inherit from this class in order to prevent automatic generation 40 * of the copy constructor and assignment operator in your class. 41 * 42 * @addtogroup grp_rt_cpp_util 43 */ 44 class RTCNonCopyable 45 { 46 protected: 47 RTCNonCopyable() {} 48 ~RTCNonCopyable() {} 49 private: 50 RTCNonCopyable(RTCNonCopyable const &); 51 RTCNonCopyable const &operator=(RTCNonCopyable const &); 52 }; 53 54 55 /** 37 56 * Shortcut to |const_cast<C &>()| that automatically derives the correct 38 57 * type (class) for the const_cast template's argument from its own argument. … … 45 64 * unconst(That) = SomeValue; 46 65 * @endcode 66 * 67 * @todo What to do about the prefix here? 47 68 */ 48 69 template <class C> … … 64 85 * unconst(pThat) = SomeValue; 65 86 * @endcode 87 * 88 * @todo What to do about the prefix here? 66 89 */ 67 90 template <class C> … … 73 96 /** @} */ 74 97 75 namespace iprt76 {77 78 /**79 * A simple class used to prevent copying and assignment.80 *81 * Inherit from this class in order to prevent automatic generation of the copy82 * constructor and assignment operator in your class.83 *84 * @ingroup grp_rt_cpp_util85 * @todo Functionality duplicated by RTCNonCopyable. grr!86 */87 class non_copyable88 {89 protected:90 non_copyable() {}91 ~non_copyable() {}92 private:93 non_copyable(non_copyable const &);94 non_copyable const &operator=(non_copyable const &);95 };96 97 } /* namespace iprt */98 99 98 #endif 100 99 -
trunk/include/iprt/mem.h
r35294 r36529 30 30 #include <iprt/cdefs.h> 31 31 #include <iprt/types.h> 32 #ifdef __cplusplus /** @todo remove when spitting. */33 # include <iprt/cpp/autores.h>34 #endif35 32 36 33 … … 901 898 RT_C_DECLS_END 902 899 903 904 #ifdef __cplusplus /** @todo Split this out into iprt/cpp/mem.h! */905 # include <iprt/assert.h>906 907 /**908 * Template function wrapping RTMemFree to get the correct Destruct909 * signature for RTAutoRes.910 *911 * We can't use a more complex template here, because the g++ on RHEL 3912 * chokes on it with an internal compiler error.913 *914 * @tparam T The data type that's being managed.915 * @param aMem Pointer to the memory that should be free.916 */917 template <class T>918 inline void RTMemAutoDestructor(T *aMem) RT_NO_THROW919 {920 RTMemFree(aMem);921 }922 923 924 /**925 * RTMemAutoPtr allocator which uses RTMemTmpAlloc().926 *927 * @returns Allocated memory on success, NULL on failure.928 * @param pvOld What to reallocate, shall always be NULL.929 * @param cbNew The amount of memory to allocate (in bytes).930 */931 inline void *RTMemTmpAutoAllocator(void *pvOld, size_t cbNew) RT_NO_THROW932 {933 AssertReturn(!pvOld, NULL);934 return RTMemTmpAlloc(cbNew);935 }936 937 938 /**939 * Template function wrapping RTMemTmpFree to get the correct Destruct940 * signature for RTAutoRes.941 *942 * We can't use a more complex template here, because the g++ on RHEL 3943 * chokes on it with an internal compiler error.944 *945 * @tparam T The data type that's being managed.946 * @param aMem Pointer to the memory that should be free.947 */948 template <class T>949 inline void RTMemTmpAutoDestructor(T *aMem) RT_NO_THROW950 {951 RTMemTmpFree(aMem);952 }953 954 955 /**956 * Template function wrapping RTMemEfFree to get the correct Destruct957 * signature for RTAutoRes.958 *959 * We can't use a more complex template here, because the g++ on RHEL 3960 * chokes on it with an internal compiler error.961 *962 * @tparam T The data type that's being managed.963 * @param aMem Pointer to the memory that should be free.964 */965 template <class T>966 inline void RTMemEfAutoFree(T *aMem) RT_NO_THROW967 {968 RTMemEfFreeNP(aMem);969 }970 971 972 /**973 * Template function wrapping NULL to get the correct NilRes signature974 * for RTAutoRes.975 *976 * @tparam T The data type that's being managed.977 * @returns NULL with the right type.978 */979 template <class T>980 inline T * RTMemAutoNil(void) RT_NO_THROW981 {982 return (T *)(NULL);983 }984 985 986 /**987 * An auto pointer-type template class for managing memory allocating988 * via C APIs like RTMem (the default).989 *990 * The main purpose of this class is to automatically free memory that991 * isn't explicitly used (release()'ed) when the object goes out of scope.992 *993 * As an additional service it can also make the allocations and994 * reallocations for you if you like, but it can also take of memory995 * you hand it.996 *997 * @tparam T The data type to manage allocations for.998 * @tparam Destruct The function to be used to free the resource.999 * This will default to RTMemFree.1000 * @tparam Allocator The function to be used to allocate or reallocate1001 * the managed memory.1002 * This is standard realloc() like stuff, so it's possible1003 * to support simple allocation without actually having1004 * to support reallocating memory if that's a problem.1005 * This will default to RTMemRealloc.1006 */1007 template <class T,1008 void Destruct(T *) = RTMemAutoDestructor<T>,1009 # if defined(RTMEM_WRAP_TO_EF_APIS) && !defined(RTMEM_NO_WRAP_TO_EF_APIS)1010 void *Allocator(void *, size_t, const char *) = RTMemEfReallocNP1011 # else1012 void *Allocator(void *, size_t, const char *) = RTMemReallocTag1013 # endif1014 >1015 class RTMemAutoPtr1016 : public RTAutoRes<T *, Destruct, RTMemAutoNil<T> >1017 {1018 public:1019 /**1020 * Constructor.1021 *1022 * @param aPtr Memory pointer to manage. Defaults to NULL.1023 */1024 RTMemAutoPtr(T *aPtr = NULL)1025 : RTAutoRes<T *, Destruct, RTMemAutoNil<T> >(aPtr)1026 {1027 }1028 1029 /**1030 * Constructor that allocates memory.1031 *1032 * @param a_cElements The number of elements (of the data type) to allocate.1033 * @param a_fZeroed Whether the memory should be memset with zeros after1034 * the allocation. Defaults to false.1035 */1036 RTMemAutoPtr(size_t a_cElements, bool a_fZeroed = false)1037 : RTAutoRes<T *, Destruct, RTMemAutoNil<T> >((T *)Allocator(NULL, a_cElements * sizeof(T), RTMEM_TAG))1038 {1039 if (a_fZeroed && RT_LIKELY(this->get() != NULL))1040 memset(this->get(), '\0', a_cElements * sizeof(T));1041 }1042 1043 /**1044 * Free current memory and start managing aPtr.1045 *1046 * @param aPtr Memory pointer to manage.1047 */1048 RTMemAutoPtr &operator=(T *aPtr)1049 {1050 this->RTAutoRes<T *, Destruct, RTMemAutoNil<T> >::operator=(aPtr);1051 return *this;1052 }1053 1054 /**1055 * Dereference with * operator.1056 */1057 T &operator*()1058 {1059 return *this->get();1060 }1061 1062 /**1063 * Dereference with -> operator.1064 */1065 T *operator->()1066 {1067 return this->get();1068 }1069 1070 /**1071 * Accessed with the subscript operator ([]).1072 *1073 * @returns Reference to the element.1074 * @param a_i The element to access.1075 */1076 T &operator[](size_t a_i)1077 {1078 return this->get()[a_i];1079 }1080 1081 /**1082 * Allocates memory and start manage it.1083 *1084 * Any previously managed memory will be freed before making1085 * the new allocation.1086 *1087 * @returns Success indicator.1088 * @retval true if the new allocation succeeds.1089 * @retval false on failure, no memory is associated with the object.1090 *1091 * @param a_cElements The number of elements (of the data type) to allocate.1092 * This defaults to 1.1093 * @param a_fZeroed Whether the memory should be memset with zeros after1094 * the allocation. Defaults to false.1095 */1096 bool alloc(size_t a_cElements = 1, bool a_fZeroed = false)1097 {1098 this->reset(NULL);1099 T *pNewMem = (T *)Allocator(NULL, a_cElements * sizeof(T), RTMEM_TAG);1100 if (a_fZeroed && RT_LIKELY(pNewMem != NULL))1101 memset(pNewMem, '\0', a_cElements * sizeof(T));1102 this->reset(pNewMem);1103 return pNewMem != NULL;1104 }1105 1106 /**1107 * Reallocate or allocates the memory resource.1108 *1109 * Free the old value if allocation fails.1110 *1111 * The content of any additional memory that was allocated is1112 * undefined when using the default allocator.1113 *1114 * @returns Success indicator.1115 * @retval true if the new allocation succeeds.1116 * @retval false on failure, no memory is associated with the object.1117 *1118 * @param a_cElements The new number of elements (of the data type) to1119 * allocate. The size of the allocation is the number of1120 * elements times the size of the data type - this is1121 * currently what's passed down to the Allocator.1122 * This defaults to 1.1123 */1124 bool realloc(size_t a_cElements = 1)1125 {1126 T *aNewValue = (T *)Allocator(this->get(), a_cElements * sizeof(T), RTMEM_TAG);1127 if (RT_LIKELY(aNewValue != NULL))1128 this->release();1129 /* We want this both if aNewValue is non-NULL and if it is NULL. */1130 this->reset(aNewValue);1131 return aNewValue != NULL;1132 }1133 };1134 1135 1136 #endif /* __cplusplus */1137 1138 1139 900 /** @} */ 1140 901
Note:
See TracChangeset
for help on using the changeset viewer.