/* Copyright (c) 2000-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dkmem.h Memory allocation functions. This module provides macros and functions for portable memory allocation. Use the dk_new() and dk_delete() macros to allocate and release memory, not the dkmem_alloc(), dkmem_alloc_tracked() and dkmem_free() functions. Use the DK_MEMRES(), DK_MEMCPY() and DK_MEMCMP() macros to reset, copy and compare memory buffers, not the dkmem_res(), dkmem_cpy() and dkmem_cmp() functions. The macros invoke the functions provided by the system. I.e. DM_MEMRES() is mapped to either memset() or bzero() or -- if these functions are not available -- dkmem_res(). Typically the functions in the C runtime library are implemented more efficiently than the fallback functions provided by the dkmem module. The only function in the dkmem module for direct use is dkmem_get_track(). */ #ifndef DK_MEM_INCLUDED /** Make sure to include the file only once. */ #define DK_MEM_INCLUDED 1 #include #if DK_HAVE_STRING_H #include #else #if DK_HAVE_STRINGS_H #include #endif #endif #if defined(EXTERN) #undef EXTERN #endif #ifndef DK_MEM_C #if !DK_HAVE_PROTOTYPES #define EXTERN extern #else #define EXTERN /* nix */ #endif #else #define EXTERN /* nix */ #endif #if defined(__cplusplus) extern "C" { #endif /** Reset memory. Set all bytes in buffer \a ptr (\a n bytes) to 0x00. @param ptr Pointer to buffer. @param bytes Number of bytes in buffer. */ EXTERN void dkmem_res DK_PR((void *ptr, size_t bytes)); /** Copy memory. Copy \a n bytes from \a s to \a d. @param d Pointer to destination buffer. @param s Pointer to source buffer. @param n Number of bytes to copy. */ EXTERN void dkmem_cpy DK_PR((void *d, void *s, size_t n)); /** Compare memory. Compare \a n bytes in buffers \a s1 and \a s2. @param s1 Pointer to one buffer. @param s2 Pointer to the other buffer. @param n Number of bytes to compare. @return - 0 if both buffers are equal, - positive value if \a s1 is "larger" than \a s2. - negative value if \a s1 is "smaller" than \a s2. */ EXTERN int dkmem_cmp DK_PR((void *s1, void *s2, size_t n)); /** Allocate memory. Attempt to allocate \a nelem elements of element size \a elsize. @param elsize Size of one element to allocate. @param nelem Number of elements to allocate. @return - Valid pointer on success. - NULL on errors. */ EXTERN void *dkmem_alloc DK_PR((size_t elsize, size_t nelem)); /** Allocate memory, keep track of allocated size. Attempt to allocate \a nelem elements of element size \a elsize and keep track of the summary size of allocated memory. @param elsize Size of one element to allocate. @param nelem Number of elements to allocate. @return - Valid pointer on success. - NULL on errors. */ EXTERN void *dkmem_alloc_tracked DK_PR((size_t elsize, size_t nelem)); /** Release memory. Release memory previously allocated by dkmem_alloc() or dkmem_alloc_tracked(). @param ptr Pointer to memory. */ EXTERN void dkmem_free DK_PR((void *ptr)); /** Get amount of memory allocated. Get number of bytes already allocated. @param usehb Flag to indicate whether the higher or lower 32 bits of the number are requested. @return The numeric value. */ EXTERN unsigned long dkmem_get_track DK_PR((int usehb)); #if defined(__cplusplus) } #endif /** Reset \a sz bytes in buffer \a ptr. */ #if DK_HAVE_MEMSET #define DK_MEMRES(ptr,sz) memset(((void *)(ptr)),0,((size_t)(sz))) #else #if DK_HAVE_BZERO #define DK_MEMRES(ptr,sz) bzero(((void *)(ptr)),((size_t)(sz))) #else #define DK_MEMRES(ptr,sz) dkmem_res(((void *)(ptr)),((size_t)(sz))) #endif #endif /** Copy \a n bytes from buffer \a s to buffer \a d. */ #if DK_HAVE_MEMCPY #define DK_MEMCPY(d,s,n) memcpy(((void *)(d)),((void *)(s)),((size_t)(n))) #else #if DK_HAVE_BCOPY #define DK_MEMCPY(d,s,n) bcopy(((void *)(s)),((void *)(d)),((size_t)(n))) #else #define DK_MEMCPY(d,s,n) dkmem_cpy(((void *)(d)),((void *)(s)),((size_t)(n))) #endif #endif /** Compare \a n bytes in buffers \a a and \a b, return 0 for equal buffers. */ #if DK_HAVE_MEMCMP #define DK_MEMCMP(a,b,n) memcmp(((void *)(a)),((void *)(b)),((size_t)(n))) #else #if DK_HAVE_BCMP #define DK_MEMCMP(a,b,n) bcmp(((void *)(a)),((void *)(b)),((size_t)(n))) #else #define DK_MEMCMP(a,b,n) dkmem_cmp(((void *)(a)),((void *)(b)),((size_t)(n))) #endif #endif #if DK_MEM_NOTRACK #define dk_new(t,s) (t *)dkmem_alloc(sizeof(t),((size_t)s)) #else /** Allocate memory, \a s bytes of type \a t, return pointer on success. */ #define dk_new(t,s) (t *)dkmem_alloc_tracked(sizeof(t),((size_t)s)) #endif /** Release memory, buffer \a p. */ #define dk_delete(p) dkmem_free((void *)(p)) #endif /* DK_MEM_INCLUDED */