multithreading optimizations, tau profiler, related changes

This commit is contained in:
David Rose 2006-04-05 19:36:05 +00:00
parent 6d0692fec6
commit 8a78fffd8f
337 changed files with 4380 additions and 2635 deletions

View File

@ -137,9 +137,9 @@
// Must global operator new and delete functions throw exceptions?
#define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
// What is the syntax of the STL allocator declaration? See
// LocalSetup.pp for allowable values.
#define STL_ALLOCATOR MODERN
// Modern versions of gcc do support the latest STL allocator
// definitions.
#define USE_STL_ALLOCATOR 1
// The dynamic library file extension (usually .so .dll or .dylib):
#define DYNAMIC_LIB_EXT .so

View File

@ -130,9 +130,8 @@
// Must global operator new and delete functions throw exceptions?
#define GLOBAL_OPERATOR_NEW_EXCEPTIONS
// What is the syntax of the STL allocator declaration? See
// LocalSetup.pp for allowable values.
#define STL_ALLOCATOR OLD
// The Irix compiler doesn't support the modern STL allocator.
#define USE_STL_ALLOCATOR
// The dynamic library file extension (usually .so .dll or .dylib):
#define DYNAMIC_LIB_EXT .so

View File

@ -7,7 +7,7 @@
//
// What additional flags should we pass to interrogate?
#define SYSTEM_IGATE_FLAGS -D__i386__ -D__const=const
#define SYSTEM_IGATE_FLAGS -D__i386__ -D__const=const -Dvolatile=
// Is the platform big-endian (like an SGI workstation) or
// little-endian (like a PC)? Define this to the empty string to
@ -136,9 +136,9 @@
// Must global operator new and delete functions throw exceptions?
#define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
// What is the syntax of the STL allocator declaration? See
// LocalSetup.pp for allowable values.
#define STL_ALLOCATOR MODERN
// Modern versions of gcc do support the latest STL allocator
// definitions.
#define USE_STL_ALLOCATOR 1
// The dynamic library file extension (usually .so .dll or .dylib):
#define DYNAMIC_LIB_EXT .so

View File

@ -173,9 +173,9 @@
// Must global operator new and delete functions throw exceptions?
#define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
// What is the syntax of the STL allocator declaration? See
// LocalSetup.pp for allowable values.
#define STL_ALLOCATOR MODERN
// Modern versions of gcc do support the latest STL allocator
// definitions.
#define USE_STL_ALLOCATOR 1
// The dynamic library file extension (usually .so .dll or .dylib):
#define DYNAMIC_LIB_EXT .dylib

View File

@ -122,10 +122,9 @@
// What level of compiler optimization/debug symbols should we build?
// The various optimize levels are defined as follows:
//
// 1 - No compiler optimizations, full debug symbols
// 2 - Full compiler optimizations, full debug symbols
// (if the compiler supports this)
// 3 - Full compiler optimizations, no debug symbols
// 1 - No compiler optimizations, debug symbols, debug heap, lots of checks
// 2 - Full compiler optimizations, debug symbols, debug heap, lots of checks
// 3 - Full compiler optimizations, full debug symbols, fewer checks
// 4 - Full optimizations, no debug symbols, and asserts removed
//
#define OPTIMIZE 3
@ -571,6 +570,13 @@
// (pthread_create(), etc.), define this true.
#define HAVE_POSIX_THREADS $[and $[isfile /usr/include/pthread.h],$[not $[WINDOWS_PLATFORM]]]
// If you're building for an i386 Linux machine, kernel version 2.6 or
// higher, and you want to use native Linux threading operations
// instead of Posix threads, define this. Warning: this is highly
// experimental code, is likely to crash, and will probably be removed
// in the future. Use Posix threads instead; they're much better.
#define HAVE_LINUX_NATIVE_THREADS
// Do you want to build in support for threading (multiprocessing)?
// Building in support for threading will enable Panda to take
// advantage of multiple CPU's if you have them (and if the OS
@ -628,6 +634,14 @@
// Do you want to build the audio interface?
#define HAVE_AUDIO 1
// The Tau profiler provides a multiplatform, thread-aware profiler.
// To use it, define TAU_MAKEFILE appropriately, define USE_TAU to 1,
// and rebuild the code with ppremake; make install.
#define TAU_MAKEFILE /usr/local/tau/i386_linux/lib/Makefile.tau-pthread-pdt
#define TAU_OPTS -optKeepFiles
#define TAU_CFLAGS -D_GNU_SOURCE
#define USE_TAU
// Info for the RAD game tools, Miles Sound System
// note this may be overwritten in wintools Config.pp
#define RAD_MSS_IPATH /usr/include/Miles6/include
@ -837,7 +851,7 @@
// relevant flags.
#defer CFLAGS_OPT1 $[CDEFINES_OPT1:%=-D%] -Wall -g
#defer CFLAGS_OPT2 $[CDEFINES_OPT2:%=-D%] -Wall -g $[OPTFLAGS]
#defer CFLAGS_OPT3 $[CDEFINES_OPT3:%=-D%] $[OPTFLAGS]
#defer CFLAGS_OPT3 $[CDEFINES_OPT3:%=-D%] -g $[OPTFLAGS]
#defer CFLAGS_OPT4 $[CDEFINES_OPT4:%=-D%] $[OPTFLAGS]
// What additional flags should be passed to both compilers when
@ -891,8 +905,8 @@
#defer SHARED_LIB_C++ $[cxx_ld] -undefined dynamic_lookup -dynamic -dynamiclib -o $[target] -install_name $[notdir $[target]] $[sources] $[lpath:%=-L%] $[libs:%=-l%] $[patsubst %,-framework %, $[frameworks]]
#defer BUNDLE_LIB_C++ $[cxx_ld] -undefined dynamic_lookup -bundle -o $[target] $[sources] $[lpath:%=-L%] $[libs:%=-l%] $[patsubst %,-framework %, $[frameworks]]
#else
#defer SHARED_LIB_C $[cc_ld] -shared -o $[target] $[sources] $[lpath:%=-L%] $[libs:%=-l%]
#defer SHARED_LIB_C++ $[cxx_ld] -shared -o $[target] $[sources] $[lpath:%=-L%] $[libs:%=-l%]
#defer SHARED_LIB_C $[cc_ld] -shared $[LFLAGS] -o $[target] $[sources] $[lpath:%=-L%] $[libs:%=-l%]
#defer SHARED_LIB_C++ $[cxx_ld] -shared $[LFLAGS] -o $[target] $[sources] $[lpath:%=-L%] $[libs:%=-l%]
#define BUNDLE_LIB_C++
#endif

View File

@ -459,6 +459,12 @@ $[cdefine HAVE_RTTI]
/* Do we have Posix threads? */
$[cdefine HAVE_POSIX_THREADS]
/* Do we want to build for Linux native threads? */
$[cdefine HAVE_LINUX_NATIVE_THREADS]
/* Is the code being compiled with the Tau profiler's instrumentor? */
$[cdefine USE_TAU]
/* Must global operator new and delete functions throw exceptions? */
$[cdefine GLOBAL_OPERATOR_NEW_EXCEPTIONS]
@ -490,38 +496,8 @@ $[cdefine USE_MEMORY_PTMALLOC2]
$[cdefine USE_MEMORY_MALLOC]
$[cdefine USE_MEMORY_NOWRAPPERS]
/* What style STL allocator should we declare? */
#define OLD_STYLE_ALLOCATOR
#define GNU_STYLE_ALLOCATOR
#define VC6_STYLE_ALLOCATOR
#define MODERN_STYLE_ALLOCATOR
#define NO_STYLE_ALLOCATOR
#if $[not $[DO_MEMORY_USAGE]]
// Without DO_MEMORY_USAGE, we never try to use custom allocators.
#set NO_STYLE_ALLOCATOR 1
#elif $[eq $[STL_ALLOCATOR], OLD]
// "OLD": Irix 6.2-era STL.
#set OLD_STYLE_ALLOCATOR 1
#elif $[eq $[STL_ALLOCATOR], GNU]
// "GNU": gcc 2.95-era.
#set GNU_STYLE_ALLOCATOR 1
#elif $[eq $[STL_ALLOCATOR], VC6]
// "VC6": Microsoft Visual C++ 6.
#set VC6_STYLE_ALLOCATOR 1
#elif $[eq $[STL_ALLOCATOR], MODERN]
// "MODERN": Have we finally come to a standard?
#set MODERN_STYLE_ALLOCATOR 1
#else
// Anything else is "unknown". We won't try to define allocators at
// all.
#set NO_STYLE_ALLOCATOR 1
#endif
$[cdefine OLD_STYLE_ALLOCATOR]
$[cdefine GNU_STYLE_ALLOCATOR]
$[cdefine VC6_STYLE_ALLOCATOR]
$[cdefine MODERN_STYLE_ALLOCATOR]
$[cdefine NO_STYLE_ALLOCATOR]
/* Can we define a modern-style STL allocator? */
$[cdefine USE_STL_ALLOCATOR]
$[cdefine IS_OSX]

View File

@ -331,6 +331,23 @@
// the target is not to be built.
#defer build_target $[BUILD_TARGET]
#if $[USE_TAU]
#defer compile_c $(TAU_COMPILER) $[TAU_OPTS] $[if $[SELECT_TAU],-optTauSelectFile=$[SELECT_TAU]] $[COMPILE_C] $[TAU_CFLAGS]
#defer compile_c++ $(TAU_COMPILER) $[TAU_OPTS] $[if $[SELECT_TAU],-optTauSelectFile=$[SELECT_TAU]] $[COMPILE_C++] $[TAU_CFLAGS] $[TAU_C++FLAGS]
#defer link_bin_c $(TAU_COMPILER) $[TAU_OPTS] $[if $[SELECT_TAU],-optTauSelectFile=$[SELECT_TAU]] $[LINK_BIN_C] $[TAU_CFLAGS]
#defer link_bin_c++ $(TAU_COMPILER) $[TAU_OPTS] $[if $[SELECT_TAU],-optTauSelectFile=$[SELECT_TAU]] $[LINK_BIN_C++] $[TAU_CFLAGS] $[TAU_C++FLAGS]
#defer shared_lib_c $(TAU_COMPILER) $[TAU_OPTS] $[if $[SELECT_TAU],-optTauSelectFile=$[SELECT_TAU]] $[SHARED_LIB_C] $[TAU_CFLAGS]
#defer shared_lib_c++ $(TAU_COMPILER) $[TAU_OPTS] $[if $[SELECT_TAU],-optTauSelectFile=$[SELECT_TAU]] $[SHARED_LIB_C++] $[TAU_CFLAGS] $[TAU_C++FLAGS]
#else
#defer compile_c $[COMPILE_C]
#defer compile_c++ $[COMPILE_C++]
#defer link_bin_c $[LINK_BIN_C]
#defer link_bin_c++ $[LINK_BIN_C++]
#defer shared_lib_c $[SHARED_LIB_C]
#defer shared_lib_c++ $[SHARED_LIB_C++]
#endif // USE_TAU
// This takes advantage of the above two variables to get the actual
// list of local libraries we are to link with, eliminating those that
@ -358,7 +375,7 @@
#defer get_sources \
$[SOURCES] \
$[if $[ne $[NO_COMBINED_SOURCES],], $[INCLUDED_SOURCES], $[get_combined_sources]]
$[if $[or $[NO_COMBINED_SOURCES],$[USE_TAU]], $[INCLUDED_SOURCES], $[get_combined_sources]]
#defer included_sources $[INCLUDED_SOURCES]

View File

@ -178,6 +178,10 @@
#### Generated automatically by $[PPREMAKE] $[PPREMAKE_VERSION] from $[SOURCEFILE].
################################# DO NOT EDIT ###########################
#if $[USE_TAU]
include $[TAU_MAKEFILE]
#endif
// If we are using GNU make, this will automatically enable the
// multiprocessor build mode according to the value in
// NUMBER_OF_PROCESSORS, which should be set by NT. Maybe this isn't
@ -213,6 +217,9 @@ $[TAB] rm -f $[patsubst %.yxx,%.cxx %.h,$[yxx_st_sources]] $[patsubst %.lxx,%.cx
#if $[py_sources]
$[TAB] rm -f *.pyc *.pyo // Also scrub out old generated Python code.
#endif
#if $[USE_TAU]
$[TAB] rm -f *.pdb *.inst.* // scrub out tau-generated files.
#endif
// 'cleanall' is intended to undo all the effects of running ppremake
// and building. It removes everything except the Makefile.
@ -344,9 +351,9 @@ $[varname] = $[sources]
$[target] : $[sources] $[static_lib_dependencies]
#if $[filter %.cxx %.yxx %.lxx,$[get_sources]]
$[TAB] $[SHARED_LIB_C++]
$[TAB] $[shared_lib_c++]
#else
$[TAB] $[SHARED_LIB_C]
$[TAB] $[shared_lib_c]
#endif
#if $[BUNDLE_EXT]
@ -454,9 +461,9 @@ $[varname] = $[patsubst %,$[%_obj],$[compile_sources]]
#define sources $($[varname])
$[target] : $[sources] $[static_lib_dependencies]
#if $[filter %.cxx %.yxx %.lxx,$[get_sources]]
$[TAB] $[SHARED_LIB_C++]
$[TAB] $[shared_lib_c++]
#else
$[TAB] $[SHARED_LIB_C]
$[TAB] $[shared_lib_c]
#endif
#end noinst_lib_target
@ -555,9 +562,9 @@ $[varname] = $[patsubst %,$[%_obj],$[compile_sources]]
#define flags $[lflags]
$[target] : $[sources] $[static_lib_dependencies]
#if $[filter %.cxx %.yxx %.lxx,$[get_sources]]
$[TAB] $[LINK_BIN_C++]
$[TAB] $[link_bin_c++]
#else
$[TAB] $[LINK_BIN_C]
$[TAB] $[link_bin_c]
#endif
#define installed_files \
@ -600,9 +607,9 @@ $[varname] = $[patsubst %,$[%_obj],$[compile_sources]]
#define flags $[lflags]
$[target] : $[sources] $[static_lib_dependencies]
#if $[filter %.cxx %.yxx %.lxx,$[get_sources]]
$[TAB] $[LINK_BIN_C++]
$[TAB] $[link_bin_c++]
#else
$[TAB] $[LINK_BIN_C]
$[TAB] $[link_bin_c]
#endif
#end noinst_bin_target test_bin_target
@ -680,7 +687,7 @@ $[TAB] cp $[target_prebuilt] $[target]
#endif
$[target] : $[source] $[get_depends $[source]]
$[TAB] $[COMPILE_C]
$[TAB] $[compile_c]
#end file
@ -700,7 +707,7 @@ $[TAB] $[COMPILE_C]
// Yacc must run before some files can be compiled, so all files
// depend on yacc having run.
$[target] : $[source] $[get_depends $[source]] $[yxx_sources:%.yxx=%.h]
$[TAB] $[COMPILE_C++]
$[TAB] $[compile_c++]
#end file

View File

@ -1,25 +1,73 @@
#define SELECT_TAU select.tau
#begin lib_target
#define TARGET dtoolbase
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
atomicAdjust.h \
atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \
atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
cmath.I cmath.h \
dallocator.T dallocator.h \
dtoolbase.cxx dtoolbase.h dtoolbase_cc.h dtoolsymbols.h \
deletedChain.h deletedChain.T \
dtoolbase.h dtoolbase_cc.h dtoolsymbols.h \
fakestringstream.h \
indent.I indent.h indent.cxx \
mutexImpl.h \
mutexDummyImpl.h mutexDummyImpl.I \
mutexNsprImpl.h mutexNsprImpl.I \
mutexLinuxImpl.h mutexLinuxImpl.I \
mutexPosixImpl.h mutexPosixImpl.I \
mutexWin32Impl.h mutexWin32Impl.I \
nearly_zero.h \
numeric_types.h \
selectThreadImpl.h \
stl_compares.I stl_compares.h \
pallocator.T pallocator.h \
pdeque.h plist.h pmap.h pset.h pvector.h \
dlmalloc.c
#define INCLUDED_SOURCES \
atomicAdjustDummyImpl.cxx \
atomicAdjustI386Impl.cxx \
atomicAdjustNsprImpl.cxx \
atomicAdjustPosixImpl.cxx \
atomicAdjustWin32Impl.cxx \
dtoolbase.cxx \
mutexDummyImpl.cxx \
mutexNsprImpl.cxx \
mutexLinuxImpl.cxx \
mutexPosixImpl.cxx \
mutexWin32Impl.cxx
#define INSTALL_HEADERS \
atomicAdjust.h \
atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \
atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
cmath.I cmath.h \
dallocator.T dallocator.h \
deletedChain.h deletedChain.T \
dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \
indent.I indent.h \
mutexImpl.h \
mutexDummyImpl.h mutexDummyImpl.I \
mutexNsprImpl.h mutexNsprImpl.I \
mutexLinuxImpl.h mutexLinuxImpl.I \
mutexPosixImpl.h mutexPosixImpl.I \
mutexWin32Impl.h mutexWin32Impl.I \
nearly_zero.h \
numeric_types.h \
selectThreadImpl.h \
stl_compares.I stl_compares.h \
pallocator.T pallocator.h \
pdeque.h plist.h pmap.h pset.h pvector.h
#end lib_target

View File

@ -1,4 +1,4 @@
// Filename: atomicAdjustImpl.h
// Filename: atomicAdjust.h
// Created by: drose (09Aug02)
//
////////////////////////////////////////////////////////////////////
@ -16,31 +16,43 @@
//
////////////////////////////////////////////////////////////////////
#ifndef ATOMICADJUSTIMPL_H
#define ATOMICADJUSTIMPL_H
#ifndef ATOMICADJUST_H
#define ATOMICADJUST_H
#include "pandabase.h"
#include "dtoolbase.h"
#include "selectThreadImpl.h"
#if defined(THREAD_DUMMY_IMPL)
#include "atomicAdjustDummyImpl.h"
typedef AtomicAdjustDummyImpl AtomicAdjustImpl;
typedef AtomicAdjustDummyImpl AtomicAdjust;
#elif defined(__i386__)
// For an i386 architecture, we'll always use the i386 implementation.
// It should be safe for any OS, and it might be a bit faster than
// any OS-provided calls.
#include "atomicAdjustI386Impl.h"
typedef AtomicAdjustI386Impl AtomicAdjust;
#elif defined(THREAD_WIN32_IMPL)
#include "atomicAdjustWin32Impl.h"
typedef AtomicAdjustWin32Impl AtomicAdjustImpl;
typedef AtomicAdjustWin32Impl AtomicAdjust;
#elif defined(THREAD_LINUX_IMPL)
#error Linux native threads are currently implemented only for i386; use Posix threads instead.
#elif defined(THREAD_POSIX_IMPL)
#include "atomicAdjustPosixImpl.h"
typedef AtomicAdjustPosixImpl AtomicAdjustImpl;
typedef AtomicAdjustPosixImpl AtomicAdjust;
#elif defined(THREAD_NSPR_IMPL)
#include "atomicAdjustNsprImpl.h"
typedef AtomicAdjustNsprImpl AtomicAdjustImpl;
typedef AtomicAdjustNsprImpl AtomicAdjust;
#endif

View File

@ -20,23 +20,23 @@
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustDummyImpl::inc
// Access: Public, Static
// Description: Atomically increments the indicated variable and
// returns the new value.
// Description: Atomically increments the indicated variable.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustDummyImpl::
INLINE void AtomicAdjustDummyImpl::
inc(PN_int32 &var) {
return ++var;
++var;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustDummyImpl::dec
// Access: Public, Static
// Description: Atomically decrements the indicated variable and
// returns the new value.
// returns true if the new value is nonzero, false if it
// is zero.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustDummyImpl::
INLINE bool AtomicAdjustDummyImpl::
dec(PN_int32 &var) {
return --var;
return (--var) != 0;
}
////////////////////////////////////////////////////////////////////
@ -65,3 +65,40 @@ INLINE PN_int32 AtomicAdjustDummyImpl::
get(const PN_int32 &var) {
return var;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustDummyImpl::compare_and_exchange
// Access: Public, Static
// Description: Atomic compare and exchange.
//
// If mem is equal to old_value, store new_value in mem.
// In either case, return the original value of mem.
// The caller can test for success by comparing
// return_value == old_value.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustDummyImpl::
compare_and_exchange(PN_int32 &mem, PN_int32 old_value,
PN_int32 new_value) {
PN_int32 orig_value = mem;
if (mem == old_value) {
mem = new_value;
}
return orig_value;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustDummyImpl::compare_and_exchange_ptr
// Access: Public, Static
// Description: Atomic compare and exchange.
//
// As above, but works on pointers instead of integers.
////////////////////////////////////////////////////////////////////
INLINE void *AtomicAdjustDummyImpl::
compare_and_exchange_ptr(void *&mem, void *old_value,
void *new_value) {
void *orig_value = mem;
if (mem == old_value) {
mem = new_value;
}
return orig_value;
}

View File

@ -19,26 +19,36 @@
#ifndef ATOMICADJUSTDUMMYIMPL_H
#define ATOMICADJUSTDUMMYIMPL_H
#include "pandabase.h"
#include "dtoolbase.h"
#include "selectThreadImpl.h"
#ifdef THREAD_DUMMY_IMPL
#include "pnotify.h"
#include "numeric_types.h"
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
////////////////////////////////////////////////////////////////////
// Class : AtomicAdjustDummyImpl
// Description : A trivial implementation for atomic adjustments for
// systems that don't require multiprogramming, and
// therefore don't require special atomic operations.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS AtomicAdjustDummyImpl {
class EXPCL_DTOOL AtomicAdjustDummyImpl {
public:
INLINE static PN_int32 inc(PN_int32 &var);
INLINE static PN_int32 dec(PN_int32 &var);
INLINE static void inc(PN_int32 &var);
INLINE static bool dec(PN_int32 &var);
INLINE static PN_int32 set(PN_int32 &var, PN_int32 new_value);
INLINE static PN_int32 get(const PN_int32 &var);
INLINE static PN_int32 compare_and_exchange(PN_int32 &mem,
PN_int32 old_value,
PN_int32 new_value);
INLINE static void *compare_and_exchange_ptr(void *&mem,
void *old_value,
void *new_value);
};
#include "atomicAdjustDummyImpl.I"

View File

@ -0,0 +1,129 @@
// Filename: atomicAdjustI386Impl.I
// Created by: drose (01Apr06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustI386Impl::inc
// Access: Public, Static
// Description: Atomically increments the indicated variable.
////////////////////////////////////////////////////////////////////
INLINE void AtomicAdjustI386Impl::
inc(volatile PN_int32 &var) {
#ifndef __EDG__
__asm__ __volatile__("lock; incl %0"
:"=m" (var)
:"m" (&var));
#endif // __EDG__
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustI386Impl::dec
// Access: Public, Static
// Description: Atomically decrements the indicated variable and
// returns true if the new value is nonzero, false if it
// is zero.
////////////////////////////////////////////////////////////////////
INLINE bool AtomicAdjustI386Impl::
dec(volatile PN_int32 &var) {
unsigned char c;
#ifndef __EDG__
__asm__ __volatile__("lock; decl %0; sete %1"
:"=m" (var), "=qm" (c)
:"m" (&var) : "memory");
#endif // __EDG__
return (c == 0);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustI386Impl::set
// Access: Public, Static
// Description: Atomically changes the indicated variable and
// returns the original value.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustI386Impl::
set(PN_int32 &var, PN_int32 new_value) {
PN_int32 orig_value = var;
var = new_value;
return orig_value;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustI386Impl::get
// Access: Public, Static
// Description: Atomically retrieves the snapshot value of the
// indicated variable. This is the only guaranteed safe
// way to retrieve the value that other threads might be
// asynchronously setting, incrementing, or decrementing
// (via other AtomicAjust methods).
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustI386Impl::
get(const PN_int32 &var) {
return var;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustI386Impl::compare_and_exchange
// Access: Public, Static
// Description: Atomic compare and exchange.
//
// If mem is equal to old_value, store new_value in mem.
// In either case, return the original value of mem.
// The caller can test for success by comparing
// return_value == old_value.
//
// The atomic function expressed in pseudo-code:
//
// orig_value = mem;
// if (mem == old_value) {
// mem = new_value;
// }
// return orig_value;
//
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustI386Impl::
compare_and_exchange(volatile PN_int32 &mem, PN_int32 old_value,
PN_int32 new_value) {
PN_int32 prev;
#ifndef __EDG__
__asm__ __volatile__("lock; cmpxchgl %1,%2"
: "=a"(prev)
: "r"(new_value), "m"(mem), "0"(old_value)
: "memory");
#endif // __EDG__
return prev;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustI386Impl::compare_and_exchange_ptr
// Access: Public, Static
// Description: Atomic compare and exchange.
//
// As above, but works on pointers instead of integers.
////////////////////////////////////////////////////////////////////
INLINE void *AtomicAdjustI386Impl::
compare_and_exchange_ptr(void * volatile &mem, void *old_value,
void *new_value) {
void *prev;
#ifndef __EDG__
__asm__ __volatile__("lock; cmpxchgl %1,%2"
: "=a"(prev)
: "r"(new_value), "m"(mem), "0"(old_value)
: "memory");
#endif // __EDG__
return prev;
}

View File

@ -1,5 +1,5 @@
// Filename: atomicAdjust.cxx
// Created by: drose (09Aug02)
// Filename: atomicAdjustI386Impl.cxx
// Created by: drose (28Mar06)
//
////////////////////////////////////////////////////////////////////
//
@ -16,4 +16,10 @@
//
////////////////////////////////////////////////////////////////////
#include "atomicAdjust.h"
#include "selectThreadImpl.h"
#ifdef __i386__
#include "atomicAdjustI386Impl.h"
#endif // __i386__

View File

@ -0,0 +1,59 @@
// Filename: atomicAdjustI386Impl.h
// Created by: drose (01Apr06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef ATOMICADJUSTI386IMPL_H
#define ATOMICADJUSTI386IMPL_H
#include "dtoolbase.h"
#include "selectThreadImpl.h"
#if defined(__i386__)
#include "numeric_types.h"
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
////////////////////////////////////////////////////////////////////
// Class : AtomicAdjustI386Impl
// Description : Uses assembly-language calls to atomically increment
// and decrement. Although this class is named i386, it
// actually uses instructions that are specific to 486
// and higher.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOL AtomicAdjustI386Impl {
public:
INLINE static void inc(volatile PN_int32 &var);
INLINE static bool dec(volatile PN_int32 &var);
INLINE static PN_int32 set(PN_int32 &var, PN_int32 new_value);
INLINE static PN_int32 get(const PN_int32 &var);
INLINE static PN_int32 compare_and_exchange(volatile PN_int32 &mem,
PN_int32 old_value,
PN_int32 new_value);
INLINE static void *compare_and_exchange_ptr(void * volatile &mem,
void *old_value,
void *new_value);
};
#include "atomicAdjustI386Impl.I"
#endif // __i386__
#endif

View File

@ -20,23 +20,23 @@
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustNsprImpl::inc
// Access: Public, Static
// Description: Atomically increments the indicated variable and
// returns the new value.
// Description: Atomically increments the indicated variable.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustNsprImpl::
INLINE void AtomicAdjustNsprImpl::
inc(PN_int32 &var) {
return PR_AtomicIncrement(&var);
PR_AtomicIncrement(&var);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustNsprImpl::dec
// Access: Public, Static
// Description: Atomically decrements the indicated variable and
// returns the new value.
// returns true if the new value is nonzero, false if it
// is zero.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustNsprImpl::
INLINE bool AtomicAdjustNsprImpl::
dec(PN_int32 &var) {
return PR_AtomicDecrement(&var);
return (PR_AtomicDecrement(&var) != 0);
}
////////////////////////////////////////////////////////////////////

View File

@ -24,7 +24,6 @@
#ifdef THREAD_NSPR_IMPL
#include "pnotify.h"
#include "numeric_types.h"
#include <pratom.h>
@ -33,10 +32,10 @@
// Class : AtomicAdjustNsprImpl
// Description : Uses NSPR to implement atomic adjustments.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS AtomicAdjustNsprImpl {
class EXPCL_DTOOL AtomicAdjustNsprImpl {
public:
INLINE static PN_int32 inc(PN_int32 &var);
INLINE static PN_int32 dec(PN_int32 &var);
INLINE static void inc(PN_int32 &var);
INLINE static bool dec(PN_int32 &var);
INLINE static PN_int32 set(PN_int32 &var, PN_int32 new_value);
INLINE static PN_int32 get(const PN_int32 &var);
};

View File

@ -20,29 +20,28 @@
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustPosixImpl::inc
// Access: Public, Static
// Description: Atomically increments the indicated variable and
// returns the new value.
// Description: Atomically increments the indicated variable.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustPosixImpl::
INLINE void AtomicAdjustPosixImpl::
inc(PN_int32 &var) {
pthread_mutex_lock(&_mutex);
PN_int32 result = ++var;
++var;
pthread_mutex_unlock(&_mutex);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustPosixImpl::dec
// Access: Public, Static
// Description: Atomically decrements the indicated variable and
// returns the new value.
// returns true if the new value is nonzero, false if it
// is zero.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustPosixImpl::
INLINE bool AtomicAdjustPosixImpl::
dec(PN_int32 &var) {
pthread_mutex_lock(&_mutex);
PN_int32 result = --var;
pthread_mutex_unlock(&_mutex);
return result;
return (result != 0);
}
////////////////////////////////////////////////////////////////////

View File

@ -19,12 +19,11 @@
#ifndef ATOMICADJUSTPOSIXIMPL_H
#define ATOMICADJUSTPOSIXIMPL_H
#include "pandabase.h"
#include "dtoolbase.h"
#include "selectThreadImpl.h"
#ifdef THREAD_POSIX_IMPL
#include "pnotify.h"
#include "numeric_types.h"
#include <pthread.h>
@ -33,10 +32,10 @@
// Class : AtomicAdjustPosixImpl
// Description : Uses POSIX to implement atomic adjustments.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS AtomicAdjustPosixImpl {
class EXPCL_DTOOL AtomicAdjustPosixImpl {
public:
INLINE static PN_int32 inc(PN_int32 &var);
INLINE static PN_int32 dec(PN_int32 &var);
INLINE static void inc(PN_int32 &var);
INLINE static bool dec(PN_int32 &var);
INLINE static PN_int32 set(PN_int32 &var, PN_int32 new_value);
INLINE static PN_int32 get(const PN_int32 &var);

View File

@ -20,23 +20,23 @@
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustWin32Impl::inc
// Access: Public, Static
// Description: Atomically increments the indicated variable and
// returns the new value.
// Description: Atomically increments the indicated variable.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustWin32Impl::
INLINE void AtomicAdjustWin32Impl::
inc(PN_int32 &var) {
return InterlockedIncrement((LONG *)&var);
InterlockedIncrement((LONG *)&var);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustWin32Impl::dec
// Access: Public, Static
// Description: Atomically decrements the indicated variable and
// returns the new value.
// returns true if the new value is nonzero, false if it
// is zero.
////////////////////////////////////////////////////////////////////
INLINE PN_int32 AtomicAdjustWin32Impl::
INLINE bool AtomicAdjustWin32Impl::
dec(PN_int32 &var) {
return InterlockedDecrement((LONG *)&var);
return (InterlockedDecrement((LONG *)&var) != 0);
}
////////////////////////////////////////////////////////////////////

View File

@ -24,7 +24,6 @@
#ifdef THREAD_WIN32_IMPL
#include "pnotify.h"
#include "numeric_types.h"
#include <windows.h>
@ -34,10 +33,10 @@
// Description : Uses Windows native calls to implement atomic
// adjustments.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS AtomicAdjustWin32Impl {
class EXPCL_DTOOL AtomicAdjustWin32Impl {
public:
INLINE static PN_int32 inc(PN_int32 &var);
INLINE static PN_int32 dec(PN_int32 &var);
INLINE static void inc(PN_int32 &var);
INLINE static bool dec(PN_int32 &var);
INLINE static PN_int32 set(PN_int32 &var, PN_int32 new_value);
INLINE static PN_int32 get(const PN_int32 &var);
};

View File

@ -16,46 +16,6 @@
//
////////////////////////////////////////////////////////////////////
#if defined(OLD_STYLE_ALLOCATOR)
template<class Type>
INLINE Type *dallocator<Type>::
allocate(size_t n) {
return (Type *)default_operator_new(n);
}
template<class Type>
INLINE void dallocator<Type>::
deallocate(void *p, size_t) {
default_operator_delete(p);
}
#elif defined(GNU_STYLE_ALLOCATOR)
template<class Type>
INLINE dallocator<Type>::
dallocator() {
}
template<class Type>
template<class _Tp1>
INLINE dallocator<Type>::
dallocator(const dallocator<_Tp1> &) {
}
template<class Type>
INLINE Type *dallocator<Type>::
allocate(size_t n) {
return (Type *)default_operator_new(n * sizeof(Type));
}
template<class Type>
INLINE void dallocator<Type>::
deallocate(void *p, size_t) {
default_operator_delete(p);
}
#elif MODERN_STYLE_ALLOCATOR
template<class Type>
INLINE dallocator<Type>::
@ -73,5 +33,3 @@ INLINE void dallocator<Type>::
deallocate(TYPENAME dallocator<Type>::pointer p, TYPENAME dallocator<Type>::size_type) {
(*global_operator_delete)(p);
}
#endif // *_STYLE_ALLOCATOR

View File

@ -35,46 +35,14 @@
// within the MemoryUsage class itself.
////////////////////////////////////////////////////////////////////
#if defined(NO_STYLE_ALLOCATOR)
#ifndef USE_STL_ALLOCATOR
// If we're not trying to make custom allocators (either we don't know
// what kind of syntax this STL library wants, or we're compiling with
// OPTIMIZE 4), then simply use the standard allocator.
#define dallocator allocator
#elif defined(OLD_STYLE_ALLOCATOR)
// Early versions of gcc wanted to use their own kind of allocator,
// somewhat different from the STL standard. Irix uses this one too.
// It might be inherited from an early draft of the STL standard.
#else
template<class Type>
class dallocator : public alloc {
public:
INLINE static Type *allocate(size_t n);
INLINE static void deallocate(void *p, size_t n);
};
#elif defined(GNU_STYLE_ALLOCATOR)
// Later versions of gcc want to use a still different,
// not-quite-standard definition. Sheesh.
template<class Type>
class dallocator : public allocator<Type> {
public:
INLINE dallocator();
template<class _Tp1>
INLINE dallocator(const dallocator<_Tp1> &other);
INLINE Type *allocate(size_t n);
INLINE void deallocate(void *p, size_t n);
template <class _Tp1> struct rebind {
typedef dallocator<_Tp1> other;
};
};
#elif defined(MODERN_STYLE_ALLOCATOR)
// The final specification?
template<class Type>
class dallocator : public allocator<Type> {
public:
@ -95,31 +63,14 @@ public:
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
INLINE void deallocate(pointer p, size_type n);
/*
#ifdef __GNUC__
template<class Subtype>
INLINE void destroy(Subtype *p) {
p->~Subtype();
}
template<class Subtype>
INLINE void construct(Subtype *p, const Subtype &value) {
::new(p) Subtype(value);
}
#endif // __GNUC__
*/
template<class U> struct rebind {
typedef dallocator<U> other;
};
};
#else
#error Unrecognized allocator symbol defined!
#endif // *_STYLE_ALLOCATOR
#ifndef NO_STYLE_ALLOCATOR
#include "dallocator.T"
#endif
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -0,0 +1,100 @@
// Filename: deletedChain.T
// Created by: drose (01Apr06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
template<class Type>
TYPENAME DeletedChain<Type>::ObjectNode *DeletedChain<Type>::_deleted_chain;
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
template<class Type>
MutexImpl DeletedChain<Type>::_lock;
#endif
////////////////////////////////////////////////////////////////////
// Function: DeletedChain::allocate
// Access: Public, Static
// Description: Allocates the memory for a new object of Type.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE Type *DeletedChain<Type>::
allocate(size_t size) {
assert(size <= sizeof(Type));
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
_lock.lock();
if (_deleted_chain != (ObjectNode *)NULL) {
ObjectNode *obj = _deleted_chain;
_deleted_chain = _deleted_chain->_next;
_lock.release();
return (Type *)obj;
}
_lock.release();
#else // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
ObjectNode *obj = _deleted_chain;
while (obj != (ObjectNode *)NULL) {
ObjectNode *result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void *&)_deleted_chain, (void *)obj, (void *)obj->_next);
if (result == obj) {
// We got it.
return (Type *)obj;
}
// Someone else grabbed the top link first. Try again.
obj = _deleted_chain;
}
#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
// If we get here, the deleted_chain is empty; we have to allocate a
// new object from the system pool.
#ifdef DO_MEMORY_USAGE
return (Type *)(*global_operator_new)(sizeof(Type));
#else
return (Type *)malloc(sizeof(Type));
#endif
}
////////////////////////////////////////////////////////////////////
// Function: DeletedChain::deallocate
// Access: Public
// Description: Frees the memory for an object of Type.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void DeletedChain<Type>::
deallocate(Type *ptr) {
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
_lock.lock();
ObjectNode *obj = (ObjectNode *)ptr;
obj->_next = _deleted_chain;
_deleted_chain = obj;
_lock.release();
#else // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
ObjectNode *obj = (ObjectNode *)ptr;
ObjectNode *result;
do {
obj->_next = _deleted_chain;
result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void *&)_deleted_chain, (void *)obj->_next, (void *)obj);
// Keep trying until no one else got to _deleted_chain first.
} while (result != obj->_next);
#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
}

View File

@ -0,0 +1,99 @@
// Filename: deletedChain.h
// Created by: drose (01Apr06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef DELETEDCHAIN_H
#define DELETEDCHAIN_H
#include "dtoolbase.h"
#include "mutexImpl.h"
#include "atomicAdjust.h"
#include <assert.h>
////////////////////////////////////////////////////////////////////
// Class : DeletedChain
// Description : This template class can be used to provide faster
// allocation/deallocation for many Panda objects. It
// works by maintaining a linked list of deleted objects
// that are all of the same type; when a new object is
// allocated that matches that type, the same space is
// just reused.
//
// This is particularly important to do in the case of a
// multithreaded pipeline, so we minimize contention
// between the parallel threads. If we didn't do this,
// the threads might compete overmuch on the system
// mutex protecting the malloc() call. This way, there
// can be a different mutex for each type of object; or on
// some systems (e.g. i386), no mutex at all.
//
// Of course, this trick of maintaining the deleted
// object chain won't work in the presence of
// polymorphism, where you might have many classes that
// derive from a base class, and all of them have a
// different size--unless you instantiate a DeletedChain
// for *every* kind of derived class. The
// ALLOC_DELETED_CHAIN macro, below, is designed to make
// this easy.
////////////////////////////////////////////////////////////////////
template<class Type>
class DeletedChain {
public:
INLINE static Type *allocate(size_t size);
INLINE static void deallocate(Type *ptr);
private:
class ObjectNode {
public:
ObjectNode *_next;
};
// Ideally, the compiler and linker will unify all references to
// this static pointer for a given type, as per the C++ spec.
// However, if the compiler fails to do this (*cough* Microsoft), it
// won't be a big deal; it just means there will be multiple
// unrelated chains of deleted objects for a particular type.
static ObjectNode *_deleted_chain;
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
// If we don't have atomic compare-and-exchange, we need to use a
// Mutex to protect the above linked list.
static MutexImpl _lock;
#endif
};
// Place this macro within a class definition to define appropriate
// operator new and delete methods that take advantage of
// DeletedChain.
#define ALLOC_DELETED_CHAIN(Type) \
inline void *operator new(size_t size) { \
return (void *)DeletedChain<Type>::allocate(size); \
} \
inline void *operator new(size_t size, void *ptr) { \
return ptr; \
} \
inline void operator delete(void *ptr) { \
DeletedChain<Type>::deallocate((Type *)ptr); \
} \
inline void operator delete(void *, void *) { \
}
#include "deletedChain.T"
#endif

View File

@ -138,6 +138,108 @@
#include <stdtypedefs.h>
#endif
#ifdef USE_TAU
/* If we're building with the Tau instrumentor, include the
appropriate header file to pick up the TAU macros. */
#include <TAU.h>
#else
/* Otherwise, if we're not building with the Tau instrumentor, turn
off all the TAU macros. We could include the Tau header file to do
this, but it's better not to assume that Tau is installed. */
#define TAU_TYPE_STRING(profileString, str)
#define TAU_PROFILE(name, type, group)
#define TAU_PROFILE_TIMER(var, name, type, group)
#define TAU_PROFILE_START(var)
#define TAU_PROFILE_STOP(var)
#define TAU_PROFILE_STMT(stmt)
#define TAU_PROFILE_EXIT(msg)
#define TAU_PROFILE_INIT(argc, argv)
#define TAU_PROFILE_SET_NODE(node)
#define TAU_PROFILE_SET_CONTEXT(context)
#define TAU_PROFILE_SET_GROUP_NAME(newname)
#define TAU_PROFILE_TIMER_SET_GROUP_NAME(t, newname)
#define TAU_PROFILE_CALLSTACK()
#define TAU_DB_DUMP()
#define TAU_DB_PURGE()
#define TAU_REGISTER_CONTEXT_EVENT(event, name)
#define TAU_CONTEXT_EVENT(event, data)
#define TAU_DISABLE_CONTEXT_EVENT(event)
#define TAU_ENABLE_CONTEXT_EVENT(event)
#define TAU_REGISTER_EVENT(event, name)
#define TAU_EVENT(event, data)
#define TAU_EVENT_DISABLE_MIN(event)
#define TAU_EVENT_DISABLE_MAX(event)
#define TAU_EVENT_DISABLE_MEAN(event)
#define TAU_EVENT_DISABLE_STDDEV(event)
#define TAU_REPORT_STATISTICS()
#define TAU_REPORT_THREAD_STATISTICS()
#define TAU_REGISTER_THREAD()
#define TAU_REGISTER_FORK(id, op)
#define TAU_ENABLE_INSTRUMENTATION()
#define TAU_DISABLE_INSTRUMENTATION()
#define TAU_ENABLE_GROUP(group)
#define TAU_DISABLE_GROUP(group)
#define TAU_ENABLE_GROUP_NAME(group)
#define TAU_DISABLE_GROUP_NAME(group)
#define TAU_ENABLE_ALL_GROUPS()
#define TAU_DISABLE_ALL_GROUPS()
#define TAU_TRACK_MEMORY()
#define TAU_TRACK_MEMORY_HERE()
#define TAU_ENABLE_TRACKING_MEMORY()
#define TAU_DISABLE_TRACKING_MEMORY()
#define TAU_TRACK_MEMORY()
#define TAU_TRACK_MEMORY_HERE()
#define TAU_ENABLE_TRACKING_MUSE_EVENTS()
#define TAU_DISABLE_TRACKING_MUSE_EVENTS()
#define TAU_TRACK_MUSE_EVENTS()
#define TAU_SET_INTERRUPT_INTERVAL(value)
#define TAU_TRACE_SENDMSG(type, destination, length)
#define TAU_TRACE_RECVMSG(type, source, length)
#define TAU_MAPPING(stmt, group) stmt
#define TAU_MAPPING_OBJECT(FuncInfoVar)
#define TAU_MAPPING_LINK(FuncInfoVar, Group)
#define TAU_MAPPING_PROFILE(FuncInfoVar)
#define TAU_MAPPING_CREATE(name, type, key, groupname, tid)
#define TAU_MAPPING_PROFILE_TIMER(Timer, FuncInfoVar, tid)
#define TAU_MAPPING_TIMER_CREATE(t, name, type, gr, group_name)
#define TAU_MAPPING_PROFILE_START(Timer, tid)
#define TAU_MAPPING_PROFILE_STOP(tid)
#define TAU_MAPPING_PROFILE_EXIT(msg, tid)
#define TAU_MAPPING_DB_DUMP(tid)
#define TAU_MAPPING_DB_PURGE(tid)
#define TAU_MAPPING_PROFILE_SET_NODE(node, tid)
#define TAU_MAPPING_PROFILE_SET_GROUP_NAME(timer, name)
#define TAU_PROFILE_TIMER_SET_NAME(t, newname)
#define TAU_PROFILE_TIMER_SET_TYPE(t, newname)
#define TAU_PROFILE_TIMER_SET_GROUP(t, id)
#define TAU_MAPPING_PROFILE_SET_NAME(timer, name)
#define TAU_MAPPING_PROFILE_SET_TYPE(timer, name)
#define TAU_MAPPING_PROFILE_SET_GROUP(timer, id)
#define TAU_MAPPING_PROFILE_GET_GROUP_NAME(timer)
#define TAU_MAPPING_PROFILE_GET_GROUP(timer)
#define TAU_MAPPING_PROFILE_GET_NAME(timer)
#define TAU_MAPPING_PROFILE_GET_TYPE(timer)
#define TAU_PHASE(name, type, group)
#define TAU_PHASE_CREATE_STATIC(var, name, type, group)
#define TAU_PHASE_CREATE_DYNAMIC(var, name, type, group)
#define TAU_PHASE_START(var)
#define TAU_PHASE_STOP(var)
#define TAU_GLOBAL_PHASE(timer, name, type, group)
#define TAU_GLOBAL_PHASE_START(timer)
#define TAU_GLOBAL_PHASE_STOP(timer)
#define TAU_GLOBAL_PHASE_EXTERNAL(timer)
#define TAU_GLOBAL_TIMER(timer, name, type, group)
#define TAU_GLOBAL_TIMER_EXTERNAL(timer)
#define TAU_GLOBAL_TIMER_START(timer)
#define TAU_GLOBAL_TIMER_STOP()
#endif // USE_TAU
/*
We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket
functions and global variable definitions that are to be published

View File

@ -0,0 +1,5 @@
#include "atomicAdjustDummyImpl.cxx"
#include "atomicAdjustI386Impl.cxx"
#include "atomicAdjustNsprImpl.cxx"
#include "atomicAdjustPosixImpl.cxx"
#include "atomicAdjustWin32Impl.cxx"

View File

@ -0,0 +1,6 @@
#include "dtoolbase.cxx"
#include "mutexDummyImpl.cxx"
#include "mutexNsprImpl.cxx"
#include "mutexLinuxImpl.cxx"
#include "mutexPosixImpl.cxx"
#include "mutexWin32Impl.cxx"

View File

@ -24,15 +24,13 @@
#ifdef THREAD_DUMMY_IMPL
#include "pnotify.h"
////////////////////////////////////////////////////////////////////
// Class : MutexDummyImpl
// Description : A fake mutex implementation for single-threaded
// applications that don't need any synchronization
// control. This does nothing at all.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG MutexDummyImpl {
class EXPCL_DTOOL MutexDummyImpl {
public:
INLINE MutexDummyImpl();
INLINE ~MutexDummyImpl();

View File

@ -36,6 +36,12 @@ typedef MutexWin32Impl MutexImpl;
typedef MutexWin32Impl ReMutexImpl; // Win32 Mutexes are always reentrant.
#define HAVE_REMUTEXIMPL 1
#elif defined(THREAD_LINUX_IMPL)
#include "mutexLinuxImpl.h"
typedef MutexLinuxImpl MutexImpl;
#undef HAVE_REMUTEXIMPL // The futex implementation is non-reentrant.
#elif defined(THREAD_POSIX_IMPL)
#include "mutexPosixImpl.h"

View File

@ -0,0 +1,38 @@
// Filename: mutexLinuxImpl.I
// Created by: drose (28Mar06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: MutexLinuxImpl::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE MutexLinuxImpl::
MutexLinuxImpl() {
_mode = M_unlocked;
}
////////////////////////////////////////////////////////////////////
// Function: MutexLinuxImpl::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE MutexLinuxImpl::
~MutexLinuxImpl() {
assert(_mode == M_unlocked);
}

View File

@ -0,0 +1,64 @@
// Filename: mutexLinuxImpl.cxx
// Created by: drose (28Mar06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "selectThreadImpl.h"
#ifdef THREAD_LINUX_IMPL
#include "mutexLinuxImpl.h"
#include "atomicAdjust.h"
#include <linux/futex.h>
#include <sys/time.h>
#include <sys/syscall.h>
////////////////////////////////////////////////////////////////////
// Function: MutexLinuxImpl::lock
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void MutexLinuxImpl::
lock() {
PN_int32 c;
c = AtomicAdjust::compare_and_exchange
(_mode, M_unlocked, M_locked_no_waiters);
while (c != M_unlocked) {
if (c == M_locked_with_waiters ||
AtomicAdjust::compare_and_exchange(_mode, M_locked_no_waiters,
M_locked_with_waiters) != M_unlocked) {
syscall(SYS_futex, &_mode, FUTEX_WAIT, M_locked_with_waiters, (void *)NULL);
}
c = AtomicAdjust::compare_and_exchange
(_mode, M_unlocked, M_locked_with_waiters);
}
}
////////////////////////////////////////////////////////////////////
// Function: MutexLinuxImpl::release
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void MutexLinuxImpl::
release() {
if (AtomicAdjust::dec(_mode)) {
_mode = M_unlocked;
syscall(SYS_futex, &_mode, FUTEX_WAKE, 1);
}
}
#endif // THREAD_LINUX_IMPL

View File

@ -1,5 +1,5 @@
// Filename: atomicAdjust.h
// Created by: drose (09Aug02)
// Filename: mutexLinuxImpl.h
// Created by: drose (28Mar06)
//
////////////////////////////////////////////////////////////////////
//
@ -16,28 +16,43 @@
//
////////////////////////////////////////////////////////////////////
#ifndef ATOMICADJUST_H
#define ATOMICADJUST_H
#ifndef MUTEXLINUXIMPL_H
#define MUTEXLINUXIMPL_H
#include "dtoolbase.h"
#include "selectThreadImpl.h"
#ifdef THREAD_LINUX_IMPL
#include "pandabase.h"
#include "atomicAdjustImpl.h"
#include "numeric_types.h"
#undef MUTEX_DEFINES_TRYLOCK
////////////////////////////////////////////////////////////////////
// Class : AtomicAdjust
// Description : A suite of functions to atomically adjust a numeric
// value. Some platforms require a bit more work than
// others to guarantee that a multibyte value is changed
// in one atomic operation.
// Class : MutexLinuxImpl
// Description : Uses Linux threads to implement a mutex.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEXPRESS AtomicAdjust {
class EXPCL_DTOOL MutexLinuxImpl {
public:
INLINE static PN_int32 inc(PN_int32 &var);
INLINE static PN_int32 dec(PN_int32 &var);
INLINE static PN_int32 set(PN_int32 &var, PN_int32 new_value);
INLINE static PN_int32 get(const PN_int32 &var);
INLINE MutexLinuxImpl();
INLINE ~MutexLinuxImpl();
void lock();
void release();
private:
enum Mode {
M_unlocked = 0,
M_locked_no_waiters = 1,
M_locked_with_waiters = 2,
};
PN_int32 _mode;
friend class ConditionVarLinuxImpl;
};
#include "atomicAdjust.I"
#include "mutexLinuxImpl.I"
#endif // THREAD_LINUX_IMPL
#endif

View File

@ -25,7 +25,7 @@
INLINE MutexNsprImpl::
MutexNsprImpl() {
_lock = PR_NewLock();
nassertv(_lock != (PRLock *)NULL);
assert(_lock != (PRLock *)NULL);
}
////////////////////////////////////////////////////////////////////
@ -68,5 +68,5 @@ try_lock() {
INLINE void MutexNsprImpl::
release() {
int status = PR_Unlock(_lock);
nassertv(status == PR_SUCCESS);
assert(status == PR_SUCCESS);
}

View File

@ -24,8 +24,6 @@
#ifdef THREAD_NSPR_IMPL
#include "pnotify.h"
#include <prlock.h>
#undef MUTEX_DEFINES_TRYLOCK
@ -34,7 +32,7 @@
// Class : MutexNsprImpl
// Description : Uses NSPR to implement a mutex.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG MutexNsprImpl {
class EXPCL_DTOOL MutexNsprImpl {
public:
INLINE MutexNsprImpl();
INLINE ~MutexNsprImpl();

View File

@ -24,12 +24,13 @@
////////////////////////////////////////////////////////////////////
INLINE MutexPosixImpl::
MutexPosixImpl() {
TAU_PROFILE("MutexPosixImpl::MutexPosixImpl", " ", TAU_USER);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
int result = pthread_mutex_init(&_lock, &attr);
pthread_mutexattr_destroy(&attr);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -39,8 +40,9 @@ MutexPosixImpl() {
////////////////////////////////////////////////////////////////////
INLINE MutexPosixImpl::
~MutexPosixImpl() {
TAU_PROFILE("MutexPosixImpl::~MutexPosixImpl", " ", TAU_USER);
int result = pthread_mutex_destroy(&_lock);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -50,8 +52,9 @@ INLINE MutexPosixImpl::
////////////////////////////////////////////////////////////////////
INLINE void MutexPosixImpl::
lock() {
TAU_PROFILE("MutexPosixImpl::lock", " ", TAU_USER);
int result = pthread_mutex_lock(&_lock);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -61,8 +64,9 @@ lock() {
////////////////////////////////////////////////////////////////////
INLINE bool MutexPosixImpl::
try_lock() {
TAU_PROFILE("MutexPosixImpl::try_lock", " ", TAU_USER);
int result = pthread_mutex_trylock(&_lock);
nassertr(result == 0 || result == EBUSY, false);
assert(result == 0 || result == EBUSY);
return (result == 0);
}
@ -73,8 +77,9 @@ try_lock() {
////////////////////////////////////////////////////////////////////
INLINE void MutexPosixImpl::
release() {
TAU_PROFILE("MutexPosixImpl::release", " ", TAU_USER);
int result = pthread_mutex_unlock(&_lock);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -84,12 +89,13 @@ release() {
////////////////////////////////////////////////////////////////////
INLINE ReMutexPosixImpl::
ReMutexPosixImpl() {
TAU_PROFILE("ReMutexPosixImpl::ReMutexPosixImpl", " ", TAU_USER);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
int result = pthread_mutex_init(&_lock, &attr);
pthread_mutexattr_destroy(&attr);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -99,8 +105,9 @@ ReMutexPosixImpl() {
////////////////////////////////////////////////////////////////////
INLINE ReMutexPosixImpl::
~ReMutexPosixImpl() {
TAU_PROFILE("ReMutexPosixImpl::~ReMutexPosixImpl", " ", TAU_USER);
int result = pthread_mutex_destroy(&_lock);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -110,8 +117,9 @@ INLINE ReMutexPosixImpl::
////////////////////////////////////////////////////////////////////
INLINE void ReMutexPosixImpl::
lock() {
TAU_PROFILE("ReMutexPosixImpl::lock", " ", TAU_USER);
int result = pthread_mutex_lock(&_lock);
nassertv(result == 0);
assert(result == 0);
}
////////////////////////////////////////////////////////////////////
@ -121,8 +129,9 @@ lock() {
////////////////////////////////////////////////////////////////////
INLINE bool ReMutexPosixImpl::
try_lock() {
TAU_PROFILE("ReMutexPosixImpl::try_lock", " ", TAU_USER);
int result = pthread_mutex_trylock(&_lock);
nassertr(result == 0 || result == EBUSY, false);
assert(result == 0 || result == EBUSY);
return (result == 0);
}
@ -133,6 +142,7 @@ try_lock() {
////////////////////////////////////////////////////////////////////
INLINE void ReMutexPosixImpl::
release() {
TAU_PROFILE("ReMutexPosixImpl::release", " ", TAU_USER);
int result = pthread_mutex_unlock(&_lock);
nassertv(result == 0);
assert(result == 0);
}

View File

@ -24,8 +24,6 @@
#ifdef THREAD_POSIX_IMPL
#include "pnotify.h"
#include <pthread.h>
#include <errno.h>
@ -35,7 +33,7 @@
// Class : MutexPosixImpl
// Description : Uses Posix threads to implement a mutex.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG MutexPosixImpl {
class EXPCL_DTOOL MutexPosixImpl {
public:
INLINE MutexPosixImpl();
INLINE ~MutexPosixImpl();
@ -53,7 +51,7 @@ private:
// Class : ReMutexPosixImpl
// Description : Uses Posix threads to implement a reentrant mutex.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG ReMutexPosixImpl {
class EXPCL_DTOOL ReMutexPosixImpl {
public:
INLINE ReMutexPosixImpl();
INLINE ~ReMutexPosixImpl();

View File

@ -24,8 +24,6 @@
#ifdef THREAD_WIN32_IMPL
#include "pnotify.h"
#include <windows.h>
#define MUTEX_DEFINES_TRYLOCK 1
@ -34,7 +32,7 @@
// Class : MutexWin32Impl
// Description : Uses Windows native calls to implement a mutex.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG MutexWin32Impl {
class EXPCL_DTOOL MutexWin32Impl {
public:
INLINE MutexWin32Impl();
INLINE ~MutexWin32Impl();

View File

@ -16,77 +16,42 @@
//
////////////////////////////////////////////////////////////////////
#if defined(OLD_STYLE_ALLOCATOR)
template<class Type>
INLINE Type *pallocator<Type>::
allocate(size_t n) {
return (Type *)(*global_operator_new)(n);
INLINE pallocator_single<Type>::
pallocator_single() throw() {
}
template<class Type>
INLINE void pallocator<Type>::
deallocate(void *p, size_t) {
INLINE TYPENAME pallocator_single<Type>::pointer pallocator_single<Type>::
allocate(TYPENAME pallocator_single<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
TAU_PROFILE("pallocator_single:allocate()", " ", TAU_USER);
// This doesn't support allocating arrays.
assert(n == 1);
return DeletedChain<Type>::allocate(sizeof(Type));
}
template<class Type>
INLINE void pallocator_single<Type>::
deallocate(TYPENAME pallocator_single<Type>::pointer p, TYPENAME pallocator_single<Type>::size_type) {
TAU_PROFILE("pallocator_single:deallocate()", " ", TAU_USER);
return DeletedChain<Type>::deallocate(p);
}
template<class Type>
INLINE pallocator_array<Type>::
pallocator_array() throw() {
}
template<class Type>
INLINE TYPENAME pallocator_array<Type>::pointer pallocator_array<Type>::
allocate(TYPENAME pallocator_array<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
TAU_PROFILE("pallocator_array:allocate()", " ", TAU_USER);
return (TYPENAME pallocator_array<Type>::pointer)(*global_operator_new)(n * sizeof(Type));
}
template<class Type>
INLINE void pallocator_array<Type>::
deallocate(TYPENAME pallocator_array<Type>::pointer p, TYPENAME pallocator_array<Type>::size_type) {
TAU_PROFILE("pallocator_array:deallocate()", " ", TAU_USER);
(*global_operator_delete)(p);
}
#elif defined(GNU_STYLE_ALLOCATOR)
template<class Type>
INLINE pallocator<Type>::
pallocator() {
}
template<class Type>
template<class _Tp1>
INLINE pallocator<Type>::
pallocator(const pallocator<_Tp1> &) {
}
template<class Type>
INLINE Type *pallocator<Type>::
allocate(size_t n) {
return (Type *)(*global_operator_new)(n * sizeof(Type));
}
template<class Type>
INLINE void pallocator<Type>::
deallocate(void *p, size_t) {
(*global_operator_delete)(p);
}
#elif VC6_STYLE_ALLOCATOR
template<class Type>
INLINE pallocator<Type>::pointer pallocator<Type>::
allocate(pallocator<Type>::size_type n, allocator<void>::const_pointer) {
return (pallocator<Type>::pointer)(*global_operator_new)(n * sizeof(Type));
}
template<class Type>
INLINE void pallocator<Type>::
//deallocate(pallocator<Type>::pointer p, allocator<Type>::size_type) {
deallocate(void *p, allocator<Type>::size_type) {
(*global_operator_delete)(p);
}
#elif MODERN_STYLE_ALLOCATOR
template<class Type>
INLINE pallocator<Type>::
pallocator() throw() {
}
template<class Type>
INLINE TYPENAME pallocator<Type>::pointer pallocator<Type>::
allocate(TYPENAME pallocator<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
return (TYPENAME pallocator<Type>::pointer)(*global_operator_new)(n * sizeof(Type));
}
template<class Type>
INLINE void pallocator<Type>::
deallocate(TYPENAME pallocator<Type>::pointer p, TYPENAME pallocator<Type>::size_type) {
(*global_operator_delete)(p);
}
#endif // *_STYLE_ALLOCATOR

View File

@ -21,7 +21,7 @@
#include <memory>
#include "dtoolbase.h"
#include "deletedChain.h"
////////////////////////////////////////////////////////////////////
// Class : pallocator
@ -32,60 +32,24 @@
//
// pvector, pmap, etc. are all defined in this directory
// to use a pallocator.
// pallocator actually comes it two flavors now:
// pallocator_single, which can only allocate single
// instances of an object, and pallocator_array, which
// can allocate arrays of objects.
////////////////////////////////////////////////////////////////////
#if defined(NO_STYLE_ALLOCATOR)
#ifndef USE_STL_ALLOCATOR
// If we're not trying to make custom allocators (either we don't know
// what kind of syntax this STL library wants, or we're compiling with
// OPTIMIZE 4), then simply use the standard allocator.
#define pallocator allocator
#define pallocator_single allocator
#define pallocator_array allocator
#elif defined(OLD_STYLE_ALLOCATOR)
// Early versions of gcc wanted to use their own kind of allocator,
// somewhat different from the STL standard. Irix uses this one too.
// It might be inherited from an early draft of the STL standard.
#else
template<class Type>
class pallocator : public alloc {
public:
INLINE static Type *allocate(size_t n);
INLINE static void deallocate(void *p, size_t n);
};
#elif defined(GNU_STYLE_ALLOCATOR)
// Later versions of gcc want to use a still different,
// not-quite-standard definition. Sheesh.
template<class Type>
class pallocator : public allocator<Type> {
public:
INLINE pallocator();
template<class _Tp1>
INLINE pallocator(const pallocator<_Tp1> &other);
INLINE Type *allocate(size_t n);
INLINE void deallocate(void *p, size_t n);
template <class _Tp1> struct rebind {
typedef pallocator<_Tp1> other;
};
};
#elif defined(VC6_STYLE_ALLOCATOR)
// The VC6-era definition.
template<class Type>
class pallocator : public allocator<Type> {
public:
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
INLINE void deallocate(void *p, size_type n);
};
#elif defined(MODERN_STYLE_ALLOCATOR)
// The final specification?
template<class Type>
class pallocator : public allocator<Type> {
class pallocator_single : public allocator<Type> {
public:
// Nowadays we cannot implicitly inherit typedefs from base classes
// in a template class; we must explicitly copy them here.
@ -95,42 +59,48 @@ public:
typedef TYPENAME allocator<Type>::const_reference const_reference;
typedef TYPENAME allocator<Type>::size_type size_type;
INLINE pallocator() throw();
INLINE pallocator_single() throw();
// template member functions in VC++ can only be defined in-class.
template<class U>
INLINE pallocator(const pallocator<U> &) throw() { }
INLINE pallocator_single(const pallocator_single<U> &) throw() { }
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
INLINE void deallocate(pointer p, size_type n);
/*
#ifdef __GNUC__
// The gcc 4.0 version seems to pass any old type to construct() and
// destroy(), so we need template methods.
template<class Subtype>
INLINE void construct(Subtype *p, const Subtype &value) {
::new(p) Subtype(value);
}
template<class Subtype>
INLINE void destroy(Subtype *p) {
p->~Subtype();
}
#endif // __GNUC__
*/
template<class U> struct rebind {
typedef pallocator<U> other;
typedef pallocator_single<U> other;
};
};
#else
#error Unrecognized allocator symbol defined!
#endif // *_STYLE_ALLOCATOR
template<class Type>
class pallocator_array : public allocator<Type> {
public:
// Nowadays we cannot implicitly inherit typedefs from base classes
// in a template class; we must explicitly copy them here.
typedef TYPENAME allocator<Type>::pointer pointer;
typedef TYPENAME allocator<Type>::reference reference;
typedef TYPENAME allocator<Type>::const_pointer const_pointer;
typedef TYPENAME allocator<Type>::const_reference const_reference;
typedef TYPENAME allocator<Type>::size_type size_type;
INLINE pallocator_array() throw();
// template member functions in VC++ can only be defined in-class.
template<class U>
INLINE pallocator_array(const pallocator_array<U> &) throw() { }
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
INLINE void deallocate(pointer p, size_type n);
template<class U> struct rebind {
typedef pallocator_array<U> other;
};
};
#ifndef NO_STYLE_ALLOCATOR
#include "pallocator.T"
#endif
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -23,7 +23,7 @@
#include "pallocator.h"
#include <deque>
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
// If we're not using custom allocators, just use the standard class
// definition.
#define pdeque deque
@ -38,14 +38,14 @@
// memory.
////////////////////////////////////////////////////////////////////
template<class Type>
class pdeque : public deque<Type, pallocator<Type> > {
class pdeque : public deque<Type, pallocator_array<Type> > {
public:
typedef TYPENAME deque<Type, pallocator<Type> >::size_type size_type;
pdeque() : deque<Type, pallocator<Type> >() { }
pdeque(const pdeque<Type> &copy) : deque<Type, pallocator<Type> >(copy) { }
pdeque(size_type n) : deque<Type, pallocator<Type> >(n) { }
pdeque(size_type n, const Type &value) : deque<Type, pallocator<Type> >(n, value) { }
typedef TYPENAME deque<Type, pallocator_array<Type> >::size_type size_type;
pdeque() : deque<Type, pallocator_array<Type> >() { }
pdeque(const pdeque<Type> &copy) : deque<Type, pallocator_array<Type> >(copy) { }
pdeque(size_type n) : deque<Type, pallocator_array<Type> >(n) { }
pdeque(size_type n, const Type &value) : deque<Type, pallocator_array<Type> >(n, value) { }
};
#endif // NO_STYLE_ALLOCATOR
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -23,7 +23,7 @@
#include "pallocator.h"
#include <list>
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
// If we're not using custom allocators, just use the standard class
// definition.
#define plist list
@ -38,19 +38,19 @@
// memory.
////////////////////////////////////////////////////////////////////
template<class Type>
class plist : public list<Type, pallocator<Type> > {
class plist : public list<Type, pallocator_single<Type> > {
public:
typedef TYPENAME list<Type, pallocator<Type> >::size_type size_type;
plist() : list<Type, pallocator<Type> >() { }
plist(const plist<Type> &copy) : list<Type, pallocator<Type> >(copy) { }
plist(size_type n) : list<Type, pallocator<Type> >(n) { }
plist(size_type n, const Type &value) : list<Type, pallocator<Type> >(n, value) { }
typedef TYPENAME list<Type, pallocator_single<Type> >::size_type size_type;
plist() : list<Type, pallocator_single<Type> >() { }
plist(const plist<Type> &copy) : list<Type, pallocator_single<Type> >(copy) { }
plist(size_type n) : list<Type, pallocator_single<Type> >(n) { }
plist(size_type n, const Type &value) : list<Type, pallocator_single<Type> >(n, value) { }
typedef TYPENAME list<Type, pallocator<Type> >::iterator iterator;
typedef TYPENAME list<Type, pallocator<Type> >::const_iterator const_iterator;
typedef TYPENAME list<Type, pallocator<Type> >::reverse_iterator reverse_iterator;
typedef TYPENAME list<Type, pallocator<Type> >::const_reverse_iterator const_reverse_iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::iterator iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::const_iterator const_iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::reverse_iterator reverse_iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::const_reverse_iterator const_reverse_iterator;
};
#endif // NO_STYLE_ALLOCATOR
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -28,7 +28,7 @@
#include <hash_map>
#endif
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
// If we're not using custom allocators, just use the standard class
// definition.
#define pmap map
@ -42,7 +42,7 @@
#define phash_multimap multimap
#endif // HAVE_STL_HASH
#else // NO_STYLE_ALLOCATOR
#else // USE_STL_ALLOCATOR
////////////////////////////////////////////////////////////////////
// Class : pmap
@ -52,11 +52,65 @@
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Value, class Compare = less<Key> >
class pmap : public map<Key, Value, Compare, pallocator<pair<const Key, Value> > > {
class pmap : public map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > {
public:
pmap() : map<Key, Value, Compare, pallocator<pair<const Key, Value> > >() { }
pmap(const pmap<Key, Value, Compare> &copy) : map<Key, Value, Compare, pallocator<pair<const Key, Value> > >(copy) { }
pmap(const Compare &comp) : map<Key, Value, Compare, pallocator<pair<const Key, Value> > >(comp) { }
typedef map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > base_class;
pmap() : base_class() { }
pmap(const pmap<Key, Value, Compare> &copy) : base_class(copy) { }
pmap(const Compare &comp) : base_class(comp) { }
#ifdef USE_TAU
TYPENAME base_class::mapped_type &
operator [] (const TYPENAME base_class::key_type &k) {
TAU_PROFILE("pmap::operator [] (const key_type &)", " ", TAU_USER);
return base_class::operator [] (k);
}
std::pair<TYPENAME base_class::iterator, bool>
insert(const TYPENAME base_class::value_type &x) {
TAU_PROFILE("pmap::insert(const value_type &)", " ", TAU_USER);
return base_class::insert(x);
}
TYPENAME base_class::iterator
insert(TYPENAME base_class::iterator position,
const TYPENAME base_class::value_type &x) {
TAU_PROFILE("pmap::insert(iterator, const value_type &)", " ", TAU_USER);
return base_class::insert(position, x);
}
void
erase(TYPENAME base_class::iterator position) {
TAU_PROFILE("pmap::erase(iterator)", " ", TAU_USER);
base_class::erase(position);
}
TYPENAME base_class::size_type
erase(const TYPENAME base_class::key_type &x) {
TAU_PROFILE("pmap::erase(const key_type &)", " ", TAU_USER);
return base_class::erase(x);
}
void
clear() {
TAU_PROFILE("pmap::clear()", " ", TAU_USER);
base_class::clear();
}
TYPENAME base_class::iterator
find(const TYPENAME base_class::key_type &x) {
TAU_PROFILE("pmap::find(const key_type &)", " ", TAU_USER);
return base_class::find(x);
}
TYPENAME base_class::const_iterator
find(const TYPENAME base_class::key_type &x) const {
TAU_PROFILE("pmap::find(const key_type &)", " ", TAU_USER);
return base_class::find(x);
}
#endif // USE_TAU
};
////////////////////////////////////////////////////////////////////
@ -67,11 +121,11 @@ public:
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Value, class Compare = less<Key> >
class pmultimap : public multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > > {
class pmultimap : public multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > {
public:
pmultimap() : multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > >() { }
pmultimap(const pmultimap<Key, Value, Compare> &copy) : multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > >(copy) { }
pmultimap(const Compare &comp) : multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > >(comp) { }
pmultimap() : multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >() { }
pmultimap(const pmultimap<Key, Value, Compare> &copy) : multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(copy) { }
pmultimap(const Compare &comp) : multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(comp) { }
};
#ifdef HAVE_STL_HASH
@ -83,11 +137,11 @@ public:
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Value, class Compare = method_hash<Key, less<Key> > >
class phash_map : public hash_map<Key, Value, Compare, pallocator<pair<const Key, Value> > > {
class phash_map : public hash_map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > {
public:
phash_map() : hash_map<Key, Value, Compare, pallocator<pair<const Key, Value> > >() { }
phash_map(const phash_map<Key, Value, Compare> &copy) : hash_map<Key, Value, Compare, pallocator<pair<const Key, Value> > >(copy) { }
phash_map(const Compare &comp) : hash_map<Key, Value, Compare, pallocator<pair<const Key, Value> > >(comp) { }
phash_map() : hash_map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >() { }
phash_map(const phash_map<Key, Value, Compare> &copy) : hash_map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(copy) { }
phash_map(const Compare &comp) : hash_map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(comp) { }
};
////////////////////////////////////////////////////////////////////
@ -98,11 +152,11 @@ public:
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Value, class Compare = method_hash<Key, less<Key> > >
class phash_multimap : public hash_multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > > {
class phash_multimap : public hash_multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > {
public:
phash_multimap() : hash_multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > >() { }
phash_multimap(const phash_multimap<Key, Value, Compare> &copy) : hash_multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > >(copy) { }
phash_multimap(const Compare &comp) : hash_multimap<Key, Value, Compare, pallocator<pair<const Key, Value> > >(comp) { }
phash_multimap() : hash_multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >() { }
phash_multimap(const phash_multimap<Key, Value, Compare> &copy) : hash_multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(copy) { }
phash_multimap(const Compare &comp) : hash_multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(comp) { }
};
#else // HAVE_STL_HASH
@ -110,5 +164,5 @@ public:
#define phash_multimap pmultimap
#endif // HAVE_STL_HASH
#endif // NO_STYLE_ALLOCATOR
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -28,7 +28,7 @@
#include <hash_set>
#endif
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
// If we're not using custom allocators, just use the standard class
// definition.
#define pset set
@ -42,7 +42,7 @@
#define phash_multiset multiset
#endif // HAVE_STL_HASH
#else // NO_STYLE_ALLOCATOR
#else // USE_STL_ALLOCATOR
////////////////////////////////////////////////////////////////////
// Class : pset
@ -52,11 +52,57 @@
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Compare = less<Key> >
class pset : public set<Key, Compare, pallocator<Key> > {
class pset : public set<Key, Compare, pallocator_single<Key> > {
public:
pset() : set<Key, Compare, pallocator<Key> >() { }
pset(const pset<Key, Compare> &copy) : set<Key, Compare, pallocator<Key> >(copy) { }
pset(const Compare &comp) : set<Key, Compare, pallocator<Key> >(comp) { }
typedef set<Key, Compare, pallocator_single<Key> > base_class;
pset() : base_class() { }
pset(const pset<Key, Compare> &copy) : base_class(copy) { }
pset(const Compare &comp) : base_class(comp) { }
#ifdef USE_TAU
std::pair<TYPENAME base_class::iterator, bool>
insert(const TYPENAME base_class::value_type &x) {
TAU_PROFILE("pset::insert(const value_type &)", " ", TAU_USER);
return base_class::insert(x);
}
TYPENAME base_class::iterator
insert(TYPENAME base_class::iterator position,
const TYPENAME base_class::value_type &x) {
TAU_PROFILE("pset::insert(iterator, const value_type &)", " ", TAU_USER);
return base_class::insert(position, x);
}
void
erase(TYPENAME base_class::iterator position) {
TAU_PROFILE("pset::erase(iterator)", " ", TAU_USER);
base_class::erase(position);
}
TYPENAME base_class::size_type
erase(const TYPENAME base_class::key_type &x) {
TAU_PROFILE("pset::erase(const key_type &)", " ", TAU_USER);
return base_class::erase(x);
}
void
clear() {
TAU_PROFILE("pset::clear()", " ", TAU_USER);
base_class::clear();
}
TYPENAME base_class::iterator
find(const TYPENAME base_class::key_type &x) {
TAU_PROFILE("pset::find(x)", " ", TAU_USER);
return base_class::find(x);
}
TYPENAME base_class::const_iterator
find(const TYPENAME base_class::key_type &x) const {
TAU_PROFILE("pset::find(x)", " ", TAU_USER);
return base_class::find(x);
}
#endif // USE_TAU
};
////////////////////////////////////////////////////////////////////
@ -67,11 +113,11 @@ public:
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Compare = less<Key> >
class pmultiset : public multiset<Key, Compare, pallocator<Key> > {
class pmultiset : public multiset<Key, Compare, pallocator_single<Key> > {
public:
pmultiset() : multiset<Key, Compare, pallocator<Key> >() { }
pmultiset(const pmultiset<Key, Compare> &copy) : multiset<Key, Compare, pallocator<Key> >(copy) { }
pmultiset(const Compare &comp) : multiset<Key, Compare, pallocator<Key> >(comp) { }
pmultiset() : multiset<Key, Compare, pallocator_single<Key> >() { }
pmultiset(const pmultiset<Key, Compare> &copy) : multiset<Key, Compare, pallocator_single<Key> >(copy) { }
pmultiset(const Compare &comp) : multiset<Key, Compare, pallocator_single<Key> >(comp) { }
};
#ifdef HAVE_STL_HASH
@ -83,11 +129,11 @@ public:
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Compare = method_hash<Key, less<Key> > >
class phash_set : public hash_set<Key, Compare, pallocator<Key> > {
class phash_set : public hash_set<Key, Compare, pallocator_single<Key> > {
public:
phash_set() : hash_set<Key, Compare, pallocator<Key> >() { }
phash_set(const phash_set<Key, Compare> &copy) : hash_set<Key, Compare, pallocator<Key> >(copy) { }
phash_set(const Compare &comp) : hash_set<Key, Compare, pallocator<Key> >(comp) { }
phash_set() : hash_set<Key, Compare, pallocator_single<Key> >() { }
phash_set(const phash_set<Key, Compare> &copy) : hash_set<Key, Compare, pallocator_single<Key> >(copy) { }
phash_set(const Compare &comp) : hash_set<Key, Compare, pallocator_single<Key> >(comp) { }
};
////////////////////////////////////////////////////////////////////
@ -98,11 +144,11 @@ public:
// memory.
////////////////////////////////////////////////////////////////////
template<class Key, class Compare = method_hash<Key, less<Key> > >
class phash_multiset : public hash_multiset<Key, Compare, pallocator<Key> > {
class phash_multiset : public hash_multiset<Key, Compare, pallocator_single<Key> > {
public:
phash_multiset() : hash_multiset<Key, Compare, pallocator<Key> >() { }
phash_multiset(const phash_multiset<Key, Compare> &copy) : hash_multiset<Key, Compare, pallocator<Key> >(copy) { }
phash_multiset(const Compare &comp) : hash_multiset<Key, Compare, pallocator<Key> >(comp) { }
phash_multiset() : hash_multiset<Key, Compare, pallocator_single<Key> >() { }
phash_multiset(const phash_multiset<Key, Compare> &copy) : hash_multiset<Key, Compare, pallocator_single<Key> >(copy) { }
phash_multiset(const Compare &comp) : hash_multiset<Key, Compare, pallocator_single<Key> >(comp) { }
};
#else // HAVE_STL_HASH
@ -110,5 +156,5 @@ public:
#define phash_multiset pmultiset
#endif // HAVE_STL_HASH
#endif // NO_STYLE_ALLOCATOR
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -24,7 +24,7 @@
#include "dtoolbase.h"
#include "pallocator.h"
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
// If we're not using custom allocators, just use the standard class
// definition.
#define pvector vector
@ -39,17 +39,26 @@
// memory.
////////////////////////////////////////////////////////////////////
template<class Type>
class pvector : public vector<Type, pallocator<Type> > {
class pvector : public vector<Type, pallocator_array<Type> > {
public:
typedef TYPENAME vector<Type, pallocator<Type> >::size_type size_type;
typedef vector<Type, pallocator_array<Type> > base_class;
typedef TYPENAME base_class::size_type size_type;
pvector() : vector<Type, pallocator<Type> >() { }
pvector(const pvector<Type> &copy) : vector<Type, pallocator<Type> >(copy) { }
pvector(size_type n) : vector<Type, pallocator<Type> >(n) { }
pvector(size_type n, const Type &value) : vector<Type, pallocator<Type> >(n, value) { }
pvector(const Type *begin, const Type *end) : vector<Type, pallocator<Type> >(begin, end) { }
pvector() : base_class() { }
pvector(const pvector<Type> &copy) : base_class(copy) { }
pvector(size_type n) : base_class(n) { }
pvector(size_type n, const Type &value) : base_class(n, value) { }
pvector(const Type *begin, const Type *end) : base_class(begin, end) { }
#ifdef USE_TAU
void
push_back(const TYPENAME base_class::value_type &x) {
TAU_PROFILE("pvector::push_back(const value_type &)", " ", TAU_USER);
base_class::push_back(x);
}
#endif // USE_TAU
};
#endif // NO_STYLE_ALLOCATOR
#endif // USE_STL_ALLOCATOR
#endif

View File

@ -0,0 +1,4 @@
BEGIN_EXCLUDE_LIST
void *default_operator_new#
void default_operator_delete#
END_EXCLUDE_LIST

View File

@ -43,6 +43,11 @@
// In Windows, use the native threading library.
#define THREAD_WIN32_IMPL 1
#elif defined(HAVE_LINUX_NATIVE_THREADS)
// In Linux, we might want to use the low-level system calls.
#define THREAD_LINUX_IMPL 1
#elif defined(HAVE_POSIX_THREADS)
// Posix threads are nice.

View File

@ -21,6 +21,7 @@
#include "dtoolbase.h"
#include "pmap.h"
#include "pvector.h"
////////////////////////////////////////////////////////////////////
// Class : PandaSystem

View File

@ -52,7 +52,7 @@
#ifdef HAVE_DINKUM
// With the Dinkum library, we must first export the base class,
// _Vector_val.
#define VV_BASE std::_Vector_val<TYPE, pallocator<TYPE> >
#define VV_BASE std::_Vector_val<TYPE, pallocator_array<TYPE> >
#pragma warning (disable : 4231)
EXPORT_TEMPLATE_CLASS(EXPCL, EXPTP, VV_BASE)
#undef VV_BASE
@ -61,10 +61,10 @@ EXPORT_TEMPLATE_CLASS(EXPCL, EXPTP, VV_BASE)
// Now we can export the vector class.
#pragma warning (disable : 4231)
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
EXPORT_TEMPLATE_CLASS(EXPCL, EXPTP, std::vector<TYPE>)
#else
#define STD_VECTOR std::vector<TYPE, pallocator<TYPE> >
#define STD_VECTOR std::vector<TYPE, pallocator_array<TYPE> >
EXPORT_TEMPLATE_CLASS(EXPCL, EXPTP, STD_VECTOR)
#undef STD_VECTOR
EXPORT_TEMPLATE_CLASS(EXPCL, EXPTP, pvector<TYPE>)
@ -74,7 +74,7 @@ EXPORT_TEMPLATE_CLASS(EXPCL, EXPTP, pvector<TYPE>)
// Now make a typedef for the vector.
#ifdef NO_STYLE_ALLOCATOR
#ifndef USE_STL_ALLOCATOR
typedef std::vector<TYPE> NAME;
#else
typedef pvector<TYPE> NAME;

View File

@ -3,63 +3,47 @@
#begin lib_target
#define TARGET interrogatedb
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
config_interrogatedb.h indexRemapper.h interrogateComponent.I \
interrogateComponent.h interrogateDatabase.I \
interrogateDatabase.h interrogateElement.I \
interrogateElement.h interrogateFunction.I \
interrogateFunction.h interrogateFunctionWrapper.I \
interrogateFunctionWrapper.h interrogateManifest.I \
interrogateManifest.h interrogateType.I interrogateType.h \
interrogate_datafile.I interrogate_datafile.h \
interrogate_interface.h interrogate_request.h \
mutexImpl.h \
mutexDummyImpl.h mutexDummyImpl.I \
mutexNsprImpl.h mutexNsprImpl.I \
mutexPosixImpl.h mutexPosixImpl.I \
mutexWin32Impl.h mutexWin32Impl.I \
py_panda.h \
register_type.I register_type.h \
selectThreadImpl.h \
typedObject.I typedObject.h \
typeHandle.I typeHandle.h \
typeRegistry.I typeRegistry.h \
typeRegistryNode.I typeRegistryNode.h \
vector_int.h
config_interrogatedb.h indexRemapper.h interrogateComponent.I \
interrogateComponent.h interrogateDatabase.I \
interrogateDatabase.h interrogateElement.I \
interrogateElement.h interrogateFunction.I \
interrogateFunction.h interrogateFunctionWrapper.I \
interrogateFunctionWrapper.h interrogateManifest.I \
interrogateManifest.h interrogateType.I interrogateType.h \
interrogate_datafile.I interrogate_datafile.h \
interrogate_interface.h interrogate_request.h \
py_panda.h \
register_type.I register_type.h \
typedObject.I typedObject.h \
typeHandle.I typeHandle.h \
typeRegistry.I typeRegistry.h \
typeRegistryNode.I typeRegistryNode.h \
vector_int.h
#define INCLUDED_SOURCES \
config_interrogatedb.cxx \
dtool_super_base.cxx \
indexRemapper.cxx \
interrogateComponent.cxx interrogateDatabase.cxx \
interrogateElement.cxx interrogateFunction.cxx \
interrogateFunctionWrapper.cxx interrogateManifest.cxx \
interrogateType.cxx interrogate_datafile.cxx \
interrogate_interface.cxx interrogate_request.cxx \
mutexDummyImpl.cxx \
mutexNsprImpl.cxx \
mutexPosixImpl.cxx \
mutexWin32Impl.cxx \
py_panda.cxx \
register_type.cxx \
typedObject.cxx \
typeHandle.cxx \
typeRegistry.cxx typeRegistryNode.cxx \
vector_int.cxx
config_interrogatedb.cxx \
dtool_super_base.cxx \
indexRemapper.cxx \
interrogateComponent.cxx interrogateDatabase.cxx \
interrogateElement.cxx interrogateFunction.cxx \
interrogateFunctionWrapper.cxx interrogateManifest.cxx \
interrogateType.cxx interrogate_datafile.cxx \
interrogate_interface.cxx interrogate_request.cxx \
py_panda.cxx \
register_type.cxx \
typedObject.cxx \
typeHandle.cxx \
typeRegistry.cxx typeRegistryNode.cxx \
vector_int.cxx
#define INSTALL_HEADERS \
interrogate_interface.h interrogate_request.h vector_int.h \
config_interrogatedb.h \
mutexImpl.h \
mutexDummyImpl.h mutexDummyImpl.I \
mutexNsprImpl.h mutexNsprImpl.I \
mutexPosixImpl.h mutexPosixImpl.I \
mutexWin32Impl.h mutexWin32Impl.I \
py_panda.h \
register_type.I register_type.h \
selectThreadImpl.h \
typedObject.I typedObject.h \
typeHandle.I typeHandle.h \
typeRegistry.I typeRegistry.h \

View File

@ -20,6 +20,7 @@
#include "interrogateDatabase.h"
#include "interrogateType.h"
#include "interrogateFunction.h"
#include "config_interrogatedb.h"
// This function adds one more directory to the list of directories
// search for interrogate (*.in) files. In the past, this list has

View File

@ -1,9 +1,5 @@
#include "interrogateType.cxx"
#include "interrogate_request.cxx"
#include "mutexDummyImpl.cxx"
#include "mutexNsprImpl.cxx"
#include "mutexPosixImpl.cxx"
#include "mutexWin32Impl.cxx"
#include "py_panda.cxx"
#include "register_type.cxx"
#include "typedObject.cxx"

View File

@ -80,6 +80,7 @@ INLINE void ConfigDeclaration::
set_string_value(const string &string_value) {
_string_value = string_value;
_got_words = false;
invalidate_cache();
}
////////////////////////////////////////////////////////////////////

View File

@ -84,6 +84,7 @@ set_string_word(int n, const string &value) {
_string_value += (*wi)._str;
++wi;
}
invalidate_cache();
}
////////////////////////////////////////////////////////////////////
@ -102,6 +103,7 @@ set_bool_word(int n, bool value) {
_words[n]._flags |= (F_checked_bool | F_valid_bool);
_words[n]._bool = value;
invalidate_cache();
}
////////////////////////////////////////////////////////////////////
@ -118,6 +120,7 @@ set_int_word(int n, int value) {
_words[n]._flags |= (F_checked_int | F_valid_int);
_words[n]._int = value;
invalidate_cache();
}
////////////////////////////////////////////////////////////////////
@ -134,6 +137,7 @@ set_double_word(int n, double value) {
_words[n]._flags |= (F_checked_double | F_valid_double);
_words[n]._double = value;
invalidate_cache();
}
////////////////////////////////////////////////////////////////////

View File

@ -20,6 +20,7 @@
#define CONFIGDECLARATION_H
#include "dtoolbase.h"
#include "configFlags.h"
#include "configPage.h"
#include "vector_string.h"
@ -33,7 +34,7 @@ class ConfigVariableCore;
// a pairing of a string name (actually, a
// ConfigVariableCore pointer) to a string value.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG ConfigDeclaration {
class EXPCL_DTOOLCONFIG ConfigDeclaration : public ConfigFlags {
private:
ConfigDeclaration(ConfigPage *page, ConfigVariableCore *variable,
const string &string_value, int decl_seq);

View File

@ -16,3 +16,52 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ConfigFlags::is_cache_valid
// Access: Protected, Static
// Description: Returns true if the local object's cache is still
// valid (based on a comparison of the supplied
// local_modified value with the global_modified value).
////////////////////////////////////////////////////////////////////
INLINE bool ConfigFlags::
is_cache_valid(PN_int32 local_modified) {
return local_modified == _global_modified;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigFlags::mark_cache_valid
// Access: Protected, Static
// Description: Updates the indicated local_modified value so that
// the cache will appear to be valid, until someone next
// calls invalidate_cache().
////////////////////////////////////////////////////////////////////
INLINE void ConfigFlags::
mark_cache_valid(PN_int32 &local_modified) {
local_modified = _global_modified;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigFlags::initial_invalid_cache
// Access: Protected, Static
// Description: Returns a value that will be appropriate for
// initializing a local_modified value. This value will
// indicate an invalid cache in the next call to
// is_cache_valid().
////////////////////////////////////////////////////////////////////
INLINE PN_int32 ConfigFlags::
initial_invalid_cache() {
return _global_modified - 1;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigFlags::invalidate_cache
// Access: Protected, Static
// Description: Invalidates all of the global ConfigVariable caches
// in the world at once, by incrementing the
// global_modified counter.
////////////////////////////////////////////////////////////////////
INLINE void ConfigFlags::
invalidate_cache() {
AtomicAdjust::inc(_global_modified);
}

View File

@ -18,6 +18,8 @@
#include "configFlags.h"
PN_int32 ConfigFlags::_global_modified;
////////////////////////////////////////////////////////////////////
// Function: ConfigFlags::Type output operator
// Description:

View File

@ -20,6 +20,8 @@
#define CONFIGFLAGS_H
#include "dtoolbase.h"
#include "numeric_types.h"
#include "atomicAdjust.h"
////////////////////////////////////////////////////////////////////
// Class : ConfigFlags
@ -60,9 +62,20 @@ PUBLISHED:
// shouldn't pass this in directly.
F_dconfig = 0x00008000,
};
protected:
INLINE static bool is_cache_valid(PN_int32 local_modified);
INLINE static void mark_cache_valid(PN_int32 &local_modified);
INLINE static PN_int32 initial_invalid_cache();
INLINE static void invalidate_cache();
private:
static PN_int32 _global_modified;
};
ostream &operator << (ostream &out, ConfigFlags::ValueType type);
#include "configFlags.I"
#endif

View File

@ -304,6 +304,7 @@ reload_implicit_pages() {
}
_currently_loading = false;
invalidate_cache();
}
////////////////////////////////////////////////////////////////////
@ -320,6 +321,7 @@ make_explicit_page(const string &name) {
++_next_page_seq;
_explicit_pages.push_back(page);
_pages_sorted = false;
invalidate_cache();
return page;
}
@ -340,6 +342,7 @@ delete_explicit_page(ConfigPage *page) {
if ((*pi) == page) {
_explicit_pages.erase(pi);
delete page;
invalidate_cache();
return true;
}
}

View File

@ -20,6 +20,7 @@
#define CONFIGPAGEMANAGER_H
#include "dtoolbase.h"
#include "configFlags.h"
#include "pvector.h"
#include "dSearchPath.h"
#include "globPattern.h"
@ -33,7 +34,7 @@ class ConfigPage;
// everywhere in the world, and keeps them in sorted
// order.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG ConfigPageManager {
class EXPCL_DTOOLCONFIG ConfigPageManager : public ConfigFlags {
protected:
ConfigPageManager();
~ConfigPageManager();

View File

@ -24,7 +24,8 @@
////////////////////////////////////////////////////////////////////
INLINE ConfigVariableBool::
ConfigVariableBool(const string &name) :
ConfigVariable(name, VT_bool)
ConfigVariable(name, VT_bool),
_local_modified(initial_invalid_cache())
{
_core->set_used();
}
@ -37,7 +38,12 @@ ConfigVariableBool(const string &name) :
INLINE ConfigVariableBool::
ConfigVariableBool(const string &name, bool default_value,
const string &description, int flags) :
ConfigVariable(name, VT_bool, description, flags)
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, VT_bool, description, flags),
#else
ConfigVariable(name, VT_bool, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value ? "1" : "0");
_core->set_used();
@ -51,7 +57,12 @@ ConfigVariableBool(const string &name, bool default_value,
INLINE ConfigVariableBool::
ConfigVariableBool(const string &name, const string &default_value,
const string &description, int flags) :
ConfigVariable(name, VT_bool, description, flags)
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, VT_bool, description, flags),
#else
ConfigVariable(name, VT_bool, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value);
_core->set_used();
@ -115,7 +126,12 @@ set_value(bool value) {
////////////////////////////////////////////////////////////////////
INLINE bool ConfigVariableBool::
get_value() const {
return get_bool_word(0);
TAU_PROFILE("bool ConfigVariableBool::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
mark_cache_valid(((ConfigVariableBool *)this)->_local_modified);
((ConfigVariableBool *)this)->_cache = get_bool_word(0);
}
return _cache;
}
////////////////////////////////////////////////////////////////////

View File

@ -47,6 +47,10 @@ PUBLISHED:
INLINE bool get_word(int n) const;
INLINE void set_word(int n, bool value);
private:
PN_int32 _local_modified;
bool _cache;
};
#include "configVariableBool.I"

View File

@ -163,20 +163,6 @@ has_local_value() const {
return _local_value != (ConfigDeclaration *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableCore::get_value_seq
// Access: Public
// Description: Returns a sequence number that changes every time the
// value of the variable might have changed. This is
// useful for caching values from the variable, and
// detecting when the cache has expired. It is
// initially zero and will increment from there.
////////////////////////////////////////////////////////////////////
INLINE int ConfigVariableCore::
get_value_seq() const {
return _value_seq;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableCore::get_num_references
// Access: Public

View File

@ -41,8 +41,7 @@ ConfigVariableCore(const string &name) :
_default_value(NULL),
_local_value(NULL),
_declarations_sorted(true),
_value_queried(false),
_value_seq(0)
_value_queried(false)
{
}
@ -63,8 +62,7 @@ ConfigVariableCore(const ConfigVariableCore &templ, const string &name) :
_default_value(NULL),
_local_value(NULL),
_declarations_sorted(false),
_value_queried(false),
_value_seq(0)
_value_queried(false)
{
if (templ._default_value != (ConfigDeclaration *)NULL) {
set_default_value(templ._default_value->get_string_value());
@ -244,11 +242,6 @@ make_local_value() {
}
}
// Assume that everytime someone asks for the local value, they're
// about to change it; further assume that no one changes the local
// value without calling this method immediately before.
_value_seq++;
return _local_value;
}
@ -267,7 +260,6 @@ clear_local_value() {
if (_local_value != (ConfigDeclaration *)NULL) {
ConfigPage::get_local_page()->delete_declaration(_local_value);
_local_value = (ConfigDeclaration *)NULL;
_value_seq++;
return true;
}
@ -403,10 +395,6 @@ add_declaration(ConfigDeclaration *decl) {
_declarations.push_back(decl);
_declarations_sorted = false;
if (!has_local_value()) {
_value_seq++;
}
}
////////////////////////////////////////////////////////////////////
@ -429,9 +417,6 @@ remove_declaration(ConfigDeclaration *decl) {
(*di) = (*di2);
_declarations.erase(di2);
_declarations_sorted = false;
if (!has_local_value()) {
_value_seq++;
}
return;
}
}

View File

@ -71,8 +71,6 @@ public:
int get_num_declarations() const;
const ConfigDeclaration *get_declaration(int n) const;
INLINE int get_value_seq() const;
INLINE int get_num_references() const;
INLINE const ConfigDeclaration *get_reference(int n) const;
@ -108,7 +106,6 @@ private:
Declarations _unique_declarations;
bool _declarations_sorted;
bool _value_queried;
int _value_seq;
friend class ConfigDeclaration;
friend class ConfigVariableManager;

View File

@ -24,7 +24,8 @@
////////////////////////////////////////////////////////////////////
INLINE ConfigVariableDouble::
ConfigVariableDouble(const string &name) :
ConfigVariable(name, VT_double)
ConfigVariable(name, VT_double),
_local_modified(initial_invalid_cache())
{
_core->set_used();
}
@ -38,10 +39,11 @@ INLINE ConfigVariableDouble::
ConfigVariableDouble(const string &name, double default_value,
const string &description, int flags) :
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, ConfigVariableCore::VT_double, description, flags)
ConfigVariable(name, ConfigVariableCore::VT_double, description, flags),
#else
ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags)
ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
set_default_value(default_value);
_core->set_used();
@ -56,10 +58,11 @@ INLINE ConfigVariableDouble::
ConfigVariableDouble(const string &name, const string &default_value,
const string &description, int flags) :
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, ConfigVariableCore::VT_double, description, flags)
ConfigVariable(name, ConfigVariableCore::VT_double, description, flags),
#else
ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags)
ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value);
_core->set_used();
@ -123,7 +126,12 @@ set_value(double value) {
////////////////////////////////////////////////////////////////////
INLINE double ConfigVariableDouble::
get_value() const {
return get_double_word(0);
TAU_PROFILE("double ConfigVariableDouble::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
mark_cache_valid(((ConfigVariableDouble *)this)->_local_modified);
((ConfigVariableDouble *)this)->_cache = get_double_word(0);
}
return _cache;
}
////////////////////////////////////////////////////////////////////

View File

@ -52,6 +52,10 @@ PUBLISHED:
private:
void set_default_value(double default_value);
private:
PN_int32 _local_modified;
double _cache;
};
#include "configVariableDouble.I"

View File

@ -31,10 +31,9 @@ ConfigVariableEnum(const string &name, EnumType default_value,
#else
ConfigVariable(name, ConfigVariableCore::VT_enum, string(), flags),
#endif
_value_seq(-1),
_value(default_value),
_got_default_value(true),
_default_value(default_value)
_default_value(default_value),
_local_modified(initial_invalid_cache())
{
_core->set_default_value(format_enum(default_value));
_core->set_used();
@ -54,10 +53,9 @@ ConfigVariableEnum(const string &name, const string &default_value,
#else
ConfigVariable(name, ConfigVariableCore::VT_enum, string(), flags),
#endif
_value_seq(-1),
_value(default_value),
_got_default_value(true),
_default_value(parse_string(default_value))
_default_value(parse_string(default_value)),
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value);
_core->set_used();
@ -136,11 +134,12 @@ set_value(EnumType value) {
template<class EnumType>
INLINE EnumType ConfigVariableEnum<EnumType>::
get_value() const {
if (_value_seq != _core->get_value_seq()) {
((ConfigVariableEnum<EnumType> *)this)->_value = (EnumType)parse_string(get_string_value());
((ConfigVariableEnum<EnumType> *)this)->_value_seq = _core->get_value_seq();
TAU_PROFILE("EnumType ConfigVariableEnum<EnumType>::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
mark_cache_valid(((ConfigVariableEnum<EnumType> *)this)->_local_modified);
((ConfigVariableEnum<EnumType> *)this)->_cache = (EnumType)parse_string(get_string_value());
}
return _value;
return _cache;
}
////////////////////////////////////////////////////////////////////

View File

@ -63,11 +63,12 @@ private:
INLINE EnumType parse_string(const string &value) const;
INLINE string format_enum(EnumType value) const;
int _value_seq;
EnumType _value;
private:
bool _got_default_value;
EnumType _default_value;
PN_int32 _local_modified;
EnumType _cache;
};
#include "configVariableEnum.I"

View File

@ -25,8 +25,7 @@
INLINE ConfigVariableFilename::
ConfigVariableFilename(const string &name) :
ConfigVariable(name, VT_filename),
_value_seq(-1),
_value_stale(true)
_local_modified(initial_invalid_cache())
{
_core->set_used();
}
@ -44,8 +43,7 @@ ConfigVariableFilename(const string &name, const Filename &default_value,
#else
ConfigVariable(name, VT_filename, string(), flags),
#endif
_value_seq(-1),
_value_stale(true)
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value);
_core->set_used();
@ -233,10 +231,11 @@ set_value(const Filename &value) {
////////////////////////////////////////////////////////////////////
INLINE const Filename &ConfigVariableFilename::
get_value() const {
if (_value_stale || _value_seq != _core->get_value_seq()) {
((ConfigVariableFilename *)this)->reload_value();
TAU_PROFILE("const Filename &ConfigVariableFilename::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
((ConfigVariableFilename *)this)->reload_cache();
}
return _value;
return _cache;
}
////////////////////////////////////////////////////////////////////

View File

@ -20,14 +20,15 @@
#include "executionEnvironment.h"
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableFilename::reload_value
// Function: ConfigVariableFilename::reload_cache
// Access: Private
// Description: Recopies the config variable into the Filename for
// returning its value.
////////////////////////////////////////////////////////////////////
void ConfigVariableFilename::
reload_value() {
reload_cache() {
nassertv(_core != (ConfigVariableCore *)NULL);
mark_cache_valid(_local_modified);
const ConfigDeclaration *decl = _core->get_declaration(0);
const ConfigPage *page = decl->get_page();
@ -36,9 +37,6 @@ reload_value() {
Filename page_dirname = page_filename.get_dirname();
ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
_value = Filename::expand_from(decl->get_string_value());
_cache = Filename::expand_from(decl->get_string_value());
ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
_value_seq = _core->get_value_seq();
_value_stale = false;
}

View File

@ -67,12 +67,11 @@ PUBLISHED:
INLINE void set_word(int n, const Filename &value);
private:
void reload_value();
void reload_cache();
int _value_seq;
bool _value_stale;
Filename _value;
private:
PN_int32 _local_modified;
Filename _cache;
};
#include "configVariableFilename.I"

View File

@ -24,7 +24,8 @@
////////////////////////////////////////////////////////////////////
INLINE ConfigVariableInt::
ConfigVariableInt(const string &name) :
ConfigVariable(name, VT_int)
ConfigVariable(name, VT_int),
_local_modified(initial_invalid_cache())
{
_core->set_used();
}
@ -38,10 +39,11 @@ INLINE ConfigVariableInt::
ConfigVariableInt(const string &name, int default_value,
const string &description, int flags) :
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, ConfigVariableCore::VT_int, description, flags)
ConfigVariable(name, ConfigVariableCore::VT_int, description, flags),
#else
ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags)
ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
set_default_value(default_value);
_core->set_used();
@ -56,10 +58,11 @@ INLINE ConfigVariableInt::
ConfigVariableInt(const string &name, const string &default_value,
const string &description, int flags) :
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, ConfigVariableCore::VT_int, description, flags)
ConfigVariable(name, ConfigVariableCore::VT_int, description, flags),
#else
ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags)
ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value);
_core->set_used();
@ -123,7 +126,12 @@ set_value(int value) {
////////////////////////////////////////////////////////////////////
INLINE int ConfigVariableInt::
get_value() const {
return get_int_word(0);
TAU_PROFILE("int ConfigVariableInt::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
mark_cache_valid(((ConfigVariableInt *)this)->_local_modified);
((ConfigVariableInt *)this)->_cache = get_int_word(0);
}
return _cache;
}
////////////////////////////////////////////////////////////////////

View File

@ -52,6 +52,10 @@ PUBLISHED:
private:
void set_default_value(int default_value);
private:
PN_int32 _local_modified;
int _cache;
};
#include "configVariableInt.I"

View File

@ -30,7 +30,8 @@ class ConfigVariableCore;
////////////////////////////////////////////////////////////////////
// Class : ConfigVariableManager
// Description : A global object that maintains the set of ConfigVariableCores
// Description : A global object that maintains the set of
// ConfigVariables (actually, ConfigVariableCores)
// everywhere in the world, and keeps them in sorted
// order.
////////////////////////////////////////////////////////////////////

View File

@ -30,8 +30,7 @@ ConfigVariableSearchPath(const string &name,
#else
ConfigVariableBase(name, VT_search_path, string(), flags),
#endif
_value_seq(-1),
_value_stale(true)
_local_modified(initial_invalid_cache())
{
// A SearchPath variable implicitly defines a default value of the empty
// string. This is just to prevent the core variable from
@ -61,6 +60,20 @@ operator const DSearchPath & () const {
return get_value();
}
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableSearchPath::get_value
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const DSearchPath &ConfigVariableSearchPath::
get_value() const {
TAU_PROFILE("const DSearchPath &ConfigVariableSearchPath::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
((ConfigVariableSearchPath *)this)->reload_search_path();
}
return _cache;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableSearchPath::clear_local_value
// Access: Published
@ -79,7 +92,7 @@ clear_local_value() {
any_to_clear = true;
}
_value_stale = true;
_local_modified = initial_invalid_cache();
return any_to_clear;
}
@ -102,7 +115,7 @@ clear() {
INLINE void ConfigVariableSearchPath::
append_directory(const Filename &directory) {
_postfix.append_directory(directory);
_value_stale = true;
_local_modified = initial_invalid_cache();
}
////////////////////////////////////////////////////////////////////
@ -113,7 +126,7 @@ append_directory(const Filename &directory) {
INLINE void ConfigVariableSearchPath::
prepend_directory(const Filename &directory) {
_prefix.prepend_directory(directory);
_value_stale = true;
_local_modified = initial_invalid_cache();
}
////////////////////////////////////////////////////////////////////
@ -125,7 +138,7 @@ prepend_directory(const Filename &directory) {
INLINE void ConfigVariableSearchPath::
append_path(const string &path, const string &separator) {
_postfix.append_path(path, separator);
_value_stale = true;
_local_modified = initial_invalid_cache();
}
////////////////////////////////////////////////////////////////////
@ -137,7 +150,7 @@ append_path(const string &path, const string &separator) {
INLINE void ConfigVariableSearchPath::
append_path(const DSearchPath &path) {
_postfix.append_path(path);
_value_stale = true;
_local_modified = initial_invalid_cache();
}
////////////////////////////////////////////////////////////////////
@ -149,7 +162,7 @@ append_path(const DSearchPath &path) {
INLINE void ConfigVariableSearchPath::
prepend_path(const DSearchPath &path) {
_prefix.prepend_path(path);
_value_stale = true;
_local_modified = initial_invalid_cache();
}
////////////////////////////////////////////////////////////////////

View File

@ -19,20 +19,6 @@
#include "configVariableSearchPath.h"
#include "executionEnvironment.h"
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableSearchPath::get_value
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
const DSearchPath &ConfigVariableSearchPath::
get_value() const {
nassertr(_core != (ConfigVariableCore *)NULL, _value);
if (_value_stale || _value_seq != _core->get_value_seq()) {
((ConfigVariableSearchPath *)this)->reload_search_path();
}
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: ConfigVariableSearchPath::reload_search_path
// Access: Private
@ -42,9 +28,10 @@ get_value() const {
void ConfigVariableSearchPath::
reload_search_path() {
nassertv(_core != (ConfigVariableCore *)NULL);
_value.clear();
mark_cache_valid(_local_modified);
_cache.clear();
_value.append_path(_prefix);
_cache.append_path(_prefix);
int num_unique_references = _core->get_num_unique_references();
for (int i = 0; i < num_unique_references; i++) {
const ConfigDeclaration *decl = _core->get_unique_reference(i);
@ -56,16 +43,13 @@ reload_search_path() {
string expanded = ExecutionEnvironment::expand_string(decl->get_string_value());
ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
if (!expanded.empty()) {
_value.append_directory(Filename::from_os_specific(expanded));
_cache.append_directory(Filename::from_os_specific(expanded));
}
}
_value.append_path(_postfix);
_cache.append_path(_postfix);
if (_value.is_empty()) {
if (_cache.is_empty()) {
// An empty search path implicitly has "." on it.
_value.append_directory(".");
_cache.append_directory(".");
}
_value_seq = _core->get_value_seq();
_value_stale = false;
}

View File

@ -51,7 +51,7 @@ PUBLISHED:
INLINE ~ConfigVariableSearchPath();
INLINE operator const DSearchPath & () const;
const DSearchPath &get_value() const;
INLINE const DSearchPath &get_value() const;
INLINE bool clear_local_value();
@ -77,11 +77,10 @@ PUBLISHED:
private:
void reload_search_path();
int _value_seq;
bool _value_stale;
DSearchPath _value;
DSearchPath _prefix, _postfix;
PN_int32 _local_modified;
DSearchPath _cache;
};
INLINE ostream &operator << (ostream &out, const ConfigVariableSearchPath &variable);

View File

@ -24,7 +24,8 @@
////////////////////////////////////////////////////////////////////
INLINE ConfigVariableString::
ConfigVariableString(const string &name) :
ConfigVariable(name, VT_string)
ConfigVariable(name, VT_string),
_local_modified(initial_invalid_cache())
{
_core->set_used();
}
@ -38,10 +39,11 @@ INLINE ConfigVariableString::
ConfigVariableString(const string &name, const string &default_value,
const string &description, int flags) :
#ifdef PRC_SAVE_DESCRIPTIONS
ConfigVariable(name, VT_string, description, flags)
ConfigVariable(name, VT_string, description, flags),
#else
ConfigVariable(name, VT_string, string(), flags)
ConfigVariable(name, VT_string, string(), flags),
#endif
_local_modified(initial_invalid_cache())
{
_core->set_default_value(default_value);
_core->set_used();
@ -155,7 +157,12 @@ set_value(const string &value) {
////////////////////////////////////////////////////////////////////
INLINE const string &ConfigVariableString::
get_value() const {
return get_string_value();
TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
mark_cache_valid(((ConfigVariableString *)this)->_local_modified);
((ConfigVariableString *)this)->_cache = get_string_value();
}
return _cache;
}
////////////////////////////////////////////////////////////////////

View File

@ -54,6 +54,10 @@ PUBLISHED:
INLINE string get_word(int n) const;
INLINE void set_word(int n, const string &value);
private:
PN_int32 _local_modified;
string _cache;
};
#include "configVariableString.I"

View File

@ -17,5 +17,11 @@
////////////////////////////////////////////////////////////////////
#include "config_prc.h"
#include "configVariableBool.h"
NotifyCategoryDef(prc, "");
ConfigVariableBool assert_abort
("assert-abort", false,
"Set this true to trigger a core dump and/or stack trace when the first assertion fails");

View File

@ -22,7 +22,11 @@
#include "dtoolbase.h"
#include "notifyCategoryProxy.h"
class ConfigVariableBool;
NotifyCategoryDecl(prc, EXPCL_DTOOLCONFIG, EXPTP_DTOOLCONFIG);
extern ConfigVariableBool assert_abort;
#endif

View File

@ -22,16 +22,12 @@
#include "configVariableFilename.h"
#include "configVariableBool.h"
#include "filename.h"
#include "config_prc.h"
#include <ctype.h>
Notify *Notify::_global_ptr = (Notify *)NULL;
static ConfigVariableBool assert_abort
("assert-abort", false,
"Set this true to trigger a core dump and/or stack trace when the first assertion fails");
////////////////////////////////////////////////////////////////////
// Function: Notify::Constructor
// Access: Public

View File

@ -37,6 +37,20 @@ get_basename() const {
return _basename;
}
////////////////////////////////////////////////////////////////////
// Function: NotifyCategory::get_severity
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
NotifySeverity NotifyCategory::
get_severity() const {
TAU_PROFILE("NotifyCategory NotifyCategory::get_severity() const", " ", TAU_USER);
if (!is_cache_valid(_local_modified)) {
((NotifyCategory *)this)->update_severity_cache();
}
return _severity_cache;
}
////////////////////////////////////////////////////////////////////
// Function: NotifyCategory::set_severity
// Access: Public
@ -47,6 +61,7 @@ get_basename() const {
INLINE void NotifyCategory::
set_severity(NotifySeverity severity) {
_severity = severity;
invalidate_cache();
}
////////////////////////////////////////////////////////////////////
@ -57,6 +72,7 @@ set_severity(NotifySeverity severity) {
////////////////////////////////////////////////////////////////////
INLINE bool NotifyCategory::
is_on(NotifySeverity severity) const {
TAU_PROFILE("bool NotifyCategory::is_on(NotifySeverity) const", " ", TAU_USER);
return (int)severity >= (int)get_severity();
}

View File

@ -21,6 +21,7 @@
#include "configPageManager.h"
#include "configVariableString.h"
#include "configVariableBool.h"
#include "config_prc.h"
#include <time.h> // for strftime().
#include <assert.h>
@ -40,7 +41,8 @@ NotifyCategory(const string &fullname, const string &basename,
_parent(parent),
_severity(get_config_name(), NS_unspecified,
"Default severity of this notify category",
ConfigVariable::F_dynamic)
ConfigVariable::F_dynamic),
_local_modified(initial_invalid_cache())
{
if (_parent != (NotifyCategory *)NULL) {
_parent->_children.push_back(this);
@ -50,31 +52,6 @@ NotifyCategory(const string &fullname, const string &basename,
nassertv(_parent != (NotifyCategory *)NULL || _fullname.empty());
}
////////////////////////////////////////////////////////////////////
// Function: NotifyCategory::get_severity
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
NotifySeverity NotifyCategory::
get_severity() const {
if (_severity == NS_unspecified) {
// If we don't have an explicit severity level, inherit our
// parent's.
if (_severity.has_value()) {
nout << "Invalid severity name for " << _severity.get_name() << ": "
<< _severity.get_string_value() << "\n";
}
if (_parent != (NotifyCategory *)NULL) {
return _parent->get_severity();
} else {
// Unless, of course, we're the root.
return NS_info;
}
}
return _severity;
}
////////////////////////////////////////////////////////////////////
// Function: NotifyCategory::out
// Access: Published
@ -184,6 +161,33 @@ get_config_name() const {
return config_name;
}
////////////////////////////////////////////////////////////////////
// Function: NotifyCategory::update_severity_cache
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NotifyCategory::
update_severity_cache() {
if (_severity == NS_unspecified) {
// If we don't have an explicit severity level, inherit our
// parent's.
if (_severity.has_value()) {
nout << "Invalid severity name for " << _severity.get_name() << ": "
<< _severity.get_string_value() << "\n";
}
if (_parent != (NotifyCategory *)NULL) {
_severity_cache = _parent->get_severity();
} else {
// Unless, of course, we're the root.
_severity_cache = NS_info;
}
} else {
_severity_cache = _severity;
}
mark_cache_valid(_local_modified);
}
////////////////////////////////////////////////////////////////////
// Function: NotifyCategory::get_notify_timestamp
// Access: Private, Static

View File

@ -23,6 +23,7 @@
#include "notifySeverity.h"
#include "configVariableEnum.h"
#include "configFlags.h"
#include "pvector.h"
////////////////////////////////////////////////////////////////////
@ -34,7 +35,7 @@
// created within a package if a finer grain of control
// is required.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG NotifyCategory {
class EXPCL_DTOOLCONFIG NotifyCategory : public ConfigFlags {
private:
NotifyCategory(const string &fullname, const string &basename,
NotifyCategory *parent);
@ -42,7 +43,7 @@ private:
PUBLISHED:
INLINE string get_fullname() const;
INLINE string get_basename() const;
NotifySeverity get_severity() const;
INLINE NotifySeverity get_severity() const;
INLINE void set_severity(NotifySeverity severity);
INLINE bool is_on(NotifySeverity severity) const;
@ -80,6 +81,7 @@ PUBLISHED:
private:
string get_config_name() const;
void update_severity_cache();
static bool get_notify_timestamp();
static bool get_check_debug_notify_protect();
@ -92,6 +94,9 @@ private:
static long _server_delta; // not a time_t because server delta may be signed.
PN_int32 _local_modified;
NotifySeverity _severity_cache;
friend class Notify;
};

View File

@ -85,8 +85,13 @@ public:
INLINE bool is_on(NotifySeverity severity);
#if defined(NOTIFY_DEBUG) || defined(CPPPARSER)
INLINE bool is_spam();
INLINE bool is_debug();
#else
INLINE static bool is_spam();
INLINE static bool is_debug();
#endif
INLINE bool is_info();
INLINE bool is_warning();
INLINE bool is_error();

View File

@ -19,7 +19,8 @@
#include "animChannelScalarDynamic.h"
#include "animBundle.h"
#include "config_chan.h"
#include "transformState.h"
#include "pandaNode.h"
#include "indent.h"
#include "datagram.h"
#include "datagramIterator.h"

View File

@ -23,6 +23,9 @@
#include "animChannel.h"
class PandaNode;
class TransformState;
////////////////////////////////////////////////////////////////////
// Class : AnimChannelScalarDynamic
// Description : An animation channel that accepts a scalar each frame

Some files were not shown because too many files have changed in this diff Show More