Browse Source

multithreading optimizations, tau profiler, related changes

David Rose 19 years ago
parent
commit
8a78fffd8f
100 changed files with 1478 additions and 657 deletions
  1. 3 3
      dtool/Config.FreeBSD.pp
  2. 2 3
      dtool/Config.Irix.pp
  3. 4 4
      dtool/Config.Linux.pp
  4. 3 3
      dtool/Config.osx.pp
  5. 21 7
      dtool/Config.pp
  6. 8 32
      dtool/LocalSetup.pp
  7. 18 1
      dtool/pptempl/Global.pp
  8. 17 10
      dtool/pptempl/Template.unix.pp
  9. 49 1
      dtool/src/dtoolbase/Sources.pp
  10. 20 8
      dtool/src/dtoolbase/atomicAdjust.h
  11. 44 7
      dtool/src/dtoolbase/atomicAdjustDummyImpl.I
  12. 0 0
      dtool/src/dtoolbase/atomicAdjustDummyImpl.cxx
  13. 15 5
      dtool/src/dtoolbase/atomicAdjustDummyImpl.h
  14. 129 0
      dtool/src/dtoolbase/atomicAdjustI386Impl.I
  15. 9 3
      dtool/src/dtoolbase/atomicAdjustI386Impl.cxx
  16. 59 0
      dtool/src/dtoolbase/atomicAdjustI386Impl.h
  17. 7 7
      dtool/src/dtoolbase/atomicAdjustNsprImpl.I
  18. 0 0
      dtool/src/dtoolbase/atomicAdjustNsprImpl.cxx
  19. 3 4
      dtool/src/dtoolbase/atomicAdjustNsprImpl.h
  20. 7 8
      dtool/src/dtoolbase/atomicAdjustPosixImpl.I
  21. 0 0
      dtool/src/dtoolbase/atomicAdjustPosixImpl.cxx
  22. 4 5
      dtool/src/dtoolbase/atomicAdjustPosixImpl.h
  23. 7 7
      dtool/src/dtoolbase/atomicAdjustWin32Impl.I
  24. 0 0
      dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx
  25. 3 4
      dtool/src/dtoolbase/atomicAdjustWin32Impl.h
  26. 0 42
      dtool/src/dtoolbase/dallocator.T
  27. 4 53
      dtool/src/dtoolbase/dallocator.h
  28. 100 0
      dtool/src/dtoolbase/deletedChain.T
  29. 99 0
      dtool/src/dtoolbase/deletedChain.h
  30. 102 0
      dtool/src/dtoolbase/dtoolbase.h
  31. 5 0
      dtool/src/dtoolbase/dtoolbase_composite1.cxx
  32. 6 0
      dtool/src/dtoolbase/dtoolbase_composite2.cxx
  33. 0 0
      dtool/src/dtoolbase/mutexDummyImpl.I
  34. 0 0
      dtool/src/dtoolbase/mutexDummyImpl.cxx
  35. 1 3
      dtool/src/dtoolbase/mutexDummyImpl.h
  36. 6 0
      dtool/src/dtoolbase/mutexImpl.h
  37. 38 0
      dtool/src/dtoolbase/mutexLinuxImpl.I
  38. 64 0
      dtool/src/dtoolbase/mutexLinuxImpl.cxx
  39. 32 17
      dtool/src/dtoolbase/mutexLinuxImpl.h
  40. 2 2
      dtool/src/dtoolbase/mutexNsprImpl.I
  41. 0 0
      dtool/src/dtoolbase/mutexNsprImpl.cxx
  42. 1 3
      dtool/src/dtoolbase/mutexNsprImpl.h
  43. 20 10
      dtool/src/dtoolbase/mutexPosixImpl.I
  44. 0 0
      dtool/src/dtoolbase/mutexPosixImpl.cxx
  45. 2 4
      dtool/src/dtoolbase/mutexPosixImpl.h
  46. 0 0
      dtool/src/dtoolbase/mutexWin32Impl.I
  47. 0 0
      dtool/src/dtoolbase/mutexWin32Impl.cxx
  48. 1 3
      dtool/src/dtoolbase/mutexWin32Impl.h
  49. 0 0
      dtool/src/dtoolbase/numeric_types.h
  50. 21 56
      dtool/src/dtoolbase/pallocator.T
  51. 32 62
      dtool/src/dtoolbase/pallocator.h
  52. 8 8
      dtool/src/dtoolbase/pdeque.h
  53. 12 12
      dtool/src/dtoolbase/plist.h
  54. 73 19
      dtool/src/dtoolbase/pmap.h
  55. 65 19
      dtool/src/dtoolbase/pset.h
  56. 18 9
      dtool/src/dtoolbase/pvector.h
  57. 4 0
      dtool/src/dtoolbase/select.tau
  58. 5 0
      dtool/src/dtoolbase/selectThreadImpl.h
  59. 1 0
      dtool/src/dtoolutil/pandaSystem.h
  60. 4 4
      dtool/src/dtoolutil/vector_src.h
  61. 31 47
      dtool/src/interrogatedb/Sources.pp
  62. 1 0
      dtool/src/interrogatedb/interrogate_interface.cxx
  63. 0 4
      dtool/src/interrogatedb/interrogatedb_composite2.cxx
  64. 1 0
      dtool/src/prc/configDeclaration.I
  65. 4 0
      dtool/src/prc/configDeclaration.cxx
  66. 2 1
      dtool/src/prc/configDeclaration.h
  67. 49 0
      dtool/src/prc/configFlags.I
  68. 2 0
      dtool/src/prc/configFlags.cxx
  69. 13 0
      dtool/src/prc/configFlags.h
  70. 3 0
      dtool/src/prc/configPageManager.cxx
  71. 2 1
      dtool/src/prc/configPageManager.h
  72. 20 4
      dtool/src/prc/configVariableBool.I
  73. 4 0
      dtool/src/prc/configVariableBool.h
  74. 0 14
      dtool/src/prc/configVariableCore.I
  75. 2 17
      dtool/src/prc/configVariableCore.cxx
  76. 0 3
      dtool/src/prc/configVariableCore.h
  77. 14 6
      dtool/src/prc/configVariableDouble.I
  78. 4 0
      dtool/src/prc/configVariableDouble.h
  79. 9 10
      dtool/src/prc/configVariableEnum.I
  80. 4 3
      dtool/src/prc/configVariableEnum.h
  81. 6 7
      dtool/src/prc/configVariableFilename.I
  82. 4 6
      dtool/src/prc/configVariableFilename.cxx
  83. 4 5
      dtool/src/prc/configVariableFilename.h
  84. 14 6
      dtool/src/prc/configVariableInt.I
  85. 4 0
      dtool/src/prc/configVariableInt.h
  86. 2 1
      dtool/src/prc/configVariableManager.h
  87. 21 8
      dtool/src/prc/configVariableSearchPath.I
  88. 7 23
      dtool/src/prc/configVariableSearchPath.cxx
  89. 4 5
      dtool/src/prc/configVariableSearchPath.h
  90. 11 4
      dtool/src/prc/configVariableString.I
  91. 4 0
      dtool/src/prc/configVariableString.h
  92. 6 0
      dtool/src/prc/config_prc.cxx
  93. 4 0
      dtool/src/prc/config_prc.h
  94. 1 5
      dtool/src/prc/notify.cxx
  95. 16 0
      dtool/src/prc/notifyCategory.I
  96. 30 26
      dtool/src/prc/notifyCategory.cxx
  97. 7 2
      dtool/src/prc/notifyCategory.h
  98. 5 0
      dtool/src/prc/notifyCategoryProxy.h
  99. 2 1
      panda/src/chan/animChannelScalarDynamic.cxx
  100. 3 0
      panda/src/chan/animChannelScalarDynamic.h

+ 3 - 3
dtool/Config.FreeBSD.pp

@@ -137,9 +137,9 @@
 // Must global operator new and delete functions throw exceptions?
 // Must global operator new and delete functions throw exceptions?
 #define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
 #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):
 // The dynamic library file extension (usually .so .dll or .dylib):
 #define DYNAMIC_LIB_EXT .so
 #define DYNAMIC_LIB_EXT .so

+ 2 - 3
dtool/Config.Irix.pp

@@ -130,9 +130,8 @@
 // Must global operator new and delete functions throw exceptions?
 // Must global operator new and delete functions throw exceptions?
 #define GLOBAL_OPERATOR_NEW_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):
 // The dynamic library file extension (usually .so .dll or .dylib):
 #define DYNAMIC_LIB_EXT .so
 #define DYNAMIC_LIB_EXT .so

+ 4 - 4
dtool/Config.Linux.pp

@@ -7,7 +7,7 @@
 //
 //
 
 
 // What additional flags should we pass to interrogate?
 // 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
 // Is the platform big-endian (like an SGI workstation) or
 // little-endian (like a PC)?  Define this to the empty string to
 // 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?
 // Must global operator new and delete functions throw exceptions?
 #define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
 #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):
 // The dynamic library file extension (usually .so .dll or .dylib):
 #define DYNAMIC_LIB_EXT .so
 #define DYNAMIC_LIB_EXT .so

+ 3 - 3
dtool/Config.osx.pp

@@ -173,9 +173,9 @@
 // Must global operator new and delete functions throw exceptions?
 // Must global operator new and delete functions throw exceptions?
 #define GLOBAL_OPERATOR_NEW_EXCEPTIONS 1
 #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):
 // The dynamic library file extension (usually .so .dll or .dylib):
 #define DYNAMIC_LIB_EXT .dylib
 #define DYNAMIC_LIB_EXT .dylib

+ 21 - 7
dtool/Config.pp

@@ -122,10 +122,9 @@
 // What level of compiler optimization/debug symbols should we build?
 // What level of compiler optimization/debug symbols should we build?
 // The various optimize levels are defined as follows:
 // 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
 //   4 - Full optimizations, no debug symbols, and asserts removed
 //
 //
 #define OPTIMIZE 3
 #define OPTIMIZE 3
@@ -571,6 +570,13 @@
 // (pthread_create(), etc.), define this true.
 // (pthread_create(), etc.), define this true.
 #define HAVE_POSIX_THREADS $[and $[isfile /usr/include/pthread.h],$[not $[WINDOWS_PLATFORM]]]
 #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)?
 // Do you want to build in support for threading (multiprocessing)?
 // Building in support for threading will enable Panda to take
 // Building in support for threading will enable Panda to take
 // advantage of multiple CPU's if you have them (and if the OS
 // 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?
 // Do you want to build the audio interface?
 #define HAVE_AUDIO 1
 #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
 // Info for the RAD game tools, Miles Sound System
 // note this may be overwritten in wintools Config.pp
 // note this may be overwritten in wintools Config.pp
 #define RAD_MSS_IPATH /usr/include/Miles6/include
 #define RAD_MSS_IPATH /usr/include/Miles6/include
@@ -837,7 +851,7 @@
 // relevant flags.
 // relevant flags.
 #defer CFLAGS_OPT1 $[CDEFINES_OPT1:%=-D%] -Wall -g
 #defer CFLAGS_OPT1 $[CDEFINES_OPT1:%=-D%] -Wall -g
 #defer CFLAGS_OPT2 $[CDEFINES_OPT2:%=-D%] -Wall -g $[OPTFLAGS]
 #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]
 #defer CFLAGS_OPT4 $[CDEFINES_OPT4:%=-D%] $[OPTFLAGS]
 
 
 // What additional flags should be passed to both compilers when
 // 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 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]]
   #defer BUNDLE_LIB_C++ $[cxx_ld] -undefined dynamic_lookup -bundle -o $[target] $[sources] $[lpath:%=-L%] $[libs:%=-l%] $[patsubst %,-framework %, $[frameworks]]
 #else
 #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++
   #define BUNDLE_LIB_C++
 #endif
 #endif
 
 

+ 8 - 32
dtool/LocalSetup.pp

@@ -459,6 +459,12 @@ $[cdefine HAVE_RTTI]
 /* Do we have Posix threads? */
 /* Do we have Posix threads? */
 $[cdefine 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? */
 /* Must global operator new and delete functions throw exceptions? */
 $[cdefine GLOBAL_OPERATOR_NEW_EXCEPTIONS]
 $[cdefine GLOBAL_OPERATOR_NEW_EXCEPTIONS]
 
 
@@ -490,38 +496,8 @@ $[cdefine USE_MEMORY_PTMALLOC2]
 $[cdefine USE_MEMORY_MALLOC]
 $[cdefine USE_MEMORY_MALLOC]
 $[cdefine USE_MEMORY_NOWRAPPERS]
 $[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]
 $[cdefine IS_OSX]

+ 18 - 1
dtool/pptempl/Global.pp

@@ -331,6 +331,23 @@
 // the target is not to be built.
 // the target is not to be built.
 #defer build_target $[BUILD_TARGET]
 #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
 // This takes advantage of the above two variables to get the actual
 // list of local libraries we are to link with, eliminating those that
 // list of local libraries we are to link with, eliminating those that
@@ -358,7 +375,7 @@
 
 
 #defer get_sources \
 #defer get_sources \
   $[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]
 #defer included_sources $[INCLUDED_SOURCES]
 
 

+ 17 - 10
dtool/pptempl/Template.unix.pp

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

+ 49 - 1
dtool/src/dtoolbase/Sources.pp

@@ -1,25 +1,73 @@
+#define SELECT_TAU select.tau
+
 #begin lib_target
 #begin lib_target
   #define TARGET dtoolbase
   #define TARGET dtoolbase
+
+  #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
   
   
   #define SOURCES \
   #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 \
     cmath.I cmath.h \
     dallocator.T dallocator.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 \
     fakestringstream.h \
     indent.I indent.h indent.cxx \
     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 \
     nearly_zero.h \
+    numeric_types.h \
+    selectThreadImpl.h \
     stl_compares.I stl_compares.h \
     stl_compares.I stl_compares.h \
     pallocator.T pallocator.h \
     pallocator.T pallocator.h \
     pdeque.h plist.h pmap.h pset.h pvector.h \
     pdeque.h plist.h pmap.h pset.h pvector.h \
     dlmalloc.c
     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 \
   #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 \
     cmath.I cmath.h \
     dallocator.T dallocator.h \
     dallocator.T dallocator.h \
+    deletedChain.h deletedChain.T \
     dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \
     dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \
     indent.I indent.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 \
     nearly_zero.h \
+    numeric_types.h \
+    selectThreadImpl.h \
     stl_compares.I stl_compares.h \
     stl_compares.I stl_compares.h \
     pallocator.T pallocator.h \
     pallocator.T pallocator.h \
     pdeque.h plist.h pmap.h pset.h pvector.h
     pdeque.h plist.h pmap.h pset.h pvector.h
+
 #end lib_target
 #end lib_target

+ 20 - 8
panda/src/express/atomicAdjustImpl.h → dtool/src/dtoolbase/atomicAdjust.h

@@ -1,4 +1,4 @@
-// Filename: atomicAdjustImpl.h
+// Filename: atomicAdjust.h
 // Created by:  drose (09Aug02)
 // 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"
 #include "selectThreadImpl.h"
 
 
 #if defined(THREAD_DUMMY_IMPL)
 #if defined(THREAD_DUMMY_IMPL)
 
 
 #include "atomicAdjustDummyImpl.h"
 #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)
 #elif defined(THREAD_WIN32_IMPL)
 
 
 #include "atomicAdjustWin32Impl.h"
 #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)
 #elif defined(THREAD_POSIX_IMPL)
 
 
 #include "atomicAdjustPosixImpl.h"
 #include "atomicAdjustPosixImpl.h"
-typedef AtomicAdjustPosixImpl AtomicAdjustImpl;
+typedef AtomicAdjustPosixImpl AtomicAdjust;
 
 
 #elif defined(THREAD_NSPR_IMPL)
 #elif defined(THREAD_NSPR_IMPL)
 
 
 #include "atomicAdjustNsprImpl.h"
 #include "atomicAdjustNsprImpl.h"
-typedef AtomicAdjustNsprImpl AtomicAdjustImpl;
+typedef AtomicAdjustNsprImpl AtomicAdjust;
 
 
 #endif
 #endif
 
 

+ 44 - 7
panda/src/express/atomicAdjustDummyImpl.I → dtool/src/dtoolbase/atomicAdjustDummyImpl.I

@@ -20,23 +20,23 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustDummyImpl::inc
 //     Function: AtomicAdjustDummyImpl::inc
 //       Access: Public, Static
 //       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) {
 inc(PN_int32 &var) {
-  return ++var;
+  ++var;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustDummyImpl::dec
 //     Function: AtomicAdjustDummyImpl::dec
 //       Access: Public, Static
 //       Access: Public, Static
 //  Description: Atomically decrements the indicated variable and
 //  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) {
 dec(PN_int32 &var) {
-  return --var;
+  return (--var) != 0;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -65,3 +65,40 @@ INLINE PN_int32 AtomicAdjustDummyImpl::
 get(const PN_int32 &var) {
 get(const PN_int32 &var) {
   return 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;
+}

+ 0 - 0
panda/src/express/atomicAdjustDummyImpl.cxx → dtool/src/dtoolbase/atomicAdjustDummyImpl.cxx


+ 15 - 5
panda/src/express/atomicAdjustDummyImpl.h → dtool/src/dtoolbase/atomicAdjustDummyImpl.h

@@ -19,26 +19,36 @@
 #ifndef ATOMICADJUSTDUMMYIMPL_H
 #ifndef ATOMICADJUSTDUMMYIMPL_H
 #define ATOMICADJUSTDUMMYIMPL_H
 #define ATOMICADJUSTDUMMYIMPL_H
 
 
-#include "pandabase.h"
+#include "dtoolbase.h"
 #include "selectThreadImpl.h"
 #include "selectThreadImpl.h"
 
 
 #ifdef THREAD_DUMMY_IMPL
 #ifdef THREAD_DUMMY_IMPL
 
 
-#include "pnotify.h"
 #include "numeric_types.h"
 #include "numeric_types.h"
 
 
+#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
+#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : AtomicAdjustDummyImpl
 //       Class : AtomicAdjustDummyImpl
 // Description : A trivial implementation for atomic adjustments for
 // Description : A trivial implementation for atomic adjustments for
 //               systems that don't require multiprogramming, and
 //               systems that don't require multiprogramming, and
 //               therefore don't require special atomic operations.
 //               therefore don't require special atomic operations.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDAEXPRESS AtomicAdjustDummyImpl {
+class EXPCL_DTOOL AtomicAdjustDummyImpl {
 public:
 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 set(PN_int32 &var, PN_int32 new_value);
   INLINE static PN_int32 get(const PN_int32 &var);
   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"
 #include "atomicAdjustDummyImpl.I"

+ 129 - 0
dtool/src/dtoolbase/atomicAdjustI386Impl.I

@@ -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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     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;
+}

+ 9 - 3
panda/src/express/atomicAdjust.cxx → dtool/src/dtoolbase/atomicAdjustI386Impl.cxx

@@ -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__

+ 59 - 0
dtool/src/dtoolbase/atomicAdjustI386Impl.h

@@ -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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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

+ 7 - 7
panda/src/express/atomicAdjustNsprImpl.I → dtool/src/dtoolbase/atomicAdjustNsprImpl.I

@@ -20,23 +20,23 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustNsprImpl::inc
 //     Function: AtomicAdjustNsprImpl::inc
 //       Access: Public, Static
 //       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) {
 inc(PN_int32 &var) {
-  return PR_AtomicIncrement(&var);
+  PR_AtomicIncrement(&var);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustNsprImpl::dec
 //     Function: AtomicAdjustNsprImpl::dec
 //       Access: Public, Static
 //       Access: Public, Static
 //  Description: Atomically decrements the indicated variable and
 //  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) {
 dec(PN_int32 &var) {
-  return PR_AtomicDecrement(&var);
+  return (PR_AtomicDecrement(&var) != 0);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 0 - 0
panda/src/express/atomicAdjustNsprImpl.cxx → dtool/src/dtoolbase/atomicAdjustNsprImpl.cxx


+ 3 - 4
panda/src/express/atomicAdjustNsprImpl.h → dtool/src/dtoolbase/atomicAdjustNsprImpl.h

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

+ 7 - 8
panda/src/express/atomicAdjustPosixImpl.I → dtool/src/dtoolbase/atomicAdjustPosixImpl.I

@@ -20,29 +20,28 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustPosixImpl::inc
 //     Function: AtomicAdjustPosixImpl::inc
 //       Access: Public, Static
 //       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) {
 inc(PN_int32 &var) {
   pthread_mutex_lock(&_mutex);
   pthread_mutex_lock(&_mutex);
-  PN_int32 result = ++var;
+  ++var;
   pthread_mutex_unlock(&_mutex);
   pthread_mutex_unlock(&_mutex);
-  return result;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustPosixImpl::dec
 //     Function: AtomicAdjustPosixImpl::dec
 //       Access: Public, Static
 //       Access: Public, Static
 //  Description: Atomically decrements the indicated variable and
 //  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) {
 dec(PN_int32 &var) {
   pthread_mutex_lock(&_mutex);
   pthread_mutex_lock(&_mutex);
   PN_int32 result = --var;
   PN_int32 result = --var;
   pthread_mutex_unlock(&_mutex);
   pthread_mutex_unlock(&_mutex);
-  return result;
+  return (result != 0);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 0 - 0
panda/src/express/atomicAdjustPosixImpl.cxx → dtool/src/dtoolbase/atomicAdjustPosixImpl.cxx


+ 4 - 5
panda/src/express/atomicAdjustPosixImpl.h → dtool/src/dtoolbase/atomicAdjustPosixImpl.h

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

+ 7 - 7
panda/src/express/atomicAdjustWin32Impl.I → dtool/src/dtoolbase/atomicAdjustWin32Impl.I

@@ -20,23 +20,23 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustWin32Impl::inc
 //     Function: AtomicAdjustWin32Impl::inc
 //       Access: Public, Static
 //       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) {
 inc(PN_int32 &var) {
-  return InterlockedIncrement((LONG *)&var);
+  InterlockedIncrement((LONG *)&var);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AtomicAdjustWin32Impl::dec
 //     Function: AtomicAdjustWin32Impl::dec
 //       Access: Public, Static
 //       Access: Public, Static
 //  Description: Atomically decrements the indicated variable and
 //  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) {
 dec(PN_int32 &var) {
-  return InterlockedDecrement((LONG *)&var);
+  return (InterlockedDecrement((LONG *)&var) != 0);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 0 - 0
panda/src/express/atomicAdjustWin32Impl.cxx → dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx


+ 3 - 4
panda/src/express/atomicAdjustWin32Impl.h → dtool/src/dtoolbase/atomicAdjustWin32Impl.h

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

+ 0 - 42
dtool/src/dtoolbase/dallocator.T

@@ -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>
 template<class Type>
 INLINE dallocator<Type>::
 INLINE dallocator<Type>::
@@ -73,5 +33,3 @@ INLINE void dallocator<Type>::
 deallocate(TYPENAME dallocator<Type>::pointer p, TYPENAME dallocator<Type>::size_type) {
 deallocate(TYPENAME dallocator<Type>::pointer p, TYPENAME dallocator<Type>::size_type) {
   (*global_operator_delete)(p);
   (*global_operator_delete)(p);
 }
 }
-
-#endif  // *_STYLE_ALLOCATOR

+ 4 - 53
dtool/src/dtoolbase/dallocator.h

@@ -35,46 +35,14 @@
 //               within the MemoryUsage class itself.
 //               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
 // 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
 // what kind of syntax this STL library wants, or we're compiling with
 // OPTIMIZE 4), then simply use the standard allocator.
 // OPTIMIZE 4), then simply use the standard allocator.
 #define dallocator 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.
-
-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)
+#else
 
 
-// The final specification?
 template<class Type>
 template<class Type>
 class dallocator : public allocator<Type> {
 class dallocator : public allocator<Type> {
 public:
 public:
@@ -95,31 +63,14 @@ public:
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
   INLINE void deallocate(pointer p, size_type n);
   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 { 
   template<class U> struct rebind { 
     typedef dallocator<U> other; 
     typedef dallocator<U> other; 
   };
   };
 };
 };
 
 
-#else
-#error Unrecognized allocator symbol defined!
-#endif  // *_STYLE_ALLOCATOR
-
-#ifndef NO_STYLE_ALLOCATOR
 #include "dallocator.T"
 #include "dallocator.T"
-#endif
+
+#endif  // USE_STL_ALLOCATOR
 
 
 #endif
 #endif
 
 

+ 100 - 0
dtool/src/dtoolbase/deletedChain.T

@@ -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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+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
+}

+ 99 - 0
dtool/src/dtoolbase/deletedChain.h

@@ -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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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
+

+ 102 - 0
dtool/src/dtoolbase/dtoolbase.h

@@ -138,6 +138,108 @@
 #include <stdtypedefs.h>
 #include <stdtypedefs.h>
 #endif
 #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
  We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket
  functions and global variable definitions that are to be published
  functions and global variable definitions that are to be published

+ 5 - 0
dtool/src/dtoolbase/dtoolbase_composite1.cxx

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

+ 6 - 0
dtool/src/dtoolbase/dtoolbase_composite2.cxx

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

+ 0 - 0
dtool/src/interrogatedb/mutexDummyImpl.I → dtool/src/dtoolbase/mutexDummyImpl.I


+ 0 - 0
dtool/src/interrogatedb/mutexDummyImpl.cxx → dtool/src/dtoolbase/mutexDummyImpl.cxx


+ 1 - 3
dtool/src/interrogatedb/mutexDummyImpl.h → dtool/src/dtoolbase/mutexDummyImpl.h

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

+ 6 - 0
dtool/src/interrogatedb/mutexImpl.h → dtool/src/dtoolbase/mutexImpl.h

@@ -36,6 +36,12 @@ typedef MutexWin32Impl MutexImpl;
 typedef MutexWin32Impl ReMutexImpl;  // Win32 Mutexes are always reentrant.
 typedef MutexWin32Impl ReMutexImpl;  // Win32 Mutexes are always reentrant.
 #define HAVE_REMUTEXIMPL 1
 #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)
 #elif defined(THREAD_POSIX_IMPL)
 
 
 #include "mutexPosixImpl.h"
 #include "mutexPosixImpl.h"

+ 38 - 0
dtool/src/dtoolbase/mutexLinuxImpl.I

@@ -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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     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);
+}

+ 64 - 0
dtool/src/dtoolbase/mutexLinuxImpl.cxx

@@ -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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#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

+ 32 - 17
panda/src/express/atomicAdjust.h → dtool/src/dtoolbase/mutexLinuxImpl.h

@@ -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"
 #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:
 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
 #endif

+ 2 - 2
dtool/src/interrogatedb/mutexNsprImpl.I → dtool/src/dtoolbase/mutexNsprImpl.I

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

+ 0 - 0
dtool/src/interrogatedb/mutexNsprImpl.cxx → dtool/src/dtoolbase/mutexNsprImpl.cxx


+ 1 - 3
dtool/src/interrogatedb/mutexNsprImpl.h → dtool/src/dtoolbase/mutexNsprImpl.h

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

+ 20 - 10
dtool/src/interrogatedb/mutexPosixImpl.I → dtool/src/dtoolbase/mutexPosixImpl.I

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

+ 0 - 0
dtool/src/interrogatedb/mutexPosixImpl.cxx → dtool/src/dtoolbase/mutexPosixImpl.cxx


+ 2 - 4
dtool/src/interrogatedb/mutexPosixImpl.h → dtool/src/dtoolbase/mutexPosixImpl.h

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

+ 0 - 0
dtool/src/interrogatedb/mutexWin32Impl.I → dtool/src/dtoolbase/mutexWin32Impl.I


+ 0 - 0
dtool/src/interrogatedb/mutexWin32Impl.cxx → dtool/src/dtoolbase/mutexWin32Impl.cxx


+ 1 - 3
dtool/src/interrogatedb/mutexWin32Impl.h → dtool/src/dtoolbase/mutexWin32Impl.h

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

+ 0 - 0
panda/src/express/numeric_types.h → dtool/src/dtoolbase/numeric_types.h


+ 21 - 56
dtool/src/dtoolbase/pallocator.T

@@ -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);
-}
-
-template<class Type>
-INLINE void pallocator<Type>::
-deallocate(void *p, size_t) {
-  (*global_operator_delete)(p);
-}
-
-#elif defined(GNU_STYLE_ALLOCATOR)
-
 template<class Type>
 template<class Type>
-INLINE pallocator<Type>::
-pallocator() {
+INLINE pallocator_single<Type>::
+pallocator_single() throw() {
 }
 }
 
 
 template<class Type>
 template<class Type>
-template<class _Tp1>
-INLINE pallocator<Type>::
-pallocator(const pallocator<_Tp1> &) {
+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>
 template<class Type>
-INLINE Type *pallocator<Type>::
-allocate(size_t n) {
-  return (Type *)(*global_operator_new)(n * sizeof(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>
 template<class Type>
-INLINE void pallocator<Type>::
-deallocate(void *p, size_t) {
-  (*global_operator_delete)(p);
+INLINE pallocator_array<Type>::
+pallocator_array() throw() {
 }
 }
 
 
-#elif VC6_STYLE_ALLOCATOR
-
 template<class Type>
 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));
+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>
 template<class Type>
-INLINE void pallocator<Type>::
-//deallocate(pallocator<Type>::pointer p, allocator<Type>::size_type) {
-deallocate(void *p, allocator<Type>::size_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);
   (*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

+ 32 - 62
dtool/src/dtoolbase/pallocator.h

@@ -21,7 +21,7 @@
 
 
 #include <memory>
 #include <memory>
 #include "dtoolbase.h"
 #include "dtoolbase.h"
-
+#include "deletedChain.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : pallocator
 //       Class : pallocator
@@ -32,60 +32,49 @@
 //
 //
 //               pvector, pmap, etc. are all defined in this directory
 //               pvector, pmap, etc. are all defined in this directory
 //               to use a pallocator.
 //               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
 // 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
 // what kind of syntax this STL library wants, or we're compiling with
 // OPTIMIZE 4), then simply use the standard allocator.
 // 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>
 template<class Type>
-class pallocator : public alloc {
+class pallocator_single : public allocator<Type> {
 public:
 public:
-  INLINE static Type *allocate(size_t n);
-  INLINE static void deallocate(void *p, size_t n);
-};
+  // 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;
 
 
-#elif defined(GNU_STYLE_ALLOCATOR)
-// Later versions of gcc want to use a still different,
-// not-quite-standard definition.  Sheesh.
+  INLINE pallocator_single() throw();
 
 
-template<class Type>
-class pallocator : public allocator<Type> {
-public:
-  INLINE pallocator();
-  template<class _Tp1>
-  INLINE pallocator(const pallocator<_Tp1> &other);
+  // template member functions in VC++ can only be defined in-class.
+  template<class U>
+  INLINE pallocator_single(const pallocator_single<U> &) throw() { }
 
 
-  INLINE Type *allocate(size_t n);
-  INLINE void deallocate(void *p, size_t n);
+  INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
+  INLINE void deallocate(pointer p, size_type n);
 
 
-  template <class _Tp1> struct rebind {
-    typedef pallocator<_Tp1> other;
+  template<class U> struct rebind { 
+    typedef pallocator_single<U> other;
   };
   };
 };
 };
 
 
-#elif defined(VC6_STYLE_ALLOCATOR)
-
-// The VC6-era definition.
 template<class Type>
 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_array : public allocator<Type> {
 public:
 public:
   // Nowadays we cannot implicitly inherit typedefs from base classes
   // Nowadays we cannot implicitly inherit typedefs from base classes
   // in a template class; we must explicitly copy them here.
   // in a template class; we must explicitly copy them here.
@@ -95,42 +84,23 @@ public:
   typedef TYPENAME allocator<Type>::const_reference const_reference;
   typedef TYPENAME allocator<Type>::const_reference const_reference;
   typedef TYPENAME allocator<Type>::size_type size_type;
   typedef TYPENAME allocator<Type>::size_type size_type;
 
 
-  INLINE pallocator() throw();
+  INLINE pallocator_array() throw();
 
 
   // template member functions in VC++ can only be defined in-class.
   // template member functions in VC++ can only be defined in-class.
   template<class U>
   template<class U>
-  INLINE pallocator(const pallocator<U> &) throw() { }
+  INLINE pallocator_array(const pallocator_array<U> &) throw() { }
 
 
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
   INLINE void deallocate(pointer p, size_type n);
   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 { 
   template<class U> struct rebind { 
-    typedef pallocator<U> other;
+    typedef pallocator_array<U> other;
   };
   };
 };
 };
 
 
-#else
-#error Unrecognized allocator symbol defined!
-#endif  // *_STYLE_ALLOCATOR
-
-#ifndef NO_STYLE_ALLOCATOR
 #include "pallocator.T"
 #include "pallocator.T"
-#endif
+
+#endif  // USE_STL_ALLOCATOR
 
 
 #endif
 #endif
 
 

+ 8 - 8
dtool/src/dtoolbase/pdeque.h

@@ -23,7 +23,7 @@
 #include "pallocator.h"
 #include "pallocator.h"
 #include <deque>
 #include <deque>
 
 
-#ifdef NO_STYLE_ALLOCATOR
+#ifndef USE_STL_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define pdeque deque 
 #define pdeque deque 
@@ -38,14 +38,14 @@
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Type>
 template<class Type>
-class pdeque : public deque<Type, pallocator<Type> > {
+class pdeque : public deque<Type, pallocator_array<Type> > {
 public:
 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
 #endif

+ 12 - 12
dtool/src/dtoolbase/plist.h

@@ -23,7 +23,7 @@
 #include "pallocator.h"
 #include "pallocator.h"
 #include <list>
 #include <list>
 
 
-#ifdef NO_STYLE_ALLOCATOR
+#ifndef USE_STL_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define plist list
 #define plist list
@@ -38,19 +38,19 @@
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Type>
 template<class Type>
-class plist : public list<Type, pallocator<Type> > {
+class plist : public list<Type, pallocator_single<Type> > {
 public:
 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
 #endif

+ 73 - 19
dtool/src/dtoolbase/pmap.h

@@ -28,7 +28,7 @@
 #include <hash_map>
 #include <hash_map>
 #endif
 #endif
 
 
-#ifdef NO_STYLE_ALLOCATOR
+#ifndef USE_STL_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define pmap map
 #define pmap map
@@ -42,7 +42,7 @@
 #define phash_multimap multimap
 #define phash_multimap multimap
 #endif  // HAVE_STL_HASH
 #endif  // HAVE_STL_HASH
 
 
-#else  // NO_STYLE_ALLOCATOR
+#else  // USE_STL_ALLOCATOR
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : pmap
 //       Class : pmap
@@ -52,11 +52,65 @@
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Value, class Compare = less<Key> >
 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:
 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.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Value, class Compare = less<Key> >
 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:
 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
 #ifdef HAVE_STL_HASH
@@ -83,11 +137,11 @@ public:
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Value, class Compare = method_hash<Key, less<Key> > >
 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:
 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.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Value, class Compare = method_hash<Key, less<Key> > >
 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:
 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
 #else // HAVE_STL_HASH
@@ -110,5 +164,5 @@ public:
 #define phash_multimap pmultimap
 #define phash_multimap pmultimap
 #endif  // HAVE_STL_HASH
 #endif  // HAVE_STL_HASH
 
 
-#endif  // NO_STYLE_ALLOCATOR
+#endif  // USE_STL_ALLOCATOR
 #endif
 #endif

+ 65 - 19
dtool/src/dtoolbase/pset.h

@@ -28,7 +28,7 @@
 #include <hash_set>
 #include <hash_set>
 #endif
 #endif
 
 
-#ifdef NO_STYLE_ALLOCATOR
+#ifndef USE_STL_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define pset set
 #define pset set
@@ -42,7 +42,7 @@
 #define phash_multiset multiset
 #define phash_multiset multiset
 #endif  // HAVE_STL_HASH
 #endif  // HAVE_STL_HASH
 
 
-#else  // NO_STYLE_ALLOCATOR
+#else  // USE_STL_ALLOCATOR
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : pset
 //       Class : pset
@@ -52,11 +52,57 @@
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare = less<Key> >
 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:
 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.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare = less<Key> >
 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:
 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
 #ifdef HAVE_STL_HASH
@@ -83,11 +129,11 @@ public:
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare = method_hash<Key, less<Key> > >
 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:
 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.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare = method_hash<Key, less<Key> > >
 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:
 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
 #else // HAVE_STL_HASH
@@ -110,5 +156,5 @@ public:
 #define phash_multiset pmultiset
 #define phash_multiset pmultiset
 #endif  // HAVE_STL_HASH
 #endif  // HAVE_STL_HASH
 
 
-#endif  // NO_STYLE_ALLOCATOR
+#endif  // USE_STL_ALLOCATOR
 #endif
 #endif

+ 18 - 9
dtool/src/dtoolbase/pvector.h

@@ -24,7 +24,7 @@
 #include "dtoolbase.h"
 #include "dtoolbase.h"
 #include "pallocator.h"
 #include "pallocator.h"
 
 
-#ifdef NO_STYLE_ALLOCATOR
+#ifndef USE_STL_ALLOCATOR
 // If we're not using custom allocators, just use the standard class
 // If we're not using custom allocators, just use the standard class
 // definition.
 // definition.
 #define pvector vector
 #define pvector vector
@@ -39,17 +39,26 @@
 //               memory.
 //               memory.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Type>
 template<class Type>
-class pvector : public vector<Type, pallocator<Type> > {
+class pvector : public vector<Type, pallocator_array<Type> > {
 public:
 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
 #endif
 
 

+ 4 - 0
dtool/src/dtoolbase/select.tau

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

+ 5 - 0
dtool/src/interrogatedb/selectThreadImpl.h → dtool/src/dtoolbase/selectThreadImpl.h

@@ -43,6 +43,11 @@
 // In Windows, use the native threading library.
 // In Windows, use the native threading library.
 #define THREAD_WIN32_IMPL 1
 #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)
 #elif defined(HAVE_POSIX_THREADS)
 
 
 // Posix threads are nice.
 // Posix threads are nice.

+ 1 - 0
dtool/src/dtoolutil/pandaSystem.h

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

+ 4 - 4
dtool/src/dtoolutil/vector_src.h

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

+ 31 - 47
dtool/src/interrogatedb/Sources.pp

@@ -3,63 +3,47 @@
 #begin lib_target
 #begin lib_target
   #define TARGET interrogatedb
   #define TARGET interrogatedb
   
   
-  #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx     
+  #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
   
   
   #define SOURCES \
   #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  \
  #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 \
   #define INSTALL_HEADERS \
     interrogate_interface.h interrogate_request.h vector_int.h \
     interrogate_interface.h interrogate_request.h vector_int.h \
     config_interrogatedb.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 \
     py_panda.h \
     register_type.I register_type.h \
     register_type.I register_type.h \
-    selectThreadImpl.h \
     typedObject.I typedObject.h \
     typedObject.I typedObject.h \
     typeHandle.I typeHandle.h \
     typeHandle.I typeHandle.h \
     typeRegistry.I typeRegistry.h \
     typeRegistry.I typeRegistry.h \

+ 1 - 0
dtool/src/interrogatedb/interrogate_interface.cxx

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

+ 0 - 4
dtool/src/interrogatedb/interrogatedb_composite2.cxx

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

+ 1 - 0
dtool/src/prc/configDeclaration.I

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

+ 4 - 0
dtool/src/prc/configDeclaration.cxx

@@ -84,6 +84,7 @@ set_string_word(int n, const string &value) {
     _string_value += (*wi)._str;
     _string_value += (*wi)._str;
     ++wi;
     ++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]._flags |= (F_checked_bool | F_valid_bool);
   _words[n]._bool = value;
   _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]._flags |= (F_checked_int | F_valid_int);
   _words[n]._int = value;
   _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]._flags |= (F_checked_double | F_valid_double);
   _words[n]._double = value;
   _words[n]._double = value;
+  invalidate_cache();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 1
dtool/src/prc/configDeclaration.h

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

+ 49 - 0
dtool/src/prc/configFlags.I

@@ -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);
+}

+ 2 - 0
dtool/src/prc/configFlags.cxx

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

+ 13 - 0
dtool/src/prc/configFlags.h

@@ -20,6 +20,8 @@
 #define CONFIGFLAGS_H
 #define CONFIGFLAGS_H
 
 
 #include "dtoolbase.h"
 #include "dtoolbase.h"
+#include "numeric_types.h"
+#include "atomicAdjust.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : ConfigFlags
 //       Class : ConfigFlags
@@ -60,9 +62,20 @@ PUBLISHED:
     // shouldn't pass this in directly.
     // shouldn't pass this in directly.
     F_dconfig           = 0x00008000,
     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);
 ostream &operator << (ostream &out, ConfigFlags::ValueType type);
 
 
+#include "configFlags.I"
+
 #endif
 #endif
 
 

+ 3 - 0
dtool/src/prc/configPageManager.cxx

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

+ 2 - 1
dtool/src/prc/configPageManager.h

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

+ 20 - 4
dtool/src/prc/configVariableBool.I

@@ -24,7 +24,8 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ConfigVariableBool::
 INLINE ConfigVariableBool::
 ConfigVariableBool(const string &name) :
 ConfigVariableBool(const string &name) :
-  ConfigVariable(name, VT_bool)
+  ConfigVariable(name, VT_bool),
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_used();
   _core->set_used();
 }
 }
@@ -37,7 +38,12 @@ ConfigVariableBool(const string &name) :
 INLINE ConfigVariableBool::
 INLINE ConfigVariableBool::
 ConfigVariableBool(const string &name, bool default_value, 
 ConfigVariableBool(const string &name, bool default_value, 
                    const string &description, int flags) :
                    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_default_value(default_value ? "1" : "0");
   _core->set_used();
   _core->set_used();
@@ -51,7 +57,12 @@ ConfigVariableBool(const string &name, bool default_value,
 INLINE ConfigVariableBool::
 INLINE ConfigVariableBool::
 ConfigVariableBool(const string &name, const string &default_value, 
 ConfigVariableBool(const string &name, const string &default_value, 
                    const string &description, int flags) :
                    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_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -115,7 +126,12 @@ set_value(bool value) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool ConfigVariableBool::
 INLINE bool ConfigVariableBool::
 get_value() const {
 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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 0
dtool/src/prc/configVariableBool.h

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

+ 0 - 14
dtool/src/prc/configVariableCore.I

@@ -163,20 +163,6 @@ has_local_value() const {
   return _local_value != (ConfigDeclaration *)NULL;
   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
 //     Function: ConfigVariableCore::get_num_references
 //       Access: Public
 //       Access: Public

+ 2 - 17
dtool/src/prc/configVariableCore.cxx

@@ -41,8 +41,7 @@ ConfigVariableCore(const string &name) :
   _default_value(NULL),
   _default_value(NULL),
   _local_value(NULL),
   _local_value(NULL),
   _declarations_sorted(true),
   _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),
   _default_value(NULL),
   _local_value(NULL),
   _local_value(NULL),
   _declarations_sorted(false),
   _declarations_sorted(false),
-  _value_queried(false),
-  _value_seq(0)
+  _value_queried(false)
 {
 {
   if (templ._default_value != (ConfigDeclaration *)NULL) {
   if (templ._default_value != (ConfigDeclaration *)NULL) {
     set_default_value(templ._default_value->get_string_value());
     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;
   return _local_value;
 }
 }
 
 
@@ -267,7 +260,6 @@ clear_local_value() {
   if (_local_value != (ConfigDeclaration *)NULL) {
   if (_local_value != (ConfigDeclaration *)NULL) {
     ConfigPage::get_local_page()->delete_declaration(_local_value);
     ConfigPage::get_local_page()->delete_declaration(_local_value);
     _local_value = (ConfigDeclaration *)NULL;
     _local_value = (ConfigDeclaration *)NULL;
-    _value_seq++;
     return true;
     return true;
   }
   }
 
 
@@ -403,10 +395,6 @@ add_declaration(ConfigDeclaration *decl) {
   _declarations.push_back(decl);
   _declarations.push_back(decl);
 
 
   _declarations_sorted = false;
   _declarations_sorted = false;
-
-  if (!has_local_value()) {
-    _value_seq++;
-  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -429,9 +417,6 @@ remove_declaration(ConfigDeclaration *decl) {
       (*di) = (*di2);
       (*di) = (*di2);
       _declarations.erase(di2);
       _declarations.erase(di2);
       _declarations_sorted = false;
       _declarations_sorted = false;
-      if (!has_local_value()) {
-        _value_seq++;
-      }
       return;
       return;
     }
     }
   }
   }

+ 0 - 3
dtool/src/prc/configVariableCore.h

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

+ 14 - 6
dtool/src/prc/configVariableDouble.I

@@ -24,7 +24,8 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ConfigVariableDouble::
 INLINE ConfigVariableDouble::
 ConfigVariableDouble(const string &name) :
 ConfigVariableDouble(const string &name) :
-  ConfigVariable(name, VT_double)
+  ConfigVariable(name, VT_double),
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_used();
   _core->set_used();
 }
 }
@@ -38,10 +39,11 @@ INLINE ConfigVariableDouble::
 ConfigVariableDouble(const string &name, double default_value, 
 ConfigVariableDouble(const string &name, double default_value, 
                      const string &description, int flags) :
                      const string &description, int flags) :
 #ifdef PRC_SAVE_DESCRIPTIONS
 #ifdef PRC_SAVE_DESCRIPTIONS
-  ConfigVariable(name, ConfigVariableCore::VT_double, description, flags)
+  ConfigVariable(name, ConfigVariableCore::VT_double, description, flags),
 #else
 #else
-  ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags)
+  ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags),
 #endif
 #endif
+  _local_modified(initial_invalid_cache())
 {
 {
   set_default_value(default_value);
   set_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -56,10 +58,11 @@ INLINE ConfigVariableDouble::
 ConfigVariableDouble(const string &name, const string &default_value, 
 ConfigVariableDouble(const string &name, const string &default_value, 
                      const string &description, int flags) :
                      const string &description, int flags) :
 #ifdef PRC_SAVE_DESCRIPTIONS
 #ifdef PRC_SAVE_DESCRIPTIONS
-  ConfigVariable(name, ConfigVariableCore::VT_double, description, flags)
+  ConfigVariable(name, ConfigVariableCore::VT_double, description, flags),
 #else
 #else
-  ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags)
+  ConfigVariable(name, ConfigVariableCore::VT_double, string(), flags),
 #endif
 #endif
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_default_value(default_value);
   _core->set_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -123,7 +126,12 @@ set_value(double value) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE double ConfigVariableDouble::
 INLINE double ConfigVariableDouble::
 get_value() const {
 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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 0
dtool/src/prc/configVariableDouble.h

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

+ 9 - 10
dtool/src/prc/configVariableEnum.I

@@ -31,10 +31,9 @@ ConfigVariableEnum(const string &name, EnumType default_value,
 #else
 #else
   ConfigVariable(name, ConfigVariableCore::VT_enum, string(), flags),
   ConfigVariable(name, ConfigVariableCore::VT_enum, string(), flags),
 #endif
 #endif
-  _value_seq(-1),
-  _value(default_value),
   _got_default_value(true),
   _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_default_value(format_enum(default_value));
   _core->set_used();
   _core->set_used();
@@ -54,10 +53,9 @@ ConfigVariableEnum(const string &name, const string &default_value,
 #else
 #else
   ConfigVariable(name, ConfigVariableCore::VT_enum, string(), flags),
   ConfigVariable(name, ConfigVariableCore::VT_enum, string(), flags),
 #endif
 #endif
-  _value_seq(-1),
-  _value(default_value),
   _got_default_value(true),
   _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_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -136,11 +134,12 @@ set_value(EnumType value) {
 template<class EnumType>
 template<class EnumType>
 INLINE EnumType ConfigVariableEnum<EnumType>::
 INLINE EnumType ConfigVariableEnum<EnumType>::
 get_value() const {
 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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 3
dtool/src/prc/configVariableEnum.h

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

+ 6 - 7
dtool/src/prc/configVariableFilename.I

@@ -25,8 +25,7 @@
 INLINE ConfigVariableFilename::
 INLINE ConfigVariableFilename::
 ConfigVariableFilename(const string &name) :
 ConfigVariableFilename(const string &name) :
   ConfigVariable(name, VT_filename),
   ConfigVariable(name, VT_filename),
-  _value_seq(-1),
-  _value_stale(true)
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_used();
   _core->set_used();
 }
 }
@@ -44,8 +43,7 @@ ConfigVariableFilename(const string &name, const Filename &default_value,
 #else
 #else
   ConfigVariable(name, VT_filename, string(), flags),
   ConfigVariable(name, VT_filename, string(), flags),
 #endif
 #endif
-  _value_seq(-1),
-  _value_stale(true)
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_default_value(default_value);
   _core->set_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -233,10 +231,11 @@ set_value(const Filename &value) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const Filename &ConfigVariableFilename::
 INLINE const Filename &ConfigVariableFilename::
 get_value() const {
 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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 6
dtool/src/prc/configVariableFilename.cxx

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

+ 4 - 5
dtool/src/prc/configVariableFilename.h

@@ -67,12 +67,11 @@ PUBLISHED:
   INLINE void set_word(int n, const Filename &value);
   INLINE void set_word(int n, const Filename &value);
 
 
 private:
 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"
 #include "configVariableFilename.I"

+ 14 - 6
dtool/src/prc/configVariableInt.I

@@ -24,7 +24,8 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ConfigVariableInt::
 INLINE ConfigVariableInt::
 ConfigVariableInt(const string &name) :
 ConfigVariableInt(const string &name) :
-  ConfigVariable(name, VT_int)
+  ConfigVariable(name, VT_int),
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_used();
   _core->set_used();
 }
 }
@@ -38,10 +39,11 @@ INLINE ConfigVariableInt::
 ConfigVariableInt(const string &name, int default_value, 
 ConfigVariableInt(const string &name, int default_value, 
                   const string &description, int flags) :
                   const string &description, int flags) :
 #ifdef PRC_SAVE_DESCRIPTIONS
 #ifdef PRC_SAVE_DESCRIPTIONS
-  ConfigVariable(name, ConfigVariableCore::VT_int, description, flags)
+  ConfigVariable(name, ConfigVariableCore::VT_int, description, flags),
 #else
 #else
-  ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags)
+  ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags),
 #endif
 #endif
+  _local_modified(initial_invalid_cache())
 {
 {
   set_default_value(default_value);
   set_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -56,10 +58,11 @@ INLINE ConfigVariableInt::
 ConfigVariableInt(const string &name, const string &default_value, 
 ConfigVariableInt(const string &name, const string &default_value, 
                   const string &description, int flags) :
                   const string &description, int flags) :
 #ifdef PRC_SAVE_DESCRIPTIONS
 #ifdef PRC_SAVE_DESCRIPTIONS
-  ConfigVariable(name, ConfigVariableCore::VT_int, description, flags)
+  ConfigVariable(name, ConfigVariableCore::VT_int, description, flags),
 #else
 #else
-  ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags)
+  ConfigVariable(name, ConfigVariableCore::VT_int, string(), flags),
 #endif
 #endif
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_default_value(default_value);
   _core->set_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -123,7 +126,12 @@ set_value(int value) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE int ConfigVariableInt::
 INLINE int ConfigVariableInt::
 get_value() const {
 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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 0
dtool/src/prc/configVariableInt.h

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

+ 2 - 1
dtool/src/prc/configVariableManager.h

@@ -30,7 +30,8 @@ class ConfigVariableCore;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : ConfigVariableManager
 //       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
 //               everywhere in the world, and keeps them in sorted
 //               order.
 //               order.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 21 - 8
dtool/src/prc/configVariableSearchPath.I

@@ -30,8 +30,7 @@ ConfigVariableSearchPath(const string &name,
 #else
 #else
   ConfigVariableBase(name, VT_search_path, string(), flags),
   ConfigVariableBase(name, VT_search_path, string(), flags),
 #endif
 #endif
-  _value_seq(-1),
-  _value_stale(true)
+  _local_modified(initial_invalid_cache())
 {
 {
   // A SearchPath variable implicitly defines a default value of the empty
   // A SearchPath variable implicitly defines a default value of the empty
   // string.  This is just to prevent the core variable from
   // string.  This is just to prevent the core variable from
@@ -61,6 +60,20 @@ operator const DSearchPath & () const {
   return get_value();
   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
 //     Function: ConfigVariableSearchPath::clear_local_value
 //       Access: Published
 //       Access: Published
@@ -79,7 +92,7 @@ clear_local_value() {
     any_to_clear = true;
     any_to_clear = true;
   }
   }
 
 
-  _value_stale = true;
+  _local_modified = initial_invalid_cache();
   return any_to_clear;
   return any_to_clear;
 }
 }
 
 
@@ -102,7 +115,7 @@ clear() {
 INLINE void ConfigVariableSearchPath::
 INLINE void ConfigVariableSearchPath::
 append_directory(const Filename &directory) {
 append_directory(const Filename &directory) {
   _postfix.append_directory(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::
 INLINE void ConfigVariableSearchPath::
 prepend_directory(const Filename &directory) {
 prepend_directory(const Filename &directory) {
   _prefix.prepend_directory(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::
 INLINE void ConfigVariableSearchPath::
 append_path(const string &path, const string &separator) {
 append_path(const string &path, const string &separator) {
   _postfix.append_path(path, 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::
 INLINE void ConfigVariableSearchPath::
 append_path(const DSearchPath &path) {
 append_path(const DSearchPath &path) {
   _postfix.append_path(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::
 INLINE void ConfigVariableSearchPath::
 prepend_path(const DSearchPath &path) {
 prepend_path(const DSearchPath &path) {
   _prefix.prepend_path(path);
   _prefix.prepend_path(path);
-  _value_stale = true;
+  _local_modified = initial_invalid_cache();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 7 - 23
dtool/src/prc/configVariableSearchPath.cxx

@@ -19,20 +19,6 @@
 #include "configVariableSearchPath.h"
 #include "configVariableSearchPath.h"
 #include "executionEnvironment.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
 //     Function: ConfigVariableSearchPath::reload_search_path
 //       Access: Private
 //       Access: Private
@@ -42,9 +28,10 @@ get_value() const {
 void ConfigVariableSearchPath::
 void ConfigVariableSearchPath::
 reload_search_path() {
 reload_search_path() {
   nassertv(_core != (ConfigVariableCore *)NULL);
   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();
   int num_unique_references = _core->get_num_unique_references();
   for (int i = 0; i < num_unique_references; i++) {
   for (int i = 0; i < num_unique_references; i++) {
     const ConfigDeclaration *decl = _core->get_unique_reference(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());
     string expanded = ExecutionEnvironment::expand_string(decl->get_string_value());
     ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
     ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
     if (!expanded.empty()) {
     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.
     // An empty search path implicitly has "." on it.
-    _value.append_directory(".");
+    _cache.append_directory(".");
   }
   }
-
-  _value_seq = _core->get_value_seq();
-  _value_stale = false;
 }
 }

+ 4 - 5
dtool/src/prc/configVariableSearchPath.h

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

+ 11 - 4
dtool/src/prc/configVariableString.I

@@ -24,7 +24,8 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ConfigVariableString::
 INLINE ConfigVariableString::
 ConfigVariableString(const string &name) :
 ConfigVariableString(const string &name) :
-  ConfigVariable(name, VT_string)
+  ConfigVariable(name, VT_string),
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_used();
   _core->set_used();
 }
 }
@@ -38,10 +39,11 @@ INLINE ConfigVariableString::
 ConfigVariableString(const string &name, const string &default_value, 
 ConfigVariableString(const string &name, const string &default_value, 
                      const string &description, int flags) :
                      const string &description, int flags) :
 #ifdef PRC_SAVE_DESCRIPTIONS
 #ifdef PRC_SAVE_DESCRIPTIONS
-  ConfigVariable(name, VT_string, description, flags)
+  ConfigVariable(name, VT_string, description, flags),
 #else
 #else
-  ConfigVariable(name, VT_string, string(), flags)
+  ConfigVariable(name, VT_string, string(), flags),
 #endif
 #endif
+  _local_modified(initial_invalid_cache())
 {
 {
   _core->set_default_value(default_value);
   _core->set_default_value(default_value);
   _core->set_used();
   _core->set_used();
@@ -155,7 +157,12 @@ set_value(const string &value) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const string &ConfigVariableString::
 INLINE const string &ConfigVariableString::
 get_value() const {
 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;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 0
dtool/src/prc/configVariableString.h

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

+ 6 - 0
dtool/src/prc/config_prc.cxx

@@ -17,5 +17,11 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 #include "config_prc.h"
 #include "config_prc.h"
+#include "configVariableBool.h"
 
 
 NotifyCategoryDef(prc, "");
 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");
+

+ 4 - 0
dtool/src/prc/config_prc.h

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

+ 1 - 5
dtool/src/prc/notify.cxx

@@ -22,16 +22,12 @@
 #include "configVariableFilename.h"
 #include "configVariableFilename.h"
 #include "configVariableBool.h"
 #include "configVariableBool.h"
 #include "filename.h"
 #include "filename.h"
+#include "config_prc.h"
 
 
 #include <ctype.h>
 #include <ctype.h>
 
 
 Notify *Notify::_global_ptr = (Notify *)NULL;
 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
 //     Function: Notify::Constructor
 //       Access: Public
 //       Access: Public

+ 16 - 0
dtool/src/prc/notifyCategory.I

@@ -37,6 +37,20 @@ get_basename() const {
   return _basename;
   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
 //     Function: NotifyCategory::set_severity
 //       Access: Public
 //       Access: Public
@@ -47,6 +61,7 @@ get_basename() const {
 INLINE void NotifyCategory::
 INLINE void NotifyCategory::
 set_severity(NotifySeverity severity) {
 set_severity(NotifySeverity severity) {
   _severity = severity;
   _severity = severity;
+  invalidate_cache();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -57,6 +72,7 @@ set_severity(NotifySeverity severity) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool NotifyCategory::
 INLINE bool NotifyCategory::
 is_on(NotifySeverity severity) const {
 is_on(NotifySeverity severity) const {
+  TAU_PROFILE("bool NotifyCategory::is_on(NotifySeverity) const", " ", TAU_USER);
   return (int)severity >= (int)get_severity();
   return (int)severity >= (int)get_severity();
 }
 }
 
 

+ 30 - 26
dtool/src/prc/notifyCategory.cxx

@@ -21,6 +21,7 @@
 #include "configPageManager.h"
 #include "configPageManager.h"
 #include "configVariableString.h"
 #include "configVariableString.h"
 #include "configVariableBool.h"
 #include "configVariableBool.h"
+#include "config_prc.h"
 
 
 #include <time.h>  // for strftime().
 #include <time.h>  // for strftime().
 #include <assert.h>
 #include <assert.h>
@@ -40,7 +41,8 @@ NotifyCategory(const string &fullname, const string &basename,
   _parent(parent),
   _parent(parent),
   _severity(get_config_name(), NS_unspecified, 
   _severity(get_config_name(), NS_unspecified, 
             "Default severity of this notify category", 
             "Default severity of this notify category", 
-            ConfigVariable::F_dynamic)
+            ConfigVariable::F_dynamic),
+  _local_modified(initial_invalid_cache())
 {
 {
   if (_parent != (NotifyCategory *)NULL) {
   if (_parent != (NotifyCategory *)NULL) {
     _parent->_children.push_back(this);
     _parent->_children.push_back(this);
@@ -50,31 +52,6 @@ NotifyCategory(const string &fullname, const string &basename,
   nassertv(_parent != (NotifyCategory *)NULL || _fullname.empty());
   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
 //     Function: NotifyCategory::out
 //       Access: Published
 //       Access: Published
@@ -184,6 +161,33 @@ get_config_name() const {
   return config_name;
   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
 //     Function: NotifyCategory::get_notify_timestamp
 //       Access: Private, Static
 //       Access: Private, Static

+ 7 - 2
dtool/src/prc/notifyCategory.h

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

+ 5 - 0
dtool/src/prc/notifyCategoryProxy.h

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

+ 2 - 1
panda/src/chan/animChannelScalarDynamic.cxx

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

+ 3 - 0
panda/src/chan/animChannelScalarDynamic.h

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

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