diff --git a/dtool/Config.Linux.pp b/dtool/Config.Linux.pp index 7d020fead7..fbd841e275 100644 --- a/dtool/Config.Linux.pp +++ b/dtool/Config.Linux.pp @@ -142,5 +142,3 @@ // The dynamic library file extension (usually .so .dll or .dylib): #define DYNAMIC_LIB_EXT .so - - diff --git a/dtool/Config.pp b/dtool/Config.pp index 6e45eb24a3..fda6025f07 100644 --- a/dtool/Config.pp +++ b/dtool/Config.pp @@ -555,6 +555,10 @@ // cause libdirect.dll to fail to load on Win98 clients. #define HAVE_DIRECTD +// If your system supports the Posix threads interface +// (pthread_create(), etc.), define this true. +#define HAVE_POSIX_THREADS $[isfile /usr/include/pthread.h] + // Do you want to build in support for threading (multiprocessing)? // Building in support for threading will enable Panda to take // advantage of multiple CPU's if you have them (and if the OS @@ -562,8 +566,11 @@ // slightly slow down Panda for the single CPU case, so this is not // enabled by default. -// Currently, threading support requires NSPR, so you should not -// define this true unless you have NSPR installed. +// You should only turn this on if you have some threading library +// available (most people will have one). Windows has one built-in. +// Linux uses Posix threads, which most Linuxes provide. +// Alternatively, the NSPR library also provides a threading interface +// that Panda can use. #define HAVE_THREADS // Even if threading is not defined, you might want to double-check diff --git a/dtool/LocalSetup.pp b/dtool/LocalSetup.pp index e28de4103c..80eba1a405 100644 --- a/dtool/LocalSetup.pp +++ b/dtool/LocalSetup.pp @@ -456,6 +456,9 @@ $[cdefine HAVE_SYS_SOUNDCARD_H] /* Do we have RTTI (and )? */ $[cdefine HAVE_RTTI] +/* Do we have Posix threads? */ +$[cdefine HAVE_POSIX_THREADS] + /* Must global operator new and delete functions throw exceptions? */ $[cdefine GLOBAL_OPERATOR_NEW_EXCEPTIONS] diff --git a/dtool/src/parser-inc/Sources.pp b/dtool/src/parser-inc/Sources.pp index 43d9d9e6f8..a4764e18e7 100644 --- a/dtool/src/parser-inc/Sources.pp +++ b/dtool/src/parser-inc/Sources.pp @@ -1,6 +1,6 @@ #define INSTALL_PARSER_INC \ algorithm deque ft2build.h hash_map hash_set iostream list map memory \ - pair queue set stack stdcompare.h stdtypedefs.h \ + pair pthread.h queue set stack stdcompare.h stdtypedefs.h \ string vector windows.h zlib.h files.h hex.h \ md5.h evp.h bits/pthreadtypes.h \ openssl/md5.h openssl/evp.h openssl/rand.h openssl/ssl.h openssl/x509.h openssl/err.h \ diff --git a/dtool/src/parser-inc/pthread.h b/dtool/src/parser-inc/pthread.h new file mode 100644 index 0000000000..428343eb02 --- /dev/null +++ b/dtool/src/parser-inc/pthread.h @@ -0,0 +1,32 @@ +// Filename: pthread.h +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +// This file, and all the other files in this directory, aren't +// intended to be compiled--they're just parsed by CPPParser (and +// interrogate) in lieu of the actual system headers, to generate the +// interrogate database. + +#ifndef PTHREAD_H +#define PTHREAD_H + +typedef int pthread_t; +typedef int pthread_key_t; +typedef int pthread_mutex_t; +typedef int pthread_cond_t; + +#endif diff --git a/panda/src/express/Sources.pp b/panda/src/express/Sources.pp index bc71170bbb..e0c7812139 100644 --- a/panda/src/express/Sources.pp +++ b/panda/src/express/Sources.pp @@ -12,6 +12,7 @@ atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I atomicAdjust.h \ atomicAdjust.I atomicAdjustImpl.h \ atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \ + atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \ atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \ bigEndian.h buffer.I buffer.h \ checksumHashGenerator.I checksumHashGenerator.h circBuffer.I \ @@ -19,6 +20,7 @@ conditionVarDummyImpl.h conditionVarDummyImpl.I conditionVar.h \ conditionVar.I conditionVarImpl.h \ conditionVarNsprImpl.h conditionVarNsprImpl.I \ + conditionVarPosixImpl.h conditionVarPosixImpl.I \ conditionVarWin32Impl.h conditionVarWin32Impl.I \ config_express.h \ datagram.I datagram.h datagramGenerator.I \ @@ -41,6 +43,7 @@ mutexDummyImpl.h mutexDummyImpl.I pmutex.h mutexHolder.h \ mutexHolder.I pmutex.I mutexImpl.h \ mutexNsprImpl.h mutexNsprImpl.I \ + mutexPosixImpl.h mutexPosixImpl.I \ mutexWin32Impl.h mutexWin32Impl.I \ namable.I \ namable.h nativeNumericData.I nativeNumericData.h \ @@ -66,6 +69,7 @@ textEncoder.h textEncoder.I \ threadDummyImpl.h threadDummyImpl.I thread.h thread.I threadImpl.h \ threadNsprImpl.h threadNsprImpl.I \ + threadPosixImpl.h threadPosixImpl.I \ threadWin32Impl.h threadWin32Impl.I \ threadPriority.h \ tokenBoard.I \ @@ -89,10 +93,12 @@ #define INCLUDED_SOURCES \ atomicAdjust.cxx atomicAdjustDummyImpl.cxx \ atomicAdjustNsprImpl.cxx \ + atomicAdjustPosixImpl.cxx \ atomicAdjustWin32Impl.cxx \ buffer.cxx checksumHashGenerator.cxx clockObject.cxx \ conditionVar.cxx conditionVarDummyImpl.cxx \ conditionVarNsprImpl.cxx \ + conditionVarPosixImpl.cxx \ conditionVarWin32Impl.cxx \ config_express.cxx datagram.cxx datagramGenerator.cxx \ datagramIterator.cxx \ @@ -106,6 +112,7 @@ memoryUsagePointers.cxx multifile.cxx \ pmutex.cxx mutexHolder.cxx mutexDummyImpl.cxx \ mutexNsprImpl.cxx \ + mutexPosixImpl.cxx \ mutexWin32Impl.cxx \ namable.cxx \ nativeNumericData.cxx \ @@ -129,6 +136,7 @@ textEncoder.cxx \ thread.cxx threadDummyImpl.cxx \ threadNsprImpl.cxx \ + threadPosixImpl.cxx \ threadWin32Impl.cxx \ trueClock.cxx \ typedReferenceCount.cxx \ @@ -149,6 +157,7 @@ atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I atomicAdjust.h \ atomicAdjust.I atomicAdjustImpl.h \ atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \ + atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \ atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \ bigEndian.h buffer.I buffer.h checksumHashGenerator.I \ checksumHashGenerator.h circBuffer.I circBuffer.h clockObject.I \ @@ -156,6 +165,7 @@ conditionVarDummyImpl.h conditionVarDummyImpl.I conditionVar.h \ conditionVar.I conditionVarImpl.h \ conditionVarNsprImpl.h conditionVarNsprImpl.I \ + conditionVarPosixImpl.h conditionVarPosixImpl.I \ conditionVarWin32Impl.h conditionVarWin32Impl.I \ config_express.h datagram.I datagram.h \ datagramGenerator.I datagramGenerator.h \ @@ -176,6 +186,7 @@ mutexDummyImpl.h mutexDummyImpl.I pmutex.h mutexHolder.h \ mutexHolder.I pmutex.I mutexImpl.h \ mutexNsprImpl.h mutexNsprImpl.I \ + mutexPosixImpl.h mutexPosixImpl.I \ mutexWin32Impl.h mutexWin32Impl.I \ namable.I namable.h \ nativeNumericData.I nativeNumericData.h numeric_types.h \ @@ -200,6 +211,7 @@ textEncoder.h textEncoder.I \ threadDummyImpl.h threadDummyImpl.I thread.h thread.I threadImpl.h \ threadNsprImpl.h threadNsprImpl.I \ + threadPosixImpl.h threadPosixImpl.I \ threadWin32Impl.h threadWin32Impl.I \ threadPriority.h \ tokenBoard.I \ diff --git a/panda/src/express/atomicAdjust.I b/panda/src/express/atomicAdjust.I index 048eb2c6dc..cd248dbdca 100644 --- a/panda/src/express/atomicAdjust.I +++ b/panda/src/express/atomicAdjust.I @@ -23,8 +23,8 @@ // Description: Atomically increments the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjust:: -inc(int &var) { +INLINE PN_int32 AtomicAdjust:: +inc(PN_int32 &var) { return AtomicAdjustImpl::inc(var); } @@ -34,8 +34,8 @@ inc(int &var) { // Description: Atomically decrements the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjust:: -dec(int &var) { +INLINE PN_int32 AtomicAdjust:: +dec(PN_int32 &var) { return AtomicAdjustImpl::dec(var); } @@ -45,7 +45,7 @@ dec(int &var) { // Description: Atomically changes the indicated variable and // returns the original value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjust:: -set(int &var, int new_value) { +INLINE PN_int32 AtomicAdjust:: +set(PN_int32 &var, PN_int32 new_value) { return AtomicAdjustImpl::set(var, new_value); } diff --git a/panda/src/express/atomicAdjust.h b/panda/src/express/atomicAdjust.h index e262af2222..a6333305b6 100644 --- a/panda/src/express/atomicAdjust.h +++ b/panda/src/express/atomicAdjust.h @@ -21,6 +21,7 @@ #include "pandabase.h" #include "atomicAdjustImpl.h" +#include "numeric_types.h" //////////////////////////////////////////////////////////////////// // Class : AtomicAdjust @@ -31,9 +32,9 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAEXPRESS AtomicAdjust { public: - INLINE static int inc(int &var); - INLINE static int dec(int &var); - INLINE static int set(int &var, int new_value); + 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); }; #include "atomicAdjust.I" diff --git a/panda/src/express/atomicAdjustDummyImpl.I b/panda/src/express/atomicAdjustDummyImpl.I index 8fb885a0a1..19b3d88663 100644 --- a/panda/src/express/atomicAdjustDummyImpl.I +++ b/panda/src/express/atomicAdjustDummyImpl.I @@ -23,8 +23,8 @@ // Description: Atomically increments the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustDummyImpl:: -inc(int &var) { +INLINE PN_int32 AtomicAdjustDummyImpl:: +inc(PN_int32 &var) { return ++var; } @@ -34,8 +34,8 @@ inc(int &var) { // Description: Atomically decrements the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustDummyImpl:: -dec(int &var) { +INLINE PN_int32 AtomicAdjustDummyImpl:: +dec(PN_int32 &var) { return --var; } @@ -45,9 +45,9 @@ dec(int &var) { // Description: Atomically changes the indicated variable and // returns the original value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustDummyImpl:: -set(int &var, int new_value) { - int orig_value = var; +INLINE PN_int32 AtomicAdjustDummyImpl:: +set(PN_int32 &var, PN_int32 new_value) { + PN_int32 orig_value = var; var = new_value; return orig_value; } diff --git a/panda/src/express/atomicAdjustDummyImpl.h b/panda/src/express/atomicAdjustDummyImpl.h index 406853f432..f1ad6958b0 100644 --- a/panda/src/express/atomicAdjustDummyImpl.h +++ b/panda/src/express/atomicAdjustDummyImpl.h @@ -23,7 +23,9 @@ #include "selectThreadImpl.h" #ifdef THREAD_DUMMY_IMPL + #include "notify.h" +#include "numeric_types.h" //////////////////////////////////////////////////////////////////// // Class : AtomicAdjustDummyImpl @@ -33,9 +35,9 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAEXPRESS AtomicAdjustDummyImpl { public: - INLINE static int inc(int &var); - INLINE static int dec(int &var); - INLINE static int set(int &var, int new_value); + 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); }; #include "atomicAdjustDummyImpl.I" diff --git a/panda/src/express/atomicAdjustImpl.h b/panda/src/express/atomicAdjustImpl.h index ddec8f6068..9c968f62d9 100644 --- a/panda/src/express/atomicAdjustImpl.h +++ b/panda/src/express/atomicAdjustImpl.h @@ -32,6 +32,11 @@ typedef AtomicAdjustDummyImpl AtomicAdjustImpl; #include "atomicAdjustWin32Impl.h" typedef AtomicAdjustWin32Impl AtomicAdjustImpl; +#elif defined(THREAD_POSIX_IMPL) + +#include "atomicAdjustPosixImpl.h" +typedef AtomicAdjustPosixImpl AtomicAdjustImpl; + #elif defined(THREAD_NSPR_IMPL) #include "atomicAdjustNsprImpl.h" diff --git a/panda/src/express/atomicAdjustNsprImpl.I b/panda/src/express/atomicAdjustNsprImpl.I index d463dfb896..6d3d4cc725 100644 --- a/panda/src/express/atomicAdjustNsprImpl.I +++ b/panda/src/express/atomicAdjustNsprImpl.I @@ -23,8 +23,8 @@ // Description: Atomically increments the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustNsprImpl:: -inc(int &var) { +INLINE PN_int32 AtomicAdjustNsprImpl:: +inc(PN_int32 &var) { return PR_AtomicIncrement(&var); } @@ -34,8 +34,8 @@ inc(int &var) { // Description: Atomically decrements the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustNsprImpl:: -dec(int &var) { +INLINE PN_int32 AtomicAdjustNsprImpl:: +dec(PN_int32 &var) { return PR_AtomicDecrement(&var); } @@ -45,7 +45,7 @@ dec(int &var) { // Description: Atomically changes the indicated variable and // returns the original value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustNsprImpl:: -set(int &var, int new_value) { +INLINE PN_int32 AtomicAdjustNsprImpl:: +set(PN_int32 &var, PN_int32 new_value) { return PR_AtomicSet(&var, new_value); } diff --git a/panda/src/express/atomicAdjustNsprImpl.h b/panda/src/express/atomicAdjustNsprImpl.h index 7b7ddb9188..759d1844f5 100644 --- a/panda/src/express/atomicAdjustNsprImpl.h +++ b/panda/src/express/atomicAdjustNsprImpl.h @@ -25,6 +25,7 @@ #ifdef THREAD_NSPR_IMPL #include "notify.h" +#include "numeric_types.h" #include @@ -34,9 +35,9 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAEXPRESS AtomicAdjustNsprImpl { public: - INLINE static int inc(int &var); - INLINE static int dec(int &var); - INLINE static int set(int &var, int new_value); + 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); }; #include "atomicAdjustNsprImpl.I" diff --git a/panda/src/express/atomicAdjustPosixImpl.I b/panda/src/express/atomicAdjustPosixImpl.I new file mode 100644 index 0000000000..1885750f2f --- /dev/null +++ b/panda/src/express/atomicAdjustPosixImpl.I @@ -0,0 +1,61 @@ +// Filename: atomicAdjustPosixImpl.I +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: AtomicAdjustPosixImpl::inc +// Access: Public, Static +// Description: Atomically increments the indicated variable and +// returns the new value. +//////////////////////////////////////////////////////////////////// +INLINE PN_int32 AtomicAdjustPosixImpl:: +inc(PN_int32 &var) { + pthread_mutex_lock(&_mutex); + PN_int32 result = ++var; + pthread_mutex_unlock(&_mutex); + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: AtomicAdjustPosixImpl::dec +// Access: Public, Static +// Description: Atomically decrements the indicated variable and +// returns the new value. +//////////////////////////////////////////////////////////////////// +INLINE PN_int32 AtomicAdjustPosixImpl:: +dec(PN_int32 &var) { + pthread_mutex_lock(&_mutex); + PN_int32 result = --var; + pthread_mutex_unlock(&_mutex); + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: AtomicAdjustPosixImpl::set +// Access: Public, Static +// Description: Atomically changes the indicated variable and +// returns the original value. +//////////////////////////////////////////////////////////////////// +INLINE PN_int32 AtomicAdjustPosixImpl:: +set(PN_int32 &var, PN_int32 new_value) { + pthread_mutex_lock(&_mutex); + PN_int32 orig_value = var; + var = new_value; + pthread_mutex_unlock(&_mutex); + return orig_value; +} diff --git a/panda/src/express/atomicAdjustPosixImpl.cxx b/panda/src/express/atomicAdjustPosixImpl.cxx new file mode 100644 index 0000000000..e884808195 --- /dev/null +++ b/panda/src/express/atomicAdjustPosixImpl.cxx @@ -0,0 +1,27 @@ +// Filename: atomicAdjustPosixImpl.cxx +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "atomicAdjustPosixImpl.h" + +pthread_mutex_t AtomicAdjustPosixImpl::_mutex = PTHREAD_MUTEX_INITIALIZER; + +#endif // THREAD_POSIX_IMPL diff --git a/panda/src/express/atomicAdjustPosixImpl.h b/panda/src/express/atomicAdjustPosixImpl.h new file mode 100644 index 0000000000..4a0564edf6 --- /dev/null +++ b/panda/src/express/atomicAdjustPosixImpl.h @@ -0,0 +1,50 @@ +// Filename: atomicAdjustPosixImpl.h +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef ATOMICADJUSTPOSIXIMPL_H +#define ATOMICADJUSTPOSIXIMPL_H + +#include "pandabase.h" +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "notify.h" +#include "numeric_types.h" + +#include + +//////////////////////////////////////////////////////////////////// +// Class : AtomicAdjustPosixImpl +// Description : Uses POSIX to implement atomic adjustments. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEXPRESS AtomicAdjustPosixImpl { +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); + +private: + static pthread_mutex_t _mutex; +}; + +#include "atomicAdjustPosixImpl.I" + +#endif // THREAD_POSIX_IMPL + +#endif diff --git a/panda/src/express/atomicAdjustWin32Impl.I b/panda/src/express/atomicAdjustWin32Impl.I index 29e44105f3..0ba05652e8 100644 --- a/panda/src/express/atomicAdjustWin32Impl.I +++ b/panda/src/express/atomicAdjustWin32Impl.I @@ -23,9 +23,8 @@ // Description: Atomically increments the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustWin32Impl:: -inc(int &var) { - nassertr(sizeof(int) == sizeof(LONG), ++var); +INLINE PN_int32 AtomicAdjustWin32Impl:: +inc(PN_int32 &var) { return InterlockedIncrement((LONG *)&var); } @@ -35,9 +34,8 @@ inc(int &var) { // Description: Atomically decrements the indicated variable and // returns the new value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustWin32Impl:: -dec(int &var) { - nassertr(sizeof(int) == sizeof(LONG), --var); +INLINE PN_int32 AtomicAdjustWin32Impl:: +dec(PN_int32 &var) { return InterlockedDecrement((LONG *)&var); } @@ -47,14 +45,7 @@ dec(int &var) { // Description: Atomically changes the indicated variable and // returns the original value. //////////////////////////////////////////////////////////////////// -INLINE int AtomicAdjustWin32Impl:: -set(int &var, int new_value) { -#ifndef NDEBUG - nassertd(sizeof(int) == sizeof(LONG)) { - int temp = var; - var = new_value; - return temp; - } -#endif +INLINE PN_int32 AtomicAdjustWin32Impl:: +set(PN_int32 &var, PN_int32 new_value) { return InterlockedExchange((LONG *)&var, new_value); } diff --git a/panda/src/express/atomicAdjustWin32Impl.h b/panda/src/express/atomicAdjustWin32Impl.h index d079ad1b52..fe9a7bfcb3 100644 --- a/panda/src/express/atomicAdjustWin32Impl.h +++ b/panda/src/express/atomicAdjustWin32Impl.h @@ -25,6 +25,7 @@ #ifdef THREAD_WIN32_IMPL #include "notify.h" +#include "numeric_types.h" #include @@ -35,9 +36,9 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDAEXPRESS AtomicAdjustWin32Impl { public: - INLINE static int inc(int &var); - INLINE static int dec(int &var); - INLINE static int set(int &var, int new_value); + 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); }; #include "atomicAdjustWin32Impl.I" diff --git a/panda/src/express/conditionVarImpl.h b/panda/src/express/conditionVarImpl.h index 52ac578762..fb449f552d 100644 --- a/panda/src/express/conditionVarImpl.h +++ b/panda/src/express/conditionVarImpl.h @@ -32,6 +32,11 @@ typedef ConditionVarDummyImpl ConditionVarImpl; #include "conditionVarWin32Impl.h" typedef ConditionVarWin32Impl ConditionVarImpl; +#elif defined(THREAD_POSIX_IMPL) + +#include "conditionVarPosixImpl.h" +typedef ConditionVarPosixImpl ConditionVarImpl; + #elif defined(THREAD_NSPR_IMPL) #include "conditionVarNsprImpl.h" diff --git a/panda/src/express/conditionVarPosixImpl.I b/panda/src/express/conditionVarPosixImpl.I new file mode 100644 index 0000000000..a7171b60c4 --- /dev/null +++ b/panda/src/express/conditionVarPosixImpl.I @@ -0,0 +1,64 @@ +// Filename: conditionVarPosixImpl.I +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ConditionVarPosixImpl::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConditionVarPosixImpl:: +ConditionVarPosixImpl(MutexPosixImpl &mutex) : + _mutex(mutex) +{ + int result = pthread_cond_init(&_cvar, NULL); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConditionVarPosixImpl::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ConditionVarPosixImpl:: +~ConditionVarPosixImpl() { + int result = pthread_cond_destroy(&_cvar); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConditionVarPosixImpl::wait +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ConditionVarPosixImpl:: +wait() { + int result = pthread_cond_wait(&_cvar, &_mutex._lock); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ConditionVarPosixImpl::signal +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ConditionVarPosixImpl:: +signal() { + int result = pthread_cond_signal(&_cvar); + nassertv(result == 0); +} diff --git a/panda/src/express/conditionVarPosixImpl.cxx b/panda/src/express/conditionVarPosixImpl.cxx new file mode 100644 index 0000000000..495b0cc94d --- /dev/null +++ b/panda/src/express/conditionVarPosixImpl.cxx @@ -0,0 +1,25 @@ +// Filename: conditionVarPosixImpl.cxx +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "selectThreadImpl.h" + +#ifdef THREAD_NSPR_IMPL + +#include "conditionVarNsprImpl.h" + +#endif // THREAD_NSPR_IMPL diff --git a/panda/src/express/conditionVarPosixImpl.h b/panda/src/express/conditionVarPosixImpl.h new file mode 100644 index 0000000000..30487dfc8d --- /dev/null +++ b/panda/src/express/conditionVarPosixImpl.h @@ -0,0 +1,55 @@ +// Filename: conditionVarPosixImpl.h +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef CONDITIONVARPOSIXIMPL_H +#define CONDITIONVARPOSIXIMPL_H + +#include "pandabase.h" +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "mutexPosixImpl.h" +#include "notify.h" + +#include + +class MutexPosixImpl; + +//////////////////////////////////////////////////////////////////// +// Class : ConditionVarPosixImpl +// Description : Uses Posix threads to implement a conditionVar. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEXPRESS ConditionVarPosixImpl { +public: + INLINE ConditionVarPosixImpl(MutexPosixImpl &mutex); + INLINE ~ConditionVarPosixImpl(); + + INLINE void wait(); + INLINE void signal(); + +private: + MutexPosixImpl &_mutex; + pthread_cond_t _cvar; +}; + +#include "conditionVarPosixImpl.I" + +#endif // THREAD_POSIX_IMPL + +#endif diff --git a/panda/src/express/express_composite1.cxx b/panda/src/express/express_composite1.cxx index 611df7c919..9e3943067f 100644 --- a/panda/src/express/express_composite1.cxx +++ b/panda/src/express/express_composite1.cxx @@ -1,6 +1,7 @@ #include "atomicAdjust.cxx" #include "atomicAdjustDummyImpl.cxx" #include "atomicAdjustNsprImpl.cxx" +#include "atomicAdjustPosixImpl.cxx" #include "atomicAdjustWin32Impl.cxx" #include "buffer.cxx" #include "checksumHashGenerator.cxx" @@ -8,6 +9,7 @@ #include "conditionVar.cxx" #include "conditionVarDummyImpl.cxx" #include "conditionVarNsprImpl.cxx" +#include "conditionVarPosixImpl.cxx" #include "conditionVarWin32Impl.cxx" #include "config_express.cxx" #include "datagram.cxx" @@ -30,6 +32,7 @@ #include "mutexHolder.cxx" #include "mutexDummyImpl.cxx" #include "mutexNsprImpl.cxx" +#include "mutexPosixImpl.cxx" #include "mutexWin32Impl.cxx" #include "namable.cxx" #include "nativeNumericData.cxx" diff --git a/panda/src/express/express_composite2.cxx b/panda/src/express/express_composite2.cxx index d951108dc5..a3f64bae9b 100644 --- a/panda/src/express/express_composite2.cxx +++ b/panda/src/express/express_composite2.cxx @@ -21,6 +21,7 @@ #include "thread.cxx" #include "threadDummyImpl.cxx" #include "threadNsprImpl.cxx" +#include "threadPosixImpl.cxx" #include "threadWin32Impl.cxx" #include "trueClock.cxx" #include "typedReferenceCount.cxx" diff --git a/panda/src/express/mutexImpl.h b/panda/src/express/mutexImpl.h index 6128c86a65..bb4e0284c3 100644 --- a/panda/src/express/mutexImpl.h +++ b/panda/src/express/mutexImpl.h @@ -26,19 +26,27 @@ #include "mutexDummyImpl.h" typedef MutexDummyImpl MutexImpl; -#undef MUTEX_REENTRANT +#undef HAVE_REMUTEXIMPL #elif defined(THREAD_WIN32_IMPL) #include "mutexWin32Impl.h" typedef MutexWin32Impl MutexImpl; -#define MUTEX_REENTRANT 1 // Win32 Mutexes are already reentrant. +typedef MutexWin32Impl ReMutexImpl; // Win32 Mutexes are always reentrant. +#define HAVE_REMUTEXIMPL 1 + +#elif defined(THREAD_POSIX_IMPL) + +#include "mutexPosixImpl.h" +typedef MutexPosixImpl MutexImpl; +typedef ReMutexPosixImpl ReMutexImpl; +#define HAVE_REMUTEXIMPL 1 #elif defined(THREAD_NSPR_IMPL) #include "mutexNsprImpl.h" typedef MutexNsprImpl MutexImpl; -#undef MUTEX_REENTRANT +#undef HAVE_REMUTEXIMPL #endif diff --git a/panda/src/express/mutexPosixImpl.I b/panda/src/express/mutexPosixImpl.I new file mode 100644 index 0000000000..9b0fa4b793 --- /dev/null +++ b/panda/src/express/mutexPosixImpl.I @@ -0,0 +1,114 @@ +// Filename: mutexPosixImpl.I +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: MutexPosixImpl::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE MutexPosixImpl:: +MutexPosixImpl() { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + int result = pthread_mutex_init(&_lock, &attr); + pthread_mutexattr_destroy(&attr); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MutexPosixImpl::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE MutexPosixImpl:: +~MutexPosixImpl() { + int result = pthread_mutex_destroy(&_lock); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MutexPosixImpl::lock +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void MutexPosixImpl:: +lock() { + int result = pthread_mutex_lock(&_lock); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MutexPosixImpl::release +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void MutexPosixImpl:: +release() { + int result = pthread_mutex_unlock(&_lock); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ReMutexPosixImpl::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ReMutexPosixImpl:: +ReMutexPosixImpl() { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + int result = pthread_mutex_init(&_lock, &attr); + pthread_mutexattr_destroy(&attr); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ReMutexPosixImpl::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ReMutexPosixImpl:: +~ReMutexPosixImpl() { + int result = pthread_mutex_destroy(&_lock); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ReMutexPosixImpl::lock +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ReMutexPosixImpl:: +lock() { + int result = pthread_mutex_lock(&_lock); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ReMutexPosixImpl::release +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ReMutexPosixImpl:: +release() { + int result = pthread_mutex_unlock(&_lock); + nassertv(result == 0); +} diff --git a/panda/src/express/mutexPosixImpl.cxx b/panda/src/express/mutexPosixImpl.cxx new file mode 100644 index 0000000000..ce93f2160d --- /dev/null +++ b/panda/src/express/mutexPosixImpl.cxx @@ -0,0 +1,25 @@ +// Filename: mutexPosixImpl.cxx +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "mutexPosixImpl.h" + +#endif // THREAD_POSIX_IMPL diff --git a/panda/src/express/mutexPosixImpl.h b/panda/src/express/mutexPosixImpl.h new file mode 100644 index 0000000000..e2460e9a65 --- /dev/null +++ b/panda/src/express/mutexPosixImpl.h @@ -0,0 +1,68 @@ +// Filename: mutexPosixImpl.h +// Created by: drose (10Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef MUTEXPOSIXIMPL_H +#define MUTEXPOSIXIMPL_H + +#include "pandabase.h" +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "notify.h" + +#include + +//////////////////////////////////////////////////////////////////// +// Class : MutexPosixImpl +// Description : Uses Posix threads to implement a mutex. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEXPRESS MutexPosixImpl { +public: + INLINE MutexPosixImpl(); + INLINE ~MutexPosixImpl(); + + INLINE void lock(); + INLINE void release(); + +private: + pthread_mutex_t _lock; + friend class ConditionVarPosixImpl; +}; + +//////////////////////////////////////////////////////////////////// +// Class : ReMutexPosixImpl +// Description : Uses Posix threads to implement a reentrant mutex. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEXPRESS ReMutexPosixImpl { +public: + INLINE ReMutexPosixImpl(); + INLINE ~ReMutexPosixImpl(); + + INLINE void lock(); + INLINE void release(); + +private: + pthread_mutex_t _lock; +}; + +#include "mutexPosixImpl.I" + +#endif // THREAD_POSIX_IMPL + +#endif diff --git a/panda/src/express/reMutex.I b/panda/src/express/reMutex.I index c1446b2892..6131852225 100644 --- a/panda/src/express/reMutex.I +++ b/panda/src/express/reMutex.I @@ -17,10 +17,9 @@ //////////////////////////////////////////////////////////////////// -#ifdef MUTEX_REENTRANT +#ifdef HAVE_REMUTEXIMPL // In this branch, the ReMutex class is implemented as a thin wrapper -// around the native MutexImpl class (which is already reentrant -// anyway). +// around the native ReMutexImpl class. //////////////////////////////////////////////////////////////////// // Function: ReMutex::Constructor diff --git a/panda/src/express/reMutex.cxx b/panda/src/express/reMutex.cxx index 80301fe379..64fa234a1d 100644 --- a/panda/src/express/reMutex.cxx +++ b/panda/src/express/reMutex.cxx @@ -18,7 +18,7 @@ #include "reMutex.h" -#ifndef MUTEX_REENTRANT +#ifndef HAVE_REMUTEXIMPL // Most of the methods in this class are stubbed out in the // THREAD_DUMMY_IMPL case, especially when CHECK_REENTRANT_MUTEX is @@ -81,4 +81,5 @@ do_release() { #endif // !THREAD_DUMMY_IMPL || CHECK_REENTRANT_MUTEX -#endif // MUTEX_REENTRANT +#endif // !HAVE_REMUTEXIMPL + diff --git a/panda/src/express/reMutex.h b/panda/src/express/reMutex.h index cc3874e3f1..e6bdcea512 100644 --- a/panda/src/express/reMutex.h +++ b/panda/src/express/reMutex.h @@ -47,10 +47,10 @@ public: INLINE bool debug_is_locked() const; private: -#ifdef MUTEX_REENTRANT - // If the native Mutex implementation is already reentrant, just use - // that. - MutexImpl _impl; +#ifdef HAVE_REMUTEXIMPL + // If the native Mutex implementation provides a reentrant flavor, + // just use that. + ReMutexImpl _impl; #elif !defined(THREAD_DUMMY_IMPL) || defined(CHECK_REENTRANT_MUTEX) void do_lock(); diff --git a/panda/src/express/referenceCount.h b/panda/src/express/referenceCount.h index 045101c5d7..45d642b1b0 100644 --- a/panda/src/express/referenceCount.h +++ b/panda/src/express/referenceCount.h @@ -25,6 +25,7 @@ #include "memoryUsage.h" #include "config_express.h" #include "atomicAdjust.h" +#include "numeric_types.h" #include @@ -81,7 +82,7 @@ private: deleted_ref_count = -100, }; - int _ref_count; + PN_int32 _ref_count; WeakReferenceList *_weak_list; public: diff --git a/panda/src/express/selectThreadImpl.h b/panda/src/express/selectThreadImpl.h index 5f8d4726ed..87e8c6c557 100644 --- a/panda/src/express/selectThreadImpl.h +++ b/panda/src/express/selectThreadImpl.h @@ -36,7 +36,11 @@ // In Windows, use the native threading library. #define THREAD_WIN32_IMPL 1 -#define THREAD_NSPR_IMPL 1 // Temp while developing. + +#elif defined(HAVE_POSIX_THREADS) + +// Posix threads are nice. +#define THREAD_POSIX_IMPL 1 #elif defined(HAVE_NSPR) diff --git a/panda/src/express/thread.h b/panda/src/express/thread.h index 3a0bf4612c..8860b03415 100644 --- a/panda/src/express/thread.h +++ b/panda/src/express/thread.h @@ -115,8 +115,9 @@ private: static TypeHandle _type_handle; friend class ThreadDummyImpl; - friend class ThreadNsprImpl; friend class ThreadWin32Impl; + friend class ThreadPosixImpl; + friend class ThreadNsprImpl; }; INLINE ostream &operator << (ostream &out, const Thread &thread); diff --git a/panda/src/express/threadImpl.h b/panda/src/express/threadImpl.h index 6d7596b3a7..45925fb9b4 100644 --- a/panda/src/express/threadImpl.h +++ b/panda/src/express/threadImpl.h @@ -32,6 +32,11 @@ typedef ThreadDummyImpl ThreadImpl; #include "threadWin32Impl.h" typedef ThreadWin32Impl ThreadImpl; +#elif defined(THREAD_POSIX_IMPL) + +#include "threadPosixImpl.h" +typedef ThreadPosixImpl ThreadImpl; + #elif defined(THREAD_NSPR_IMPL) #include "threadNsprImpl.h" diff --git a/panda/src/express/threadPosixImpl.I b/panda/src/express/threadPosixImpl.I new file mode 100644 index 0000000000..6ea6c74071 --- /dev/null +++ b/panda/src/express/threadPosixImpl.I @@ -0,0 +1,93 @@ +// Filename: threadPosixImpl.I +// Created by: drose (09Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ThreadPosixImpl:: +ThreadPosixImpl(Thread *parent_obj) : + _parent_obj(parent_obj) +{ + _joinable = false; + _detached = false; + _status = S_new; +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::prepare_for_exit +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ThreadPosixImpl:: +prepare_for_exit() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::get_current_thread +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Thread *ThreadPosixImpl:: +get_current_thread() { + if (!_got_pt_ptr_index) { + init_pt_ptr_index(); + } + return (Thread *)pthread_getspecific(_pt_ptr_index); +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::bind_thread +// Access: Public, Static +// Description: Associates the indicated Thread object with the +// currently-executing thread. You should not call this +// directly; use Thread::bind_thread() instead. +//////////////////////////////////////////////////////////////////// +INLINE void ThreadPosixImpl:: +bind_thread(Thread *thread) { + if (!_got_pt_ptr_index) { + init_pt_ptr_index(); + } + int result = pthread_setspecific(_pt_ptr_index, thread); + nassertv(result == 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::is_threading_supported +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool ThreadPosixImpl:: +is_threading_supported() { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::sleep +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void ThreadPosixImpl:: +sleep(double seconds) { + struct timespec rqtp; + rqtp.tv_sec = time_t(seconds); + rqtp.tv_nsec = long((seconds - (double)rqtp.tv_sec) * 1000000000.0); + nanosleep(&rqtp, NULL); +} diff --git a/panda/src/express/threadPosixImpl.cxx b/panda/src/express/threadPosixImpl.cxx new file mode 100644 index 0000000000..54212a1f59 --- /dev/null +++ b/panda/src/express/threadPosixImpl.cxx @@ -0,0 +1,231 @@ +// Filename: threadPosixImpl.cxx +// Created by: drose (09Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "threadPosixImpl.h" +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "pointerTo.h" +#include "config_express.h" +#include "mutexHolder.h" + +#include + +pthread_key_t ThreadPosixImpl::_pt_ptr_index = 0; +bool ThreadPosixImpl::_got_pt_ptr_index = false; + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +ThreadPosixImpl:: +~ThreadPosixImpl() { + if (thread_cat.is_debug()) { + thread_cat.debug() + << "Deleting thread " << _parent_obj->get_name() << "\n"; + } + + MutexHolder holder(_mutex); + + if (!_detached) { + pthread_detach(_thread); + _detached = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::start +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +bool ThreadPosixImpl:: +start(ThreadPriority priority, bool global, bool joinable) { + MutexHolder holder(_mutex); + if (thread_cat.is_debug()) { + thread_cat.debug() << "Starting thread " << _parent_obj->get_name() << "\n"; + } + + nassertr(_status == S_new, false); + _joinable = joinable; + _status = S_start_called; + _detached = false; + + if (!_got_pt_ptr_index) { + init_pt_ptr_index(); + } + + pthread_attr_t attr; + pthread_attr_init(&attr); + + if (!_joinable) { + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + _detached = true; + } + + struct sched_param param; + int current_policy; + int result = pthread_attr_getschedpolicy(&attr, ¤t_policy); + if (result != 0) { + thread_cat.warning() + << "Unable to query scheduling policy.\n"; + + } else { + int result = 0; + switch (priority) { + case TP_low: + param.sched_priority = sched_get_priority_min(current_policy); + result = pthread_attr_setschedparam(&attr, ¶m); + break; + + case TP_high: + case TP_urgent: + param.sched_priority = sched_get_priority_max(current_policy); + result = pthread_attr_setschedparam(&attr, ¶m); + break; + + case TP_normal: + default: + break; + } + + if (result != 0) { + thread_cat.warning() + << "Unable to specify thread priority.\n"; + } + } + + // Increment the parent object's reference count first. The thread + // will eventually decrement it when it terminates. + _parent_obj->ref(); + result = pthread_create(&_thread, &attr, &root_func, (void *)this); + + pthread_attr_destroy(&attr); + + if (result != 0) { + // Oops, we couldn't start the thread. Be sure to decrement the + // reference count we incremented above, and return false to + // indicate failure. + unref_delete(_parent_obj); + return false; + } + + // Thread was successfully started. + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::interrupt +// Access: Public +// Description: Sends an interrupt message to the thread. This will +// interrupt any blocking-type system calls the thread +// may be waiting on, such as I/O, so that the thread +// may continue some other processing. The specific +// behavior is implementation dependent. +//////////////////////////////////////////////////////////////////// +void ThreadPosixImpl:: +interrupt() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::join +// Access: Public +// Description: Blocks the calling process until the thread +// terminates. If the thread has already terminated, +// this returns immediately. +//////////////////////////////////////////////////////////////////// +void ThreadPosixImpl:: +join() { + _mutex.lock(); + if (!_detached) { + _mutex.release(); + void *return_val; + pthread_join(_thread, &return_val); + _detached = true; + return; + } + _mutex.release(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::root_func +// Access: Private, Static +// Description: The entry point of each thread. +//////////////////////////////////////////////////////////////////// +void *ThreadPosixImpl:: +root_func(void *data) { + ThreadPosixImpl *self = (ThreadPosixImpl *)data; + int result = pthread_setspecific(_pt_ptr_index, self->_parent_obj); + nassertr(result == 0, NULL); + + { + MutexHolder holder(self->_mutex); + nassertr(self->_status == S_start_called, NULL); + self->_status = S_running; + } + + self->_parent_obj->thread_main(); + + if (thread_cat.is_debug()) { + thread_cat.debug() + << "Terminating thread " << self->_parent_obj->get_name() + << ", count = " << self->_parent_obj->get_ref_count() << "\n"; + } + + { + MutexHolder holder(self->_mutex); + nassertr(self->_status == S_running, NULL); + self->_status = S_finished; + } + + // Now drop the parent object reference that we grabbed in start(). + // This might delete the parent object, and in turn, delete the + // ThreadPosixImpl object. + unref_delete(self->_parent_obj); + + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: ThreadPosixImpl::init_pt_ptr_index +// Access: Private, Static +// Description: Allocate a new index to store the Thread parent +// pointer as a piece of per-thread private data. +//////////////////////////////////////////////////////////////////// +void ThreadPosixImpl:: +init_pt_ptr_index() { + nassertv(!_got_pt_ptr_index); + + int result = pthread_key_create(&_pt_ptr_index, NULL); + if (result != 0) { + thread_cat.error() + << "Unable to associate Thread pointers with threads.\n"; + return; + } + + _got_pt_ptr_index = true; + + // Assume that we must be in the main thread, since this method must + // be called before the first thread is spawned. + Thread *main_thread_obj = Thread::get_main_thread(); + result = pthread_setspecific(_pt_ptr_index, main_thread_obj); + nassertv(result == 0); +} + +#endif // THREAD_POSIX_IMPL diff --git a/panda/src/express/threadPosixImpl.h b/panda/src/express/threadPosixImpl.h new file mode 100644 index 0000000000..6a7dd79d8b --- /dev/null +++ b/panda/src/express/threadPosixImpl.h @@ -0,0 +1,81 @@ +// Filename: threadPosixImpl.h +// Created by: drose (09Feb06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef THREADPOSIXIMPL_H +#define THREADPOSIXIMPL_H + +#include "pandabase.h" +#include "selectThreadImpl.h" + +#ifdef THREAD_POSIX_IMPL + +#include "notify.h" +#include "threadPriority.h" +#include "pmutex.h" + +#include + +class Thread; + +//////////////////////////////////////////////////////////////////// +// Class : ThreadPosixImpl +// Description : Uses Posix threads to implement a thread. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEXPRESS ThreadPosixImpl { +public: + INLINE ThreadPosixImpl(Thread *parent_obj); + ~ThreadPosixImpl(); + + bool start(ThreadPriority priority, bool global, bool joinable); + void interrupt(); + void join(); + + INLINE static void prepare_for_exit(); + + INLINE static Thread *get_current_thread(); + INLINE static void bind_thread(Thread *thread); + INLINE static bool is_threading_supported(); + INLINE static void sleep(double seconds); + +private: + static void *root_func(void *data); + static void init_pt_ptr_index(); + + enum Status { + S_new, + S_start_called, + S_running, + S_finished, + }; + + Mutex _mutex; + Thread *_parent_obj; + pthread_t _thread; + bool _joinable; + bool _detached; + Status _status; + + static pthread_key_t _pt_ptr_index; + static bool _got_pt_ptr_index; +}; + +#include "threadPosixImpl.I" + +#endif // THREAD_POSIX_IMPL + +#endif diff --git a/panda/src/putil/cachedTypedWritableReferenceCount.h b/panda/src/putil/cachedTypedWritableReferenceCount.h index f72eafc9e8..1cfa803eaa 100644 --- a/panda/src/putil/cachedTypedWritableReferenceCount.h +++ b/panda/src/putil/cachedTypedWritableReferenceCount.h @@ -58,7 +58,7 @@ protected: bool do_test_ref_count_integrity() const; private: - int _cache_ref_count; + PN_int32 _cache_ref_count; public: static TypeHandle get_class_type() { diff --git a/panda/src/putil/nodeCachedReferenceCount.h b/panda/src/putil/nodeCachedReferenceCount.h index c925b88216..9acbd06b5f 100644 --- a/panda/src/putil/nodeCachedReferenceCount.h +++ b/panda/src/putil/nodeCachedReferenceCount.h @@ -72,7 +72,7 @@ protected: bool do_test_ref_count_integrity() const; private: - int _node_ref_count; + PN_int32 _node_ref_count; public: static TypeHandle get_class_type() {