Browse Source

guarantee word alignment for AtomicAdjust stuff

David Rose 14 years ago
parent
commit
539b61571c

+ 13 - 10
dtool/src/dtoolbase/atomicAdjustDummyImpl.I

@@ -79,9 +79,10 @@ get(const TVOLATILE AtomicAdjustDummyImpl::Integer &var) {
 //  Description: Atomically changes the indicated variable and
 //  Description: Atomically changes the indicated variable and
 //               returns the original value.
 //               returns the original value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustDummyImpl::
-set_ptr(void * TVOLATILE &var, void *new_value) {
-  void *orig_value = var;
+INLINE AtomicAdjustDummyImpl::Pointer AtomicAdjustDummyImpl::
+set_ptr(TVOLATILE AtomicAdjustDummyImpl::Pointer &var, 
+        AtomicAdjustDummyImpl::Pointer new_value) {
+  Pointer orig_value = var;
   var = new_value;
   var = new_value;
   return orig_value;
   return orig_value;
 }
 }
@@ -95,8 +96,8 @@ set_ptr(void * TVOLATILE &var, void *new_value) {
 //               asynchronously setting, incrementing, or decrementing
 //               asynchronously setting, incrementing, or decrementing
 //               (via other AtomicAjust methods).
 //               (via other AtomicAjust methods).
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustDummyImpl::
-get_ptr(void * const TVOLATILE &var) {
+INLINE AtomicAdjustDummyImpl::Pointer AtomicAdjustDummyImpl::
+get_ptr(const TVOLATILE AtomicAdjustDummyImpl::Pointer &var) {
   return var;
   return var;
 }
 }
 
 
@@ -111,7 +112,8 @@ get_ptr(void * const TVOLATILE &var) {
 //               return_value == old_value.
 //               return_value == old_value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustDummyImpl::Integer AtomicAdjustDummyImpl::
 INLINE AtomicAdjustDummyImpl::Integer AtomicAdjustDummyImpl::
-compare_and_exchange(TVOLATILE AtomicAdjustDummyImpl::Integer &mem, AtomicAdjustDummyImpl::Integer old_value,
+compare_and_exchange(TVOLATILE AtomicAdjustDummyImpl::Integer &mem, 
+                     AtomicAdjustDummyImpl::Integer old_value,
                      AtomicAdjustDummyImpl::Integer new_value) {
                      AtomicAdjustDummyImpl::Integer new_value) {
   Integer orig_value = mem;
   Integer orig_value = mem;
   if (mem == old_value) {
   if (mem == old_value) {
@@ -127,10 +129,11 @@ compare_and_exchange(TVOLATILE AtomicAdjustDummyImpl::Integer &mem, AtomicAdjust
 //
 //
 //               As above, but works on pointers instead of integers.
 //               As above, but works on pointers instead of integers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustDummyImpl::
-compare_and_exchange_ptr(void * TVOLATILE &mem, void *old_value,
-                         void *new_value) {
-  void *orig_value = mem;
+INLINE AtomicAdjustDummyImpl::Pointer AtomicAdjustDummyImpl::
+compare_and_exchange_ptr(TVOLATILE AtomicAdjustDummyImpl::Pointer &mem, 
+                         AtomicAdjustDummyImpl::Pointer old_value,
+                         AtomicAdjustDummyImpl::Pointer new_value) {
+  Pointer orig_value = mem;
   if (mem == old_value) {
   if (mem == old_value) {
     mem = new_value;
     mem = new_value;
   }
   }

+ 8 - 7
dtool/src/dtoolbase/atomicAdjustDummyImpl.h

@@ -29,6 +29,7 @@
 class EXPCL_DTOOL AtomicAdjustDummyImpl {
 class EXPCL_DTOOL AtomicAdjustDummyImpl {
 public:
 public:
   typedef long Integer;
   typedef long Integer;
+  typedef void *Pointer;
 
 
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static bool dec(TVOLATILE Integer &var);
   INLINE static bool dec(TVOLATILE Integer &var);
@@ -36,16 +37,16 @@ public:
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer get(const TVOLATILE Integer &var);
   INLINE static Integer get(const TVOLATILE Integer &var);
 
 
-  INLINE static void *set_ptr(void * TVOLATILE &var, void *new_value);
-  INLINE static void *get_ptr(void * const TVOLATILE &var);
+  INLINE static Pointer set_ptr(TVOLATILE Pointer &var, Pointer new_value);
+  INLINE static Pointer get_ptr(const TVOLATILE Pointer &var);
 
 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
-                                              Integer old_value,
-                                              Integer new_value);
+                                             Integer old_value,
+                                             Integer new_value);
 
 
-  INLINE static void *compare_and_exchange_ptr(void * TVOLATILE &mem, 
-                                               void *old_value,
-                                               void *new_value);
+  INLINE static Pointer compare_and_exchange_ptr(TVOLATILE Pointer &mem, 
+                                                 Pointer old_value,
+                                                 Pointer new_value);
 };
 };
 
 
 #include "atomicAdjustDummyImpl.I"
 #include "atomicAdjustDummyImpl.I"

+ 25 - 12
dtool/src/dtoolbase/atomicAdjustI386Impl.I

@@ -20,6 +20,7 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void AtomicAdjustI386Impl::
 INLINE void AtomicAdjustI386Impl::
 inc(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
 inc(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
 #ifdef _M_IX86
 #ifdef _M_IX86
   // Windows case
   // Windows case
   TVOLATILE Integer *var_ptr = &var;
   TVOLATILE Integer *var_ptr = &var;
@@ -44,6 +45,7 @@ inc(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool AtomicAdjustI386Impl::
 INLINE bool AtomicAdjustI386Impl::
 dec(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
 dec(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
   unsigned char c;
   unsigned char c;
 #ifdef _M_IX86
 #ifdef _M_IX86
   // Windows case
   // Windows case
@@ -70,6 +72,7 @@ dec(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void AtomicAdjustI386Impl::
 INLINE void AtomicAdjustI386Impl::
 add(TVOLATILE AtomicAdjustI386Impl::Integer &var, AtomicAdjustI386Impl::Integer delta) {
 add(TVOLATILE AtomicAdjustI386Impl::Integer &var, AtomicAdjustI386Impl::Integer delta) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
   Integer orig_value = var;
   Integer orig_value = var;
   while (compare_and_exchange(var, orig_value, orig_value + delta) != orig_value) {
   while (compare_and_exchange(var, orig_value, orig_value + delta) != orig_value) {
     orig_value = var;
     orig_value = var;
@@ -83,7 +86,9 @@ add(TVOLATILE AtomicAdjustI386Impl::Integer &var, AtomicAdjustI386Impl::Integer
 //               returns the original value.
 //               returns the original value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
-set(TVOLATILE AtomicAdjustI386Impl::Integer &var, AtomicAdjustI386Impl::Integer new_value) {
+set(TVOLATILE AtomicAdjustI386Impl::Integer &var, 
+    AtomicAdjustI386Impl::Integer new_value) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
   Integer orig_value = var;
   Integer orig_value = var;
   var = new_value;
   var = new_value;
   return orig_value;
   return orig_value;
@@ -100,6 +105,7 @@ set(TVOLATILE AtomicAdjustI386Impl::Integer &var, AtomicAdjustI386Impl::Integer
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
 get(const TVOLATILE AtomicAdjustI386Impl::Integer &var) {
 get(const TVOLATILE AtomicAdjustI386Impl::Integer &var) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
   return var;
   return var;
 }
 }
 
 
@@ -109,9 +115,11 @@ get(const TVOLATILE AtomicAdjustI386Impl::Integer &var) {
 //  Description: Atomically changes the indicated variable and
 //  Description: Atomically changes the indicated variable and
 //               returns the original value.
 //               returns the original value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustI386Impl::
-set_ptr(void * TVOLATILE &var, void *new_value) {
-  void *orig_value = var;
+INLINE AtomicAdjustI386Impl::Pointer AtomicAdjustI386Impl::
+set_ptr(TVOLATILE AtomicAdjustI386Impl::Pointer &var, 
+        AtomicAdjustI386Impl::Pointer new_value) {
+  assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
+  Pointer orig_value = var;
   var = new_value;
   var = new_value;
   return orig_value;
   return orig_value;
 }
 }
@@ -125,8 +133,9 @@ set_ptr(void * TVOLATILE &var, void *new_value) {
 //               asynchronously setting, incrementing, or decrementing
 //               asynchronously setting, incrementing, or decrementing
 //               (via other AtomicAjust methods).
 //               (via other AtomicAjust methods).
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustI386Impl::
-get_ptr(void * const TVOLATILE &var) {
+INLINE AtomicAdjustI386Impl::Pointer AtomicAdjustI386Impl::
+get_ptr(const TVOLATILE AtomicAdjustI386Impl::Pointer &var) {
+  assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
   return var;
   return var;
 }
 }
 
 
@@ -150,8 +159,10 @@ get_ptr(void * const TVOLATILE &var) {
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
-compare_and_exchange(TVOLATILE AtomicAdjustI386Impl::Integer &mem, AtomicAdjustI386Impl::Integer old_value,
+compare_and_exchange(TVOLATILE AtomicAdjustI386Impl::Integer &mem, 
+                     AtomicAdjustI386Impl::Integer old_value,
                      AtomicAdjustI386Impl::Integer new_value) {
                      AtomicAdjustI386Impl::Integer new_value) {
+  assert((((size_t)&mem) & (sizeof(Integer) - 1)) == 0);
   Integer prev;
   Integer prev;
 #ifdef _M_IX86
 #ifdef _M_IX86
   // Windows case
   // Windows case
@@ -180,13 +191,15 @@ compare_and_exchange(TVOLATILE AtomicAdjustI386Impl::Integer &mem, AtomicAdjustI
 //
 //
 //               As above, but works on pointers instead of integers.
 //               As above, but works on pointers instead of integers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustI386Impl::
-compare_and_exchange_ptr(void * TVOLATILE &mem, void *old_value,
-                         void *new_value) {
-  void *prev;
+INLINE AtomicAdjustI386Impl::Pointer AtomicAdjustI386Impl::
+compare_and_exchange_ptr(TVOLATILE AtomicAdjustI386Impl::Pointer &mem, 
+                         AtomicAdjustI386Impl::Pointer old_value,
+                         AtomicAdjustI386Impl::Pointer new_value) {
+  assert((((size_t)&mem) & (sizeof(Pointer) - 1)) == 0);
+  Pointer prev;
 #ifdef _M_IX86
 #ifdef _M_IX86
   // Windows case
   // Windows case
-  void * TVOLATILE *mem_ptr = &mem;
+  TVOLATILE Pointer *mem_ptr = &mem;
   __asm {
   __asm {
     mov edx, mem_ptr;
     mov edx, mem_ptr;
     mov ecx, new_value;
     mov ecx, new_value;

+ 11 - 9
dtool/src/dtoolbase/atomicAdjustI386Impl.h

@@ -31,7 +31,9 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_DTOOL AtomicAdjustI386Impl {
 class EXPCL_DTOOL AtomicAdjustI386Impl {
 public:
 public:
-  typedef PN_int32 Integer;
+  typedef ALIGN_4BYTE PN_int32 Integer;
+  typedef void *UnalignedPointer;
+  typedef ALIGN_4BYTE UnalignedPointer Pointer;
 
 
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static bool dec(TVOLATILE Integer &var);
   INLINE static bool dec(TVOLATILE Integer &var);
@@ -39,16 +41,16 @@ public:
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer get(const TVOLATILE Integer &var);
   INLINE static Integer get(const TVOLATILE Integer &var);
 
 
-  INLINE static void *set_ptr(void * TVOLATILE &var, void *new_value);
-  INLINE static void *get_ptr(void * const TVOLATILE &var);
+  INLINE static Pointer set_ptr(TVOLATILE Pointer &var, Pointer new_value);
+  INLINE static Pointer get_ptr(const TVOLATILE Pointer &var);
 
 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
-                                              Integer old_value,
-                                              Integer new_value);
-
-  INLINE static void *compare_and_exchange_ptr(void * TVOLATILE &mem, 
-                                               void *old_value,
-                                               void *new_value);
+                                             Integer old_value,
+                                             Integer new_value);
+  
+  INLINE static Pointer compare_and_exchange_ptr(TVOLATILE Pointer &mem, 
+                                                 Pointer old_value,
+                                                 Pointer new_value);
 };
 };
 
 
 #include "atomicAdjustI386Impl.I"
 #include "atomicAdjustI386Impl.I"

+ 10 - 10
dtool/src/dtoolbase/atomicAdjustPosixImpl.I

@@ -91,10 +91,10 @@ get(const TVOLATILE AtomicAdjustPosixImpl::Integer &var) {
 //  Description: Atomically changes the indicated variable and
 //  Description: Atomically changes the indicated variable and
 //               returns the original value.
 //               returns the original value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustPosixImpl::
-set_ptr(void * TVOLATILE &var, void *new_value) {
+INLINE Pointer AtomicAdjustPosixImpl::
+set_ptr(TVOLATILE Pointer &var, Pointer new_value) {
   pthread_mutex_lock(&_mutex);
   pthread_mutex_lock(&_mutex);
-  void *orig_value = var;
+  Pointer orig_value = var;
   var = new_value;
   var = new_value;
   pthread_mutex_unlock(&_mutex);
   pthread_mutex_unlock(&_mutex);
   return orig_value;
   return orig_value;
@@ -109,10 +109,10 @@ set_ptr(void * TVOLATILE &var, void *new_value) {
 //               asynchronously setting, incrementing, or decrementing
 //               asynchronously setting, incrementing, or decrementing
 //               (via other AtomicAjust methods).
 //               (via other AtomicAjust methods).
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustPosixImpl::
-get_ptr(void * const TVOLATILE &var) {
+INLINE Pointer AtomicAdjustPosixImpl::
+get_ptr(const TVOLATILE Pointer &var) {
   pthread_mutex_lock(&_mutex);
   pthread_mutex_lock(&_mutex);
-  void *orig_value = var;
+  Pointer orig_value = var;
   pthread_mutex_unlock(&_mutex);
   pthread_mutex_unlock(&_mutex);
   return orig_value;
   return orig_value;
 }
 }
@@ -155,11 +155,11 @@ compare_and_exchange(TVOLATILE AtomicAdjustPosixImpl::Integer &mem, AtomicAdjust
 //
 //
 //               As above, but works on pointers instead of integers.
 //               As above, but works on pointers instead of integers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustPosixImpl::
-compare_and_exchange_ptr(void * TVOLATILE &mem, void *old_value,
-                         void *new_value) {
+INLINE Pointer AtomicAdjustPosixImpl::
+compare_and_exchange_ptr(TVOLATILE Pointer &mem, Pointer old_value,
+                         Pointer new_value) {
   pthread_mutex_lock(&_mutex);
   pthread_mutex_lock(&_mutex);
-  void *orig_value = mem;
+  Pointer orig_value = mem;
   if (mem == old_value) {
   if (mem == old_value) {
     mem = new_value;
     mem = new_value;
   }
   }

+ 7 - 6
dtool/src/dtoolbase/atomicAdjustPosixImpl.h

@@ -33,6 +33,7 @@ public:
   // In Posix, "long" is generally the native word size (32- or
   // In Posix, "long" is generally the native word size (32- or
   // 64-bit), which is what we'd prefer.
   // 64-bit), which is what we'd prefer.
   typedef long Integer;
   typedef long Integer;
+  typedef void *Pointer;
 
 
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static bool dec(TVOLATILE Integer &var);
   INLINE static bool dec(TVOLATILE Integer &var);
@@ -40,16 +41,16 @@ public:
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer get(const TVOLATILE Integer &var);
   INLINE static Integer get(const TVOLATILE Integer &var);
 
 
-  INLINE static void *set_ptr(void * TVOLATILE &var, void *new_value);
-  INLINE static void *get_ptr(void * const TVOLATILE &var);
+  INLINE static Pointer set_ptr(TVOLATILE Pointer &var, Pointer new_value);
+  INLINE static Pointer get_ptr(const TVOLATILE Pointer &var);
 
 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
                                              Integer old_value,
                                              Integer old_value,
                                              Integer new_value);
                                              Integer new_value);
-
-  INLINE static void *compare_and_exchange_ptr(void * TVOLATILE &mem, 
-                                               void *old_value,
-                                               void *new_value);
+  
+  INLINE static Pointer compare_and_exchange_ptr(TVOLATILE Pointer &mem, 
+                                                 Pointer old_value,
+                                                 Pointer new_value);
 
 
 private:
 private:
   static pthread_mutex_t _mutex;
   static pthread_mutex_t _mutex;

+ 28 - 12
dtool/src/dtoolbase/atomicAdjustWin32Impl.I

@@ -20,6 +20,7 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void AtomicAdjustWin32Impl::
 INLINE void AtomicAdjustWin32Impl::
 inc(TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
 inc(TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
 #ifdef _WIN64
 #ifdef _WIN64
   InterlockedIncrement64(&var);
   InterlockedIncrement64(&var);
 #else
 #else
@@ -36,6 +37,7 @@ inc(TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool AtomicAdjustWin32Impl::
 INLINE bool AtomicAdjustWin32Impl::
 dec(TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
 dec(TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
 #ifdef _WIN64
 #ifdef _WIN64
   return (InterlockedDecrement64(&var) != 0);
   return (InterlockedDecrement64(&var) != 0);
 #else
 #else
@@ -64,7 +66,9 @@ add(TVOLATILE AtomicAdjustWin32Impl::Integer &var, AtomicAdjustWin32Impl::Intege
 //               returns the original value.
 //               returns the original value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
-set(TVOLATILE AtomicAdjustWin32Impl::Integer &var, AtomicAdjustWin32Impl::Integer new_value) {
+set(TVOLATILE AtomicAdjustWin32Impl::Integer &var, 
+    AtomicAdjustWin32Impl::Integer new_value) {
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
 #ifdef _WIN64
 #ifdef _WIN64
   return InterlockedExchange64(&var, new_value);
   return InterlockedExchange64(&var, new_value);
 #else
 #else
@@ -83,6 +87,12 @@ set(TVOLATILE AtomicAdjustWin32Impl::Integer &var, AtomicAdjustWin32Impl::Intege
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
 get(const TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
 get(const TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
+  // On Intel platforms, word-aligned loads are atomic (if performed
+  // in a single instruction).  We can't guarantee the compiler will
+  // generate a single instruction to load this value, but it
+  // certainly won't happen if its address isn't word-aligned, so make
+  // sure that's the case.
+  assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
   return var;
   return var;
 }
 }
 
 
@@ -92,11 +102,11 @@ get(const TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
 //  Description: Atomically changes the indicated variable and
 //  Description: Atomically changes the indicated variable and
 //               returns the original value.
 //               returns the original value.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustWin32Impl::
-set_ptr(void * TVOLATILE &var, void *new_value) {
-  void *orig_value = var;
-  var = new_value;
-  return orig_value;
+INLINE AtomicAdjustWin32Impl::Pointer AtomicAdjustWin32Impl::
+set_ptr(TVOLATILE AtomicAdjustWin32Impl::Pointer &var, 
+        AtomicAdjustWin32Impl::Pointer new_value) {
+  assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
+  return InterlockedExchangePointer(&var, new_value);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -108,8 +118,10 @@ set_ptr(void * TVOLATILE &var, void *new_value) {
 //               asynchronously setting, incrementing, or decrementing
 //               asynchronously setting, incrementing, or decrementing
 //               (via other AtomicAjust methods).
 //               (via other AtomicAjust methods).
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustWin32Impl::
-get_ptr(void * const TVOLATILE &var) {
+INLINE AtomicAdjustWin32Impl::Pointer AtomicAdjustWin32Impl::
+get_ptr(const TVOLATILE AtomicAdjustWin32Impl::Pointer &var) {
+  // As in get(), make sure the address is word-aligned.
+  assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
   return var;
   return var;
 }
 }
 
 
@@ -133,8 +145,10 @@ get_ptr(void * const TVOLATILE &var) {
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
-compare_and_exchange(TVOLATILE AtomicAdjustWin32Impl::Integer &mem, AtomicAdjustWin32Impl::Integer old_value,
+compare_and_exchange(TVOLATILE AtomicAdjustWin32Impl::Integer &mem, 
+                     AtomicAdjustWin32Impl::Integer old_value,
                      AtomicAdjustWin32Impl::Integer new_value) {
                      AtomicAdjustWin32Impl::Integer new_value) {
+  assert((((size_t)&mem) & (sizeof(Integer) - 1)) == 0);
   // Note that the AtomicAdjust parameter order is different from
   // Note that the AtomicAdjust parameter order is different from
   // Windows convention!
   // Windows convention!
 #ifdef _WIN64
 #ifdef _WIN64
@@ -151,9 +165,11 @@ compare_and_exchange(TVOLATILE AtomicAdjustWin32Impl::Integer &mem, AtomicAdjust
 //
 //
 //               As above, but works on pointers instead of integers.
 //               As above, but works on pointers instead of integers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustWin32Impl::
-compare_and_exchange_ptr(void * TVOLATILE &mem, void *old_value,
-                         void *new_value) {
+INLINE AtomicAdjustWin32Impl::Pointer AtomicAdjustWin32Impl::
+compare_and_exchange_ptr(TVOLATILE AtomicAdjustWin32Impl::Pointer &mem,
+                         AtomicAdjustWin32Impl::Pointer old_value,
+                         AtomicAdjustWin32Impl::Pointer new_value) {
+  assert((((size_t)&mem) & (sizeof(Pointer) - 1)) == 0);
   // Note that the AtomicAdjust parameter order is different from
   // Note that the AtomicAdjust parameter order is different from
   // Windows convention!
   // Windows convention!
   return InterlockedCompareExchangePointer(&mem, new_value, old_value);
   return InterlockedCompareExchangePointer(&mem, new_value, old_value);

+ 12 - 8
dtool/src/dtoolbase/atomicAdjustWin32Impl.h

@@ -33,9 +33,13 @@ class EXPCL_DTOOL AtomicAdjustWin32Impl {
 public:
 public:
 #ifdef _WIN64
 #ifdef _WIN64
   // For 64-bit builds, we'd prefer to use a 64-bit integer.
   // For 64-bit builds, we'd prefer to use a 64-bit integer.
-  typedef LONGLONG Integer;
+  typedef ALIGN_8BYTE LONGLONG Integer;
+  typedef void *UnalignedPointer;
+  typedef ALIGN_8BYTE UnalignedPointer Pointer;
 #else
 #else
-  typedef LONG Integer;
+  typedef ALIGN_4BYTE LONG Integer;
+  typedef void *UnalignedPointer;
+  typedef ALIGN_4BYTE UnalignedPointer Pointer;
 #endif  // _WIN64
 #endif  // _WIN64
 
 
   INLINE static void inc(TVOLATILE Integer &var);
   INLINE static void inc(TVOLATILE Integer &var);
@@ -44,16 +48,16 @@ public:
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
   INLINE static Integer get(const TVOLATILE Integer &var);
   INLINE static Integer get(const TVOLATILE Integer &var);
 
 
-  INLINE static void *set_ptr(void * TVOLATILE &var, void *new_value);
-  INLINE static void *get_ptr(void * const TVOLATILE &var);
+  INLINE static Pointer set_ptr(TVOLATILE Pointer &var, Pointer new_value);
+  INLINE static Pointer get_ptr(const TVOLATILE Pointer &var);
 
 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
   INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem, 
                                              Integer old_value,
                                              Integer old_value,
                                              Integer new_value);
                                              Integer new_value);
-
-  INLINE static void *compare_and_exchange_ptr(void * TVOLATILE &mem, 
-                                               void *old_value,
-                                               void *new_value);
+  
+  INLINE static Pointer compare_and_exchange_ptr(TVOLATILE Pointer &mem, 
+                                                 Pointer old_value,
+                                                 Pointer new_value);
 };
 };
 
 
 #include "atomicAdjustWin32Impl.I"
 #include "atomicAdjustWin32Impl.I"

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

@@ -312,6 +312,21 @@
 #define NATIVE_WORDSIZE 32
 #define NATIVE_WORDSIZE 32
 #endif
 #endif
 
 
+/* Some byte-alignment macros. */
+#ifdef CPPPARSER
+#define ALIGN_4BYTE
+#define ALIGN_8BYTE
+#elif defined(WIN32_VC)
+#define ALIGN_4BYTE __declspec(align(4))
+#define ALIGN_8BYTE __declspec(align(8))
+#elif defined(__GNUC__)
+#define ALIGN_4BYTE __attribute__ ((aligned (4)))
+#define ALIGN_8BYTE __attribute__ ((aligned (8)))
+#else
+#define ALIGN_4BYTE
+#define ALIGN_8BYTE
+#endif
+
 
 
 /*
 /*
  We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket
  We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket

+ 1 - 1
dtool/src/dtoolbase/neverFreeMemory.cxx

@@ -27,7 +27,7 @@ static const size_t min_page_size = 128 * 1024;  // 128K
 
 
 // We always allocate integer multiples of this many bytes, to
 // We always allocate integer multiples of this many bytes, to
 // guarantee this minimum alignment.
 // guarantee this minimum alignment.
-static const size_t alignment_size = sizeof(long);
+static const size_t alignment_size = sizeof(void *);
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NeverFreeMemory::Constructor
 //     Function: NeverFreeMemory::Constructor

+ 16 - 16
dtool/src/dtoolutil/filename.cxx

@@ -51,10 +51,10 @@
 
 
 TextEncoder::Encoding Filename::_filesystem_encoding = TextEncoder::E_utf8;
 TextEncoder::Encoding Filename::_filesystem_encoding = TextEncoder::E_utf8;
 
 
-Filename *Filename::_home_directory;
-Filename *Filename::_temp_directory;
-Filename *Filename::_user_appdata_directory;
-Filename *Filename::_common_appdata_directory;
+TVOLATILE AtomicAdjust::Pointer Filename::_home_directory;
+TVOLATILE AtomicAdjust::Pointer Filename::_temp_directory;
+TVOLATILE AtomicAdjust::Pointer Filename::_user_appdata_directory;
+TVOLATILE AtomicAdjust::Pointer Filename::_common_appdata_directory;
 TypeHandle Filename::_type_handle;
 TypeHandle Filename::_type_handle;
 
 
 #ifdef WIN32
 #ifdef WIN32
@@ -506,7 +506,7 @@ temporary(const string &dirname, const string &prefix, const string &suffix,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 const Filename &Filename::
 const Filename &Filename::
 get_home_directory() {
 get_home_directory() {
-  if (AtomicAdjust::get_ptr((void * TVOLATILE &)_home_directory) == NULL) {
+  if (AtomicAdjust::get_ptr(_home_directory) == NULL) {
     Filename home_directory;
     Filename home_directory;
 
 
     // In all environments, check $HOME first.
     // In all environments, check $HOME first.
@@ -549,14 +549,14 @@ get_home_directory() {
     }
     }
 
 
     Filename *newdir = new Filename(home_directory);
     Filename *newdir = new Filename(home_directory);
-    if (AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_home_directory, NULL, newdir) != NULL) {
+    if (AtomicAdjust::compare_and_exchange_ptr(_home_directory, NULL, newdir) != NULL) {
       // Didn't store it.  Must have been stored by someone else.
       // Didn't store it.  Must have been stored by someone else.
       assert(_home_directory != NULL);
       assert(_home_directory != NULL);
       delete newdir;
       delete newdir;
     }
     }
   }
   }
   
   
-  return (*_home_directory);
+  return (*(Filename *)_home_directory);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -567,7 +567,7 @@ get_home_directory() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 const Filename &Filename::
 const Filename &Filename::
 get_temp_directory() {
 get_temp_directory() {
-  if (AtomicAdjust::get_ptr((void * TVOLATILE &)_temp_directory) == NULL) {
+  if (AtomicAdjust::get_ptr(_temp_directory) == NULL) {
     Filename temp_directory;
     Filename temp_directory;
 
 
 #ifdef WIN32
 #ifdef WIN32
@@ -596,14 +596,14 @@ get_temp_directory() {
     }
     }
 
 
     Filename *newdir = new Filename(temp_directory);
     Filename *newdir = new Filename(temp_directory);
-    if (AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_temp_directory, NULL, newdir) != NULL) {
+    if (AtomicAdjust::compare_and_exchange_ptr(_temp_directory, NULL, newdir) != NULL) {
       // Didn't store it.  Must have been stored by someone else.
       // Didn't store it.  Must have been stored by someone else.
       assert(_temp_directory != NULL);
       assert(_temp_directory != NULL);
       delete newdir;
       delete newdir;
     }
     }
   }
   }
 
 
-  return (*_temp_directory);
+  return (*(Filename *)_temp_directory);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -616,7 +616,7 @@ get_temp_directory() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 const Filename &Filename::
 const Filename &Filename::
 get_user_appdata_directory() {
 get_user_appdata_directory() {
-  if (AtomicAdjust::get_ptr((void * TVOLATILE &)_user_appdata_directory) == NULL) {
+  if (AtomicAdjust::get_ptr(_user_appdata_directory) == NULL) {
     Filename user_appdata_directory;
     Filename user_appdata_directory;
 
 
 #ifdef WIN32
 #ifdef WIN32
@@ -646,14 +646,14 @@ get_user_appdata_directory() {
     }
     }
 
 
     Filename *newdir = new Filename(user_appdata_directory);
     Filename *newdir = new Filename(user_appdata_directory);
-    if (AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_user_appdata_directory, NULL, newdir) != NULL) {
+    if (AtomicAdjust::compare_and_exchange_ptr(_user_appdata_directory, NULL, newdir) != NULL) {
       // Didn't store it.  Must have been stored by someone else.
       // Didn't store it.  Must have been stored by someone else.
       assert(_user_appdata_directory != NULL);
       assert(_user_appdata_directory != NULL);
       delete newdir;
       delete newdir;
     }
     }
   }
   }
 
 
-  return (*_user_appdata_directory);
+  return (*(Filename *)_user_appdata_directory);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -665,7 +665,7 @@ get_user_appdata_directory() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 const Filename &Filename::
 const Filename &Filename::
 get_common_appdata_directory() {
 get_common_appdata_directory() {
-  if (AtomicAdjust::get_ptr((void * TVOLATILE &)_common_appdata_directory) == NULL) {
+  if (AtomicAdjust::get_ptr(_common_appdata_directory) == NULL) {
     Filename common_appdata_directory;
     Filename common_appdata_directory;
 
 
 #ifdef WIN32
 #ifdef WIN32
@@ -694,14 +694,14 @@ get_common_appdata_directory() {
     }
     }
 
 
     Filename *newdir = new Filename(common_appdata_directory);
     Filename *newdir = new Filename(common_appdata_directory);
-    if (AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_common_appdata_directory, NULL, newdir) != NULL) {
+    if (AtomicAdjust::compare_and_exchange_ptr(_common_appdata_directory, NULL, newdir) != NULL) {
       // Didn't store it.  Must have been stored by someone else.
       // Didn't store it.  Must have been stored by someone else.
       assert(_common_appdata_directory != NULL);
       assert(_common_appdata_directory != NULL);
       delete newdir;
       delete newdir;
     }
     }
   }
   }
 
 
-  return (*_common_appdata_directory);
+  return (*(Filename *)_common_appdata_directory);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

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

@@ -256,10 +256,10 @@ protected:
   int _flags;
   int _flags;
 
 
   static TextEncoder::Encoding _filesystem_encoding;
   static TextEncoder::Encoding _filesystem_encoding;
-  static Filename *_home_directory;
-  static Filename *_temp_directory;
-  static Filename *_user_appdata_directory;
-  static Filename *_common_appdata_directory;
+  static TVOLATILE AtomicAdjust::Pointer _home_directory;
+  static TVOLATILE AtomicAdjust::Pointer _temp_directory;
+  static TVOLATILE AtomicAdjust::Pointer _user_appdata_directory;
+  static TVOLATILE AtomicAdjust::Pointer _common_appdata_directory;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 3 - 3
panda/src/audio/audioManager.cxx

@@ -106,7 +106,7 @@ PT(AudioManager) AudioManager::create_AudioManager() {
 AudioManager::
 AudioManager::
 ~AudioManager() {
 ~AudioManager() {
   if (_null_sound != (AudioSound *)NULL) {
   if (_null_sound != (AudioSound *)NULL) {
-    unref_delete(_null_sound);
+    unref_delete((AudioSound *)_null_sound);
   }
   }
 }
 }
 
 
@@ -146,7 +146,7 @@ get_null_sound() {
   if (_null_sound == (AudioSound *)NULL) {
   if (_null_sound == (AudioSound *)NULL) {
     AudioSound *new_sound = new NullAudioSound;
     AudioSound *new_sound = new NullAudioSound;
     new_sound->ref();
     new_sound->ref();
-    void *result = AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_null_sound, (void *)NULL, (void *)new_sound);
+    void *result = AtomicAdjust::compare_and_exchange_ptr(_null_sound, (void *)NULL, (void *)new_sound);
     if (result != NULL) {
     if (result != NULL) {
       // Someone else must have assigned the AudioSound first.  OK.
       // Someone else must have assigned the AudioSound first.  OK.
       nassertr(_null_sound != new_sound, NULL);
       nassertr(_null_sound != new_sound, NULL);
@@ -155,7 +155,7 @@ get_null_sound() {
     nassertr(_null_sound != NULL, NULL);
     nassertr(_null_sound != NULL, NULL);
   }
   }
   
   
-  return _null_sound;
+  return (AudioSound *)_null_sound;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 1
panda/src/audio/audioManager.h

@@ -21,6 +21,7 @@
 #include "lvecBase3.h"
 #include "lvecBase3.h"
 #include "filterProperties.h"
 #include "filterProperties.h"
 #include "movieAudio.h"
 #include "movieAudio.h"
+#include "atomicAdjust.h"
 
 
 typedef AudioManager *Create_AudioManager_proc();
 typedef AudioManager *Create_AudioManager_proc();
 
 
@@ -205,7 +206,7 @@ protected:
   // best flexibility.
   // best flexibility.
   
   
   static Create_AudioManager_proc* _create_AudioManager;
   static Create_AudioManager_proc* _create_AudioManager;
-  AudioSound *_null_sound;
+  AtomicAdjust::Pointer _null_sound;
 
 
   AudioManager();
   AudioManager();
 
 

+ 2 - 1
panda/src/express/pointerToVoid.h

@@ -18,6 +18,7 @@
 #include "pandabase.h"
 #include "pandabase.h"
 #include "pnotify.h"
 #include "pnotify.h"
 #include "memoryBase.h"
 #include "memoryBase.h"
+#include "atomicAdjust.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : PointerToVoid
 //       Class : PointerToVoid
@@ -62,7 +63,7 @@ protected:
   // from ReferenceCount.  (You can't downcast past a virtual
   // from ReferenceCount.  (You can't downcast past a virtual
   // inheritance level, but you can always cross-cast from a void
   // inheritance level, but you can always cross-cast from a void
   // pointer.)
   // pointer.)
-  void *_void_ptr;
+  AtomicAdjust::Pointer _void_ptr;
 };
 };
 
 
 #include "pointerToVoid.I"
 #include "pointerToVoid.I"

+ 4 - 4
panda/src/express/referenceCount.I

@@ -130,7 +130,7 @@ ReferenceCount::
 
 
   // Tell our weak reference holders that we're going away now.
   // Tell our weak reference holders that we're going away now.
   if (_weak_list != (WeakReferenceList *)NULL) {
   if (_weak_list != (WeakReferenceList *)NULL) {
-    delete _weak_list;
+    delete (WeakReferenceList *)_weak_list;
     _weak_list = (WeakReferenceList *)NULL;
     _weak_list = (WeakReferenceList *)NULL;
   }
   }
 
 
@@ -305,10 +305,10 @@ has_weak_list() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE WeakReferenceList *ReferenceCount::
 INLINE WeakReferenceList *ReferenceCount::
 get_weak_list() const {
 get_weak_list() const {
-  if (_weak_list == (WeakReferenceList *)NULL) {
+  if (AtomicAdjust::get_ptr(_weak_list) == (WeakReferenceList *)NULL) {
     ((ReferenceCount *)this)->create_weak_list();
     ((ReferenceCount *)this)->create_weak_list();
   }
   }
-  return _weak_list;
+  return (WeakReferenceList *)AtomicAdjust::get_ptr(_weak_list);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -334,7 +334,7 @@ INLINE void ReferenceCount::
 weak_unref(WeakPointerToVoid *ptv) {
 weak_unref(WeakPointerToVoid *ptv) {
   TAU_PROFILE("void ReferenceCount::weak_unref()", " ", TAU_USER);
   TAU_PROFILE("void ReferenceCount::weak_unref()", " ", TAU_USER);
   nassertv(has_weak_list());
   nassertv(has_weak_list());
-  _weak_list->clear_reference(ptv);
+  ((WeakReferenceList *)_weak_list)->clear_reference(ptv);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/express/referenceCount.cxx

@@ -70,7 +70,7 @@ void ReferenceCount::
 create_weak_list() {
 create_weak_list() {
   WeakReferenceList *weak_list = new WeakReferenceList;
   WeakReferenceList *weak_list = new WeakReferenceList;
   void *orig = 
   void *orig = 
-    AtomicAdjust::compare_and_exchange_ptr((void *&)_weak_list, NULL, weak_list);
+    AtomicAdjust::compare_and_exchange_ptr(_weak_list, NULL, weak_list);
   if (orig != (void *)NULL) {
   if (orig != (void *)NULL) {
     // Someone else created it first.
     // Someone else created it first.
     delete weak_list;
     delete weak_list;

+ 1 - 1
panda/src/express/referenceCount.h

@@ -88,7 +88,7 @@ private:
   };
   };
 
 
   AtomicAdjust::Integer _ref_count;
   AtomicAdjust::Integer _ref_count;
-  WeakReferenceList *_weak_list;
+  AtomicAdjust::Pointer _weak_list;  // WeakReferenceList *
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 2 - 2
panda/src/pstatclient/pStatClient.h

@@ -191,7 +191,7 @@ private:
     PerThread _per_thread;
     PerThread _per_thread;
   };
   };
   typedef Collector *CollectorPointer;
   typedef Collector *CollectorPointer;
-  void *_collectors;  // CollectorPointer *_collectors;
+  AtomicAdjust::Pointer _collectors;  // CollectorPointer *_collectors;
   AtomicAdjust::Integer _collectors_size;  // size of the allocated array
   AtomicAdjust::Integer _collectors_size;  // size of the allocated array
   AtomicAdjust::Integer _num_collectors;   // number of in-use elements within the array
   AtomicAdjust::Integer _num_collectors;   // number of in-use elements within the array
 
 
@@ -219,7 +219,7 @@ private:
     LightMutex _thread_lock;
     LightMutex _thread_lock;
   };
   };
   typedef InternalThread *ThreadPointer;
   typedef InternalThread *ThreadPointer;
-  void *_threads;  // ThreadPointer *_threads;
+  AtomicAdjust::Pointer _threads;  // ThreadPointer *_threads;
   AtomicAdjust::Integer _threads_size;  // size of the allocated array
   AtomicAdjust::Integer _threads_size;  // size of the allocated array
   AtomicAdjust::Integer _num_threads;   // number of in-use elements within the array
   AtomicAdjust::Integer _num_threads;   // number of in-use elements within the array