mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
USE_DELETED_CHAIN, memory alignment
This commit is contained in:
parent
926059131b
commit
f68fa1909a
@ -395,6 +395,13 @@
|
||||
//#defer ALTERNATIVE_MALLOC $[or $[WINDOWS_PLATFORM],$[DO_MEMORY_USAGE],$[not $[HAVE_THREADS]]]
|
||||
#define ALTERNATIVE_MALLOC
|
||||
|
||||
// Define this true to use the DELETED_CHAIN macros, which support
|
||||
// fast re-use of existing allocated blocks, minimizing the low-level
|
||||
// calls to malloc() and free() for frequently-created and -deleted
|
||||
// objects. There's usually no reason to set this false, unless you
|
||||
// suspect a bug in Panda's memory management code.
|
||||
#define USE_DELETED_CHAIN 1
|
||||
|
||||
// Define this true to build the low-level native network
|
||||
// implementation. Normally this should be set true.
|
||||
#define WANT_NATIVE_NET 1
|
||||
@ -407,6 +414,11 @@
|
||||
// Normally, if you build NATIVE_NET, you will also build NET.
|
||||
#defer HAVE_NET $[WANT_NATIVE_NET]
|
||||
|
||||
// Do you want to build the egg loader? Usually there's no reason to
|
||||
// avoid building this, unless you really want to make a low-footprint
|
||||
// build (such as, for instance, for the iPhone).
|
||||
#define HAVE_EGG 1
|
||||
|
||||
// Is a third-party STL library installed, and where? This is only
|
||||
// necessary if the default include and link lines that come with the
|
||||
// compiler don't provide adequate STL support. At least some form of
|
||||
@ -460,6 +472,17 @@
|
||||
#define TIFF_LIBS tiff z
|
||||
#defer HAVE_TIFF $[libtest $[TIFF_LPATH],$[TIFF_LIBS]]
|
||||
|
||||
// These image file formats don't require the assistance of a
|
||||
// third-party library to read and write, so there's normally no
|
||||
// reason to disable them in the build, unless you are looking to
|
||||
// reduce the memory footprint.
|
||||
#define HAVE_SGI_RGB 1
|
||||
#define HAVE_TGA 1
|
||||
#define HAVE_IMG 1
|
||||
#define HAVE_SOFTIMAGE_PIC 1
|
||||
#define HAVE_BMP 1
|
||||
#define HAVE_PNM 1
|
||||
|
||||
// Is libtar installed, and where? This is used to optimize patch
|
||||
// generation against tar files.
|
||||
#define TAR_IPATH
|
||||
|
@ -244,6 +244,14 @@ $[cdefine HAVE_PNG]
|
||||
/* Define if we have libtiff installed. */
|
||||
$[cdefine HAVE_TIFF]
|
||||
|
||||
/* Define if we want to build these other image file formats. */
|
||||
$[cdefine HAVE_SGI_RGB]
|
||||
$[cdefine HAVE_TGA]
|
||||
$[cdefine HAVE_IMG]
|
||||
$[cdefine HAVE_SOFTIMAGE_PIC]
|
||||
$[cdefine HAVE_BMP]
|
||||
$[cdefine HAVE_PNM]
|
||||
|
||||
/* Define if we have libtar installed. */
|
||||
$[cdefine HAVE_TAR]
|
||||
|
||||
@ -344,6 +352,9 @@ $[cdefine USE_PANDAFILESTREAM]
|
||||
/* Define if we want to compile the net code. */
|
||||
$[cdefine HAVE_NET]
|
||||
|
||||
/* Define if we want to compile the egg code. */
|
||||
$[cdefine HAVE_EGG]
|
||||
|
||||
/* Define if we want to compile the audio code. */
|
||||
$[cdefine HAVE_AUDIO]
|
||||
|
||||
@ -584,6 +595,9 @@ $[cdefine USE_MEMORY_PTMALLOC2]
|
||||
$[cdefine USE_MEMORY_MALLOC]
|
||||
$[cdefine USE_MEMORY_NOWRAPPERS]
|
||||
|
||||
// To activate the DELETED_CHAIN macros.
|
||||
$[cdefine USE_DELETED_CHAIN]
|
||||
|
||||
// If we are to build the native net interfaces.
|
||||
$[cdefine WANT_NATIVE_NET]
|
||||
|
||||
|
@ -8,12 +8,13 @@
|
||||
#define IPH_VERSION 2.0
|
||||
|
||||
#if $[eq $[IPH_PLATFORM], iPhoneOS]
|
||||
#define ARCH_FLAGS -arch armv6
|
||||
#define osflags -miphoneos-version-min=2.0
|
||||
#define DEBUGFLAGS
|
||||
#define ARCH_FLAGS -arch armv6 -mcpu=arm1176jzf-s
|
||||
#define osflags -fpascal-strings -fasm-blocks -fvisibility=hidden -fvisibility-inlines-hidden -miphoneos-version-min=2.0
|
||||
#define DEBUGFLAGS -gdwarf-2
|
||||
//#define DEBUGFLAGS
|
||||
#elif $[eq $[IPH_PLATFORM], iPhoneSimulator]
|
||||
#define ARCH_FLAGS -arch i386
|
||||
#define osflags -mmacosx-version-min=10.5
|
||||
#define osflags -fpascal-strings -fasm-blocks -fvisibility=hidden -fvisibility-inlines-hidden -mmacosx-version-min=10.5
|
||||
#define DEBUGFLAGS -gdwarf-2
|
||||
#else
|
||||
#error Inappropriate value for BUILD_IPHONE.
|
||||
|
@ -30,7 +30,7 @@ validate(void *ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_DELETEDCHAINFLAG
|
||||
#if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN)
|
||||
const ObjectNode *obj = buffer_to_node(ptr);
|
||||
return AtomicAdjust::get(obj->_flag) == DCF_alive;
|
||||
#else
|
||||
@ -56,7 +56,7 @@ get_buffer_size() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void *DeletedBufferChain::
|
||||
node_to_buffer(DeletedBufferChain::ObjectNode *node) {
|
||||
#ifdef USE_DELETEDCHAINFLAG
|
||||
#if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN)
|
||||
// In development mode, we increment the pointer so that the
|
||||
// returned data does not overlap our _flag member.
|
||||
return (void *)(((AtomicAdjust::Integer *)node) + 1);
|
||||
@ -72,7 +72,7 @@ node_to_buffer(DeletedBufferChain::ObjectNode *node) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DeletedBufferChain::ObjectNode *DeletedBufferChain::
|
||||
buffer_to_node(void *ptr) {
|
||||
#ifdef USE_DELETEDCHAINFLAG
|
||||
#if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN)
|
||||
// In development mode, we decrement the pointer to undo the
|
||||
// increment we did above.
|
||||
return (ObjectNode *)(((AtomicAdjust::Integer *)ptr) - 1);
|
||||
|
@ -46,6 +46,7 @@ DeletedBufferChain(size_t buffer_size) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void *DeletedBufferChain::
|
||||
allocate(size_t size, TypeHandle type_handle) {
|
||||
#ifdef USE_DELETED_CHAIN
|
||||
TAU_PROFILE("void *DeletedBufferChain::allocate(size_t, TypeHandle)", " ", TAU_USER);
|
||||
assert(size <= _buffer_size);
|
||||
|
||||
@ -89,6 +90,10 @@ allocate(size_t size, TypeHandle type_handle) {
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
return ptr;
|
||||
|
||||
#else // USE_DELETED_CHAIN
|
||||
return PANDA_MALLOC_SINGLE(_buffer_size);
|
||||
#endif // USE_DELETED_CHAIN
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -99,6 +104,7 @@ allocate(size_t size, TypeHandle type_handle) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DeletedBufferChain::
|
||||
deallocate(void *ptr, TypeHandle type_handle) {
|
||||
#ifdef USE_DELETED_CHAIN
|
||||
TAU_PROFILE("void DeletedBufferChain::deallocate(void *, TypeHandle)", " ", TAU_USER);
|
||||
assert(ptr != (void *)NULL);
|
||||
|
||||
@ -127,4 +133,8 @@ deallocate(void *ptr, TypeHandle type_handle) {
|
||||
_deleted_chain = obj;
|
||||
|
||||
_lock.release();
|
||||
|
||||
#else // USE_DELETED_CHAIN
|
||||
PANDA_FREE_SINGLE(ptr);
|
||||
#endif // USE_DELETED_CHAIN
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
static DeletedChain<Type> _chain;
|
||||
};
|
||||
|
||||
#ifdef USE_DELETED_CHAIN
|
||||
// Place this macro within a class definition to define appropriate
|
||||
// operator new and delete methods that take advantage of
|
||||
// DeletedChain.
|
||||
@ -131,6 +132,20 @@ public:
|
||||
#define ALLOC_DELETED_CHAIN_DEF(Type) \
|
||||
DeletedChain< Type > Type::_deleted_chain;
|
||||
|
||||
#else // USE_DELETED_CHAIN
|
||||
|
||||
#define ALLOC_DELETED_CHAIN(Type) \
|
||||
inline static bool validate_ptr(const void *ptr) { \
|
||||
return (ptr != NULL); \
|
||||
}
|
||||
#define ALLOC_DELETED_CHAIN_DECL(Type) \
|
||||
inline static bool validate_ptr(const void *ptr) { \
|
||||
return (ptr != NULL); \
|
||||
}
|
||||
#define ALLOC_DELETED_CHAIN_DEF(Type)
|
||||
|
||||
#endif // USE_DELETED_CHAIN
|
||||
|
||||
#include "deletedChain.T"
|
||||
|
||||
#endif
|
||||
|
@ -189,9 +189,15 @@ heap_alloc_single(size_t size) {
|
||||
void *alloc = call_malloc(inflate_size(size));
|
||||
#endif
|
||||
|
||||
if (alloc == (void *)NULL) {
|
||||
cerr << "Out of memory!\n";
|
||||
abort();
|
||||
while (alloc == (void *)NULL) {
|
||||
alloc_fail();
|
||||
#ifdef MEMORY_HOOK_MALLOC_LOCK
|
||||
_lock.acquire();
|
||||
alloc = call_malloc(inflate_size(size));
|
||||
_lock.release();
|
||||
#else
|
||||
alloc = call_malloc(inflate_size(size));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
@ -255,9 +261,15 @@ heap_alloc_array(size_t size) {
|
||||
void *alloc = call_malloc(inflate_size(size));
|
||||
#endif
|
||||
|
||||
if (alloc == (void *)NULL) {
|
||||
cerr << "Out of memory!\n";
|
||||
abort();
|
||||
while (alloc == (void *)NULL) {
|
||||
alloc_fail();
|
||||
#ifdef MEMORY_HOOK_MALLOC_LOCK
|
||||
_lock.acquire();
|
||||
alloc = call_malloc(inflate_size(size));
|
||||
_lock.release();
|
||||
#else
|
||||
alloc = call_malloc(inflate_size(size));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
@ -298,9 +310,19 @@ heap_realloc_array(void *ptr, size_t size) {
|
||||
alloc = call_realloc(alloc, inflate_size(size));
|
||||
#endif
|
||||
|
||||
if (alloc == (void *)NULL) {
|
||||
cerr << "Out of memory!\n";
|
||||
abort();
|
||||
while (alloc == (void *)NULL) {
|
||||
alloc_fail();
|
||||
|
||||
// Recover the original pointer.
|
||||
alloc = ptr_to_alloc(ptr, orig_size);
|
||||
|
||||
#ifdef MEMORY_HOOK_MALLOC_LOCK
|
||||
_lock.acquire();
|
||||
alloc = call_realloc(alloc, inflate_size(size));
|
||||
_lock.release();
|
||||
#else
|
||||
alloc = call_realloc(alloc, inflate_size(size));
|
||||
#endif
|
||||
}
|
||||
|
||||
return alloc_to_ptr(alloc, size);
|
||||
@ -499,6 +521,29 @@ get_deleted_chain(size_t buffer_size) {
|
||||
return chain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MemoryHook::alloc_fail
|
||||
// Access: Protected, Virtual
|
||||
// Description: This callback method is called whenever a low-level
|
||||
// call to call_malloc() has returned NULL, indicating
|
||||
// failure.
|
||||
//
|
||||
// Since this method is called very low-level, and may
|
||||
// be in the middle of any number of critical sections,
|
||||
// it will be difficult for this callback initiate any
|
||||
// emergency high-level operation to make more memory
|
||||
// available. However, this module is set up to assume
|
||||
// that that's what this method does, and will make
|
||||
// another alloc attempt after it returns. Probably the
|
||||
// only sensible thing this method can do, however, is
|
||||
// just to display a message and abort.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MemoryHook::
|
||||
alloc_fail() {
|
||||
cerr << "Out of memory!\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MemoryHook::overflow_heap_size
|
||||
|
@ -67,6 +67,8 @@ public:
|
||||
|
||||
DeletedBufferChain *get_deleted_chain(size_t buffer_size);
|
||||
|
||||
virtual void alloc_fail();
|
||||
|
||||
private:
|
||||
INLINE static size_t inflate_size(size_t size);
|
||||
INLINE static void *alloc_to_ptr(void *alloc, size_t size);
|
||||
|
@ -25,6 +25,10 @@ static const size_t min_page_remaining_size = 16;
|
||||
// We always allocate at least this many bytes at a time.
|
||||
static const size_t min_page_size = 128 * 1024; // 128K
|
||||
|
||||
// We always allocate integer multiples of this many bytes, to
|
||||
// guarantee this minimum alignment.
|
||||
static const size_t alignment_size = sizeof(long);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NeverFreeMemory::Constructor
|
||||
// Access: Private
|
||||
@ -45,6 +49,9 @@ void *NeverFreeMemory::
|
||||
ns_alloc(size_t size) {
|
||||
_lock.acquire();
|
||||
|
||||
// Round up to the next alignment_size.
|
||||
size = ((size + alignment_size - 1) / alignment_size) * alignment_size;
|
||||
|
||||
_total_used += size;
|
||||
|
||||
// Look for a page that has sufficient space remaining.
|
||||
|
Loading…
x
Reference in New Issue
Block a user