diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 4f0439dfd..230383fd6 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -104,6 +104,7 @@ IF(WIN32) ENDIF(WITH_MFC) ENDIF(WIN32) +FIND_PACKAGE(SDL2 REQUIRED) FIND_PACKAGE(LibXml2 REQUIRED) FIND_PACKAGE(PNG REQUIRED) FIND_PACKAGE(Jpeg) diff --git a/code/CMakeModules/FindSDL2.cmake b/code/CMakeModules/FindSDL2.cmake new file mode 100644 index 000000000..a4698da9b --- /dev/null +++ b/code/CMakeModules/FindSDL2.cmake @@ -0,0 +1,193 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2_main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDL2main.h and SDL2main.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL2 guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL2 convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake +# module with the minor edit of changing "SDL" to "SDL2" where necessary. This +# was not created for redistribution, and exists temporarily pending official +# SDL2 CMake modules. + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt +) + +#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +SET(SDL2_FOUND "NO") +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + IF(WIN32) + SET(SDL2_LIBRARY_TEMP winmm imm32 version msimg32 ${SDL2_LIBRARY_TEMP}) + ENDIF(WIN32) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") + + SET(SDL2_FOUND "YES") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) + +IF(SDL2_STATIC) + if (UNIX AND NOT APPLE) + EXECUTE_PROCESS(COMMAND sdl2-config --static-libs OUTPUT_VARIABLE SDL2_LINK_FLAGS) + STRING(REGEX REPLACE "(\r?\n)+$" "" SDL2_LINK_FLAGS "${SDL2_LINK_FLAGS}") + SET(SDL2_LIBRARY ${SDL2_LINK_FLAGS}) + ENDIF() +ENDIF(SDL2_STATIC) \ No newline at end of file diff --git a/code/nel/include/nel/misc/mutex.h b/code/nel/include/nel/misc/mutex.h index adbc7e7e5..739ea6c97 100644 --- a/code/nel/include/nel/misc/mutex.h +++ b/code/nel/include/nel/misc/mutex.h @@ -22,582 +22,70 @@ #include "common.h" #include -#ifdef NL_OS_WINDOWS -# ifdef NL_NO_ASM -# include -# endif -#elif defined(NL_OS_UNIX) -# include // PThread -# include // PThread POSIX semaphores -# include -# define __forceinline -# ifdef NL_OS_MAC -# include -# endif -#endif // NL_OS_WINDOWS - -#undef MUTEX_DEBUG - +struct SDL_mutex; +typedef int SDL_SpinLock; namespace NLMISC { +#define CFastMutex CAtomicLock +#define CFairMutex CMutex +#define CUnfairMutex CMutex -/* - * This define must be disabled when sharing a mutex between several processes that can - * have a different debug mode (because when __STL_DEBUG is on, sizeof(string) is twice - * the common string size). - */ -#define STORE_MUTEX_NAME - -#ifdef NL_OS_WINDOWS - // By default on Windows, all mutex/synchronization use the CFair* class to avoid freeze problem. -# define CMutex CFairMutex -# define CSynchronized CFairSynchronized -#else - // On GNU/Linux and Mac, we use CUnfair* everwise it creates some strange deadlock during loading and after -# define CMutex CUnfairMutex -# define CSynchronized CUnfairSynchronized -#endif - - -/** - * Classic mutex implementation (not necessarly fair) - * Don't assume the mutex are recursive (ie don't call enter() several times - * on the same mutex from the same thread without having called leave()) ; - * and don't assume either the threads are woken-up in the same order as they - * were put to sleep ! - * - * Windows: uses Mutex, cannot be shared among processes. - * Linux: uses PThread POSIX Mutex, cannot be shared among processes. - * - *\code - CUnfairMutex m; - m.enter (); - // do critical stuffs - m.leave (); - *\endcode - * \author Vianney Lecroart, Olivier Cado - * \author Nevrax France - * \date 2000 - */ -class CUnfairMutex +class CMutex { public: - /// Constructor - CUnfairMutex(); - CUnfairMutex( const std::string &name ); + CMutex(); + CMutex(const std::string &name); /// Destructor - ~CUnfairMutex(); + ~CMutex(); - /// Enter the critical section - void enter (); + /// Enter + void enter(); - /// Leave the critical section - void leave (); + /// Leave + void leave(); private: - -#ifdef NL_OS_WINDOWS - void *_Mutex; -#elif defined NL_OS_UNIX - pthread_mutex_t mutex; -#else -# error "No unfair mutex implementation for this OS" -#endif + SDL_mutex *m_SDLMutex; }; - -// Inline assembler for gcc tutorial: -// AT&T syntax: -// - operands reversed, -// - l after opcode replaces dword ptr, -// - () instead of [], -// - immediate values prefixed by $ - -/* -// Tested: works on multi-processor -#ifdef HAVE_X86_64 -# define ASM_ASWAP_FOR_GCC_XCHG __asm__ volatile( \ - "mov %1, %%rcx;" \ - "mov $1, %%eax;" \ - "xchg %%eax, (%%rcx);" \ - "mov %%eax, %0" \ - : "=m" (result) \ - : "m" (lockPtr) \ - : "eax", "rcx", "memory" ); // force to use registers and memory -#else -# define ASM_ASWAP_FOR_GCC_XCHG __asm__ volatile( \ - "mov %1, %%ecx;" \ - "mov $1, %%eax;" \ - "xchg %%eax, (%%ecx);" \ - "mov %%eax, %0" \ - : "=m" (result) \ - : "m" (lockPtr) \ - : "eax", "ecx", "memory" ); // force to use registers and memory -#endif -*/ - -/* -// Tested: does not work (at least on multi-processor)! (with or without 'lock' prefix) -#define ASM_ASWAP_FOR_GCC_CMPXCHG __asm__ volatile( \ - "mov $1, %%edx;" \ - "mov %1, %%ecx;" \ - "mov (%%ecx), %%eax;" \ - "1:nop;" \ - "lock cmpxchgl %%edx, (%%ecx);" \ - "jne 1b;" \ - "mov %%eax, %0" \ - : "=m" (result) \ - : "m" (lockPtr) \ - : "eax", "ecx", "edx", "memory" ); // force to use registers and memory -*/ - -// Tested: does not work on hyper-threading processors! -/*ASM_ASWAP_FOR_MSVC_CMPXCHG -{ - __asm - { - mov edx,1 - mov ecx,l - mov eax,[ecx] -test_again: - nop - cmpxchg dword ptr [ecx],edx - jne test_again - mov [result],eax - } -}*/ - - -/** - * Fast mutex implementation (not fairly) - * The mutex ARE NOT recursive (ie don't call enter() several times - * on the same mutex from the same thread without having called leave()) ; - * The threads ARE NOT woken-up in the same order as they were put to sleep. - * The threads ARE NOT woken-up using signals but using Sleep(). - * This mutex works but is not optimal for multiprocessors because if the mutex is locked, - * next enter will be sleeped without waiting a little. - * - * Implementation notes: - * - Implementated under WIN32 - * - Other OS use CMutex - * - * Tested: OK on Windows and Linux single & multi-processor - * - *\code - CFastMutex m; - m.enter (); - // do critical stuffs - m.leave (); - *\endcode - * \author Cyril 'Hulud' Corvazier - * \author Olivier Cado - * \author Nevrax France - * \date 2002, 2003 - */ -#if defined(__ppc__) && !defined(NL_OS_MAC) && (GCC_VERSION <= 40100) -# error "no CFastMutex implementation available, try to use GCC >4.0.1" -#endif - - -#ifdef NL_OS_WINDOWS -#pragma managed(push, off) -#endif - -class CFastMutex +class CAtomicLock { public: - /// Constructor - CFastMutex() : _Lock(0) {} - - /// Same as constructor, useful for init in a shared memory block - void init() volatile { _Lock = 0; } - - /// Atomic swap - __forceinline static bool atomic_swap (volatile uint32 *lockPtr) - { - uint32 result; -#ifdef NL_OS_WINDOWS -# ifdef NL_NO_ASM - result = _InterlockedExchange(reinterpret_cast(lockPtr), 1); -# else -# ifdef NL_DEBUG - // Workaround for dumb inlining bug (returning of function goes into the choux): push/pop registers - __asm - { - push eax - push ecx - mov ecx,lockPtr - mov eax,1 - xchg [ecx],eax - mov [result],eax - pop ecx - pop eax - } -# else - __asm - { - mov ecx,lockPtr - mov eax,1 - xchg [ecx],eax - mov [result],eax - } -# endif // NL_DEBUG -# endif // NL_NO_ASM -#elif defined(NL_OS_MAC) - return OSAtomicCompareAndSwap32(0, 1, reinterpret_cast(lockPtr)); -#elif defined(NL_OS_UNIX) - // GCC implements the same functionality using a builtin function - // http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html - // the macro below crashed on Mac OS X 10.6 in a 64bit build -# if (GCC_VERSION > 40100) - // return __sync_bool_compare_and_swap(lockPtr, 0, 1); - result = __sync_val_compare_and_swap(lockPtr, 0, 1); -# else - ASM_ASWAP_FOR_GCC_XCHG -# endif -#endif // NL_OS_WINDOWS - return result != 0; - } - - // Enter critical section - __forceinline void enter () volatile - { - //std::cout << "Entering, Lock=" << _Lock << std::endl; - if (atomic_swap (&_Lock)) - { - // First test - uint i; - for (i = 0 ;; ++i) - { - uint wait_time = i + 6; - - // Increment wait time with a log function - if (wait_time > 27) - wait_time = 27; - - // Sleep - if (wait_time <= 20) - wait_time = 0; - else - wait_time = 1 << (wait_time - 20); - - if (!atomic_swap (&_Lock)) - break; - -#ifdef NL_OS_WINDOWS - nlSleep (wait_time); -#else - //std::cout << "Sleeping i=" << i << std::endl; - usleep( wait_time*1000 ); -#endif - } - } - } - - // Leave critical section - __forceinline void leave () volatile - { - _Lock = 0; - //std::cout << "Leave" << std::endl; - } - -private: - volatile uint32 _Lock; -}; - - -/** - * Fast mutex for multiprocessor implementation (not fairly). - * Used for multiprocessor critical section synchronisation. - * The mutex ARE NOT recursive (ie don't call enter() several times - * on the same mutex from the same thread without having called leave()) ; - * The threads use a spin system to wait a little time before be put to sleep. - * It waits using CPU time. - * - * Implementation notes: - * - Implementated under WIN32 - * - Other OS use CMutex - * - *\code - CFastMutexMP m; - m.enter (); - // do critical stuffs - m.leave (); - *\endcode - * \author Cyril 'Hulud' Corvazier - * \author Olivier Cado - * \author Nevrax France - * \date 2002, 2003 - */ -#ifndef __ppc__ -class CFastMutexMP -{ -public: + CAtomicLock(); - /// Constructor - CFastMutexMP() : _Lock(0) {} + /// Destructor + ~CAtomicLock(); /// Same as constructor, useful for init in a shared memory block - void init() volatile { _Lock = 0; } - - // Enter critical section - __forceinline void enter () volatile - { - //std::cout << "Entering, Lock=" << _Lock << std::endl; - while (CFastMutex::atomic_swap (&_Lock)) - { - static uint last = 0; - static uint _max = 30; - uint spinMax = _max; - uint lastSpins = last; - volatile uint temp = 17; - uint i; - for (i = 0; i < spinMax; ++i) - { - if (i < lastSpins/2 || _Lock) - { - temp *= temp; - temp *= temp; - temp *= temp; - temp *= temp; - } - else - { - if (!CFastMutex::atomic_swap(&_Lock)) - { - last = i; - _max = 1000; - return; - } - } - } - - _max = 30; - - // First test - for (i = 0 ;; ++i) - { - uint wait_time = i + 6; - - // Increment wait time with a log function - if (wait_time > 27) - wait_time = 27; - - // Sleep - if (wait_time <= 20) - wait_time = 0; - else - wait_time = 1 << (wait_time - 20); - - if (!CFastMutex::atomic_swap (&_Lock)) - break; - -#ifdef NL_OS_WINDOWS - nlSleep (wait_time); -#else - //std::cout << "Sleeping i=" << i << std::endl; - usleep( wait_time*1000 ); -#endif - } - } - } - - // Leave critical section - __forceinline void leave () volatile - { - _Lock = 0; - //std::cout << "Leave" << std::endl; - } - -private: - volatile uint32 _Lock; -}; -#endif - - -/** - * Windows: uses Mutex, the handle can't be shared among processes, but - * the mutex still can be be shared by passing a common object name to - * createByName() / createByKey(). Note: the mutex must be explicitely - * destroyed by calling destroy(). - * - * \author Olivier Cado - * \author Nevrax France - * \date 2002 - */ -class CSharedMutex -{ -public: - - /// Constructor (does not create the mutex, see createByName()/createByKey()) - CSharedMutex(); - -#ifdef NL_OS_WINDOWS - /// Create or access an existing mutex (created by another process) with a specific object name. Returns false if it failed. - bool createByName( const char *objectName ); -#else - /// Create (with createNew to true) or access an existing mutex (created by another process) with a specific key. Returns false if it failed. - bool createByKey( int key, bool createNew ); -#endif - - /// Destroy the mutex - void destroy(); + void init(); - /// Enter the critical section - void enter (); + /// Enter + void enter(); - /// Leave the critical section - void leave (); + /// Leave + void leave(); private: + SDL_SpinLock m_SDLSpinLock; -#ifdef NL_OS_WINDOWS - /// The mutex handle - void *_Mutex; -#else - /// The semaphore id - int _SemId; -#endif }; - - -#ifdef NL_OS_WINDOWS -/** - * Trick to avoid including ! - * winbase.h: typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; - * The original RTL_CRITICAL_SECTION is in winnt.h. - */ -struct TNelRtlCriticalSection { - void *DebugInfo; - long LockCount; - long RecursionCount; - void *OwningThread; // from the thread's ClientId->UniqueThread - void *LockSemaphore; - uint32 SpinCount; -}; -#endif // NL_OS_WINDOWS - - -/** - * Kind of "fair" mutex - * - * Windows: uses Critical Section, cannot be shared among processes - * Linux: uses PThread (POSIX) semaphore, cannot be shared among processes - * - *\code - CUnfairMutex m; - m.enter (); - // do critical stuffs - m.leave (); - *\endcode - * \author Olivier Cado - * \author Nevrax France - * \date 2000 - * - *\code - CFairMutex m; - m.enter (); - // do critical stuffs - m.leave (); - *\endcode - * \author Olivier Cado - * \author Nevrax France - * \date 2001 - */ -class CFairMutex -{ -public: - - /// Constructor - CFairMutex(); - CFairMutex(const std::string &name); - - /// Destructor - ~CFairMutex(); - - void enter (); - void leave (); - -#ifdef STORE_MUTEX_NAME - std::string Name; -#endif - -private: - -#ifdef NL_OS_WINDOWS - TNelRtlCriticalSection _Cs; -#elif defined NL_OS_UNIX - sem_t _Sem; -#else -# error "No fair mutex implementation for this OS" -#endif - - -#ifdef MUTEX_DEBUG - // debug stuffs - void debugCreateMutex(); - void debugBeginEnter(); - void debugEndEnter(); - void debugLeave(); - void debugDeleteMutex(); -#endif // MUTEX_DEBUG - -}; - - -/* - * Debug info - */ -#ifdef MUTEX_DEBUG - -struct TMutexLocks -{ - TMutexLocks(uint32 m=0) : TimeToEnter(0), TimeInMutex(0), Nb(0), WaitingMutex(0), MutexNum(m), ThreadHavingTheMutex(0xFFFFFFFF), Dead(false) {} - - uint32 TimeToEnter; // cumulated time blocking on enter - uint32 TimeInMutex; // cumulated time between enter and leave - uint32 Nb; // number of calls of enter - uint32 WaitingMutex; // number of thread that waiting this mutex - sint32 MutexNum; // identifying a mutex - uint ThreadHavingTheMutex; // thread id of the thread that is in this mutex (0xFFFFFFFF if no thread) - bool Dead; // True if the mutex is dead (deleted) - std::string MutexName; // Name of the mutex - - NLMISC::TTicks BeginEnter; - NLMISC::TTicks EndEnter; -}; - -/// Inits the "mutex debugging info system" -void initAcquireTimeMap(); - -/// Gets the debugging info for all mutexes (call it evenly) -std::map getNewAcquireTimes(); - -/// The number of created mutexes (does not take in account the destroyed mutexes) -extern uint32 NbMutexes; - -#endif // MUTEX_DEBUG - - /** * This class ensure that the Value is accessed by only one thread. First you have to create a CSynchronized class with your type. * Then, if a thread want to modify or do anything on it, you create a CAccessor in a \b sub \b scope. You can modify the value - * of the CUnfairSynchronized using the value() function \b until the end of the scope. So you have to put the smaller scope as you can. - * - * Internally, this class uses a CUnfairMutex object (see CUnfairMutex for programming considerations). + * of the CSynchronized using the value() function \b until the end of the scope. So you have to put the smaller scope as you can. * *\code // the value that you want to be thread safe. - CUnfairSynchronized val; + CSynchronized val; { // create a new scope for the access // get an access to the value - CUnfairSynchronized::CAccessor acces(&val); + CSynchronized::CAccessor acces(&val); // now, you have a thread safe access until the end of the scope, so you can do whatever you want. for example, change the value acces.value () = 10; } // end of the access @@ -606,112 +94,65 @@ extern uint32 NbMutexes; * \author Nevrax France * \date 2000 */ -template -class CUnfairSynchronized +template +class CSynchronized { public: - CUnfairSynchronized (const std::string &name) : _Mutex(name) { } + CSynchronized(const std::string &name) : m_Mutex(name) { } /** * This class give you a thread safe access to the CSynchronized Value. Look at the example in the CSynchronized. */ class CAccessor { - CUnfairSynchronized *Synchronized; + CSynchronized *Synchronized; public: /// get the mutex or wait - CAccessor(CUnfairSynchronized *cs) + CAccessor(CSynchronized *cs) { Synchronized = cs; - const_cast(Synchronized->_Mutex).enter(); + const_cast(Synchronized->m_Mutex).enter(); } /// release the mutex ~CAccessor() { - const_cast(Synchronized->_Mutex).leave(); + const_cast(Synchronized->m_Mutex).leave(); } /// access to the Value T &value() { - return const_cast(Synchronized->_Value); + return const_cast(Synchronized->m_Value); } }; private: - friend class CUnfairSynchronized::CAccessor; + friend class CSynchronized::CAccessor; /// The mutex of the synchronized value. - volatile CUnfairMutex _Mutex; + volatile TMutex m_Mutex; /// The synchronized value. - volatile T _Value; + volatile T m_Value; }; - -/** - * This class is similar to CUnfairSynchronized, but it ensures that the threads - * are woken-up in the same order as they were put to sleep. - * Internally, it uses a CFairMutex object instead of a CUnfairMutex object. - * \author Olivier Cado - * \author Nevrax France - * \date 2001 - */ template -class CFairSynchronized -{ -public: - - CFairSynchronized (const std::string &name) : _Cs(name) { } - - /** - * This class give you a thread safe access to the CFairSynchronized Value. Look at the example in CSynchronized. - */ - class CAccessor - { - CFairSynchronized *Synchronized; - public: - - /// get the mutex or wait - CAccessor(CFairSynchronized *cs) - { - Synchronized = cs; - const_cast(Synchronized->_Cs).enter(); - } +class CUnfairSynchronized : public CSynchronized { }; - /// release the mutex - ~CAccessor() - { - const_cast(Synchronized->_Cs).leave(); - } - - /// access to the Value - T &value() - { - return const_cast(Synchronized->_Value); - } - }; - -private: - - friend class CFairSynchronized::CAccessor; - - /// The mutex of the synchronized value. - volatile CFairMutex _Cs; - - /// The synchronized value. - volatile T _Value; -}; +template +class CFairSynchronized : public CSynchronized { }; +template +class CFastSynchronized : public CSynchronized { }; /** Helper class that allow easy usage of mutex to protect * a local block of code with an existing mutex. */ -template +template class CAutoMutex { TMutex &_Mutex; @@ -742,7 +183,6 @@ public: } // NLMISC - #endif // NL_MUTEX_H /* End of mutex.h */ diff --git a/code/nel/include/nel/misc/reader_writer.h b/code/nel/include/nel/misc/reader_writer.h index 70c8d7e52..dc7c7f1b5 100644 --- a/code/nel/include/nel/misc/reader_writer.h +++ b/code/nel/include/nel/misc/reader_writer.h @@ -33,10 +33,10 @@ class CReaderWriter { private: - volatile CMutex _Fairness; - volatile CMutex _ReadersMutex; - volatile CMutex _RWMutex; - volatile sint _ReadersLevel; + volatile CAtomicLock _Fairness; + volatile CAtomicLock _ReadersMutex; + volatile CMutex _RWMutex; + volatile sint _ReadersLevel; public: @@ -45,29 +45,29 @@ public: void enterReader() { - const_cast(_Fairness).enter(); - const_cast(_ReadersMutex).enter(); + const_cast(_Fairness).enter(); + const_cast(_ReadersMutex).enter(); ++_ReadersLevel; if (_ReadersLevel == 1) const_cast(_RWMutex).enter(); - const_cast(_ReadersMutex).leave(); - const_cast(_Fairness).leave(); + const_cast(_ReadersMutex).leave(); + const_cast(_Fairness).leave(); } void leaveReader() { - const_cast(_ReadersMutex).enter(); + const_cast(_ReadersMutex).enter(); --_ReadersLevel; if (_ReadersLevel == 0) const_cast(_RWMutex).leave(); - const_cast(_ReadersMutex).leave(); + const_cast(_ReadersMutex).leave(); } void enterWriter() { - const_cast(_Fairness).enter(); + const_cast(_Fairness).enter(); const_cast(_RWMutex).enter(); - const_cast(_Fairness).leave(); + const_cast(_Fairness).leave(); } void leaveWriter() diff --git a/code/nel/include/nel/sound/stream_source.h b/code/nel/include/nel/sound/stream_source.h index 62c7e2faf..44506a267 100644 --- a/code/nel/include/nel/sound/stream_source.h +++ b/code/nel/include/nel/sound/stream_source.h @@ -164,7 +164,7 @@ protected: IBuffer *m_Buffers[3]; // an array of two pointers /// Mutex for buffer ops. - NLMISC::CMutex m_BufferMutex; + NLMISC::CFastMutex m_BufferMutex; /// The bytes per second according to the buffer format uint m_BytesPerSecond; diff --git a/code/nel/src/misc/CMakeLists.txt b/code/nel/src/misc/CMakeLists.txt index dc5b87e2c..a5d60f0e4 100644 --- a/code/nel/src/misc/CMakeLists.txt +++ b/code/nel/src/misc/CMakeLists.txt @@ -37,9 +37,9 @@ IF(UNIX) ENDIF(NOT APPLE) ENDIF(UNIX) -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${PNG_INCLUDE_DIR} config_file) +INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ${PNG_INCLUDE_DIR} config_file) -TARGET_LINK_LIBRARIES(nelmisc ${CMAKE_THREAD_LIBS_INIT} ${LIBXML2_LIBRARIES}) +TARGET_LINK_LIBRARIES(nelmisc ${SDL2_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${LIBXML2_LIBRARIES}) SET_TARGET_PROPERTIES(nelmisc PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nelmisc "NeL, Library: NeL Misc") NL_ADD_RUNTIME_FLAGS(nelmisc) diff --git a/code/nel/src/misc/app_context.cpp b/code/nel/src/misc/app_context.cpp index a0b35b35a..f931b3f2e 100644 --- a/code/nel/src/misc/app_context.cpp +++ b/code/nel/src/misc/app_context.cpp @@ -19,6 +19,8 @@ #include "nel/misc/dynloadlib.h" #include "nel/misc/command.h" +#include + #ifdef DEBUG_NEW #define new DEBUG_NEW #endif @@ -114,6 +116,13 @@ CApplicationContext::CApplicationContext() DebugNeedAssert = false; NoAssert = false; AlreadyCreateSharedAmongThreads = false; + SDL_Init( + SDL_INIT_TIMER + | SDL_INIT_JOYSTICK + | SDL_INIT_HAPTIC + | SDL_INIT_GAMECONTROLLER + | SDL_INIT_EVENTS); + atexit(SDL_Quit); contextReady(); } diff --git a/code/nel/src/misc/mutex.cpp b/code/nel/src/misc/mutex.cpp index f8a75d2ea..414ec5b28 100644 --- a/code/nel/src/misc/mutex.cpp +++ b/code/nel/src/misc/mutex.cpp @@ -24,692 +24,64 @@ #include "nel/misc/time_nl.h" #include "nel/misc/debug.h" -using namespace std; - -#ifndef MUTEX_DEBUG -#define debugCreateMutex() ; -#define debugBeginEnter() ; -#define debugEndEnter() ; -#define debugLeave() ; -#define debugDeleteMutex() ; -#endif - - -/**************** - * Windows code * - ****************/ - -#ifdef NL_OS_WINDOWS - -// these defines are for IsDebuggerPresent(). It'll not compile on windows 95 -// just comment this and the IsDebuggerPresent to compile on windows 95 -#define _WIN32_WINDOWS 0x0410 -#define WINVER 0x0400 -#define NOMINMAX -#include - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC { - - - -inline void EnterMutex( void *handle ) -{ -#ifdef NL_DEBUG - DWORD timeout; - if ( IsDebuggerPresent() ) - timeout = INFINITE; - else - timeout = 10000; - - // Request ownership of mutex - DWORD dwWaitResult = WaitForSingleObject (handle, timeout); -#else - // Request ownership of mutex during 10s - DWORD dwWaitResult = WaitForSingleObject (handle, 10000); -#endif // NL_DEBUG - switch (dwWaitResult) - { - // The thread got mutex ownership. - case WAIT_OBJECT_0: break; - // Cannot get mutex ownership due to time-out. - case WAIT_TIMEOUT: nlerror ("Dead lock in a mutex (or more that 10s for the critical section"); - // Got ownership of the abandoned mutex object. - case WAIT_ABANDONED: nlerror ("A thread forgot to release the mutex"); - default: nlerror ("EnterMutex failed"); - } -} - - -inline void LeaveMutex( void *handle ) -{ - if (ReleaseMutex(handle) == 0) - { - //LPVOID lpMsgBuf; - //FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - // NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );*/ - nlerror ("error while releasing the mutex (0x%x %d), %p", GetLastError(), GetLastError(), handle); - //LocalFree( lpMsgBuf ); - } -} - - -/////////////////////////// CUnfairMutex - - -/* - * Windows version - */ - -CUnfairMutex::CUnfairMutex() -{ - // Create a mutex with no initial owner. - _Mutex = (void *) CreateMutex( NULL, FALSE, NULL ); - nlassert( _Mutex != NULL ); -} - - -CUnfairMutex::CUnfairMutex( const std::string & /* name */ ) -{ - // Create a mutex with no initial owner. - _Mutex = (void *) CreateMutex( NULL, FALSE, NULL ); - nlassert( _Mutex != NULL ); - - // (Does not use name, only provided for debug compatibility with CFairMutex) -} - - -/* - * Windows version - */ -CUnfairMutex::~CUnfairMutex() -{ - CloseHandle( _Mutex ); -} - - -/* - * Windows version - */ -void CUnfairMutex::enter() -{ - EnterMutex( _Mutex ); -} - - -/* - * Windows version - */ -void CUnfairMutex::leave() -{ - LeaveMutex( _Mutex ); -} - - -/////////////////////////// CSharedMutexW - - -/* - * - */ -CSharedMutex::CSharedMutex() -{ - _Mutex = NULL; -} - - -/* - * Create or use an existing mutex (created by another process) with a specific object name (createNow must be false in the constructor) - * Returns false if it failed. - */ -bool CSharedMutex::createByName( const char *objectName ) -{ -#ifdef NL_DEBUG - nlassert( _Mutex == NULL ); -#endif - _Mutex = (void *) CreateMutex( NULL, FALSE, objectName ); - //nldebug( "Creating mutex %s: handle %p", objectName, _Mutex ); - return ( _Mutex != NULL ); -} - - -/* - * - */ -void CSharedMutex::destroy() -{ - CloseHandle( _Mutex ); - _Mutex = NULL; -} - -/* - * - */ -void CSharedMutex::enter() -{ - EnterMutex( _Mutex ); -} - - -/* - * - */ -void CSharedMutex::leave() -{ - LeaveMutex( _Mutex ); -} - - -/////////////////////////// CFairMutex - - -/* - * Windows version - */ -CFairMutex::CFairMutex() -{ -#ifdef STORE_MUTEX_NAME - Name = "unset mutex name"; -#endif - - debugCreateMutex(); - - // Check that the CRITICAL_SECTION structure has not changed - nlassert( sizeof(TNelRtlCriticalSection)==sizeof(CRITICAL_SECTION) ); - -#if (_WIN32_WINNT >= 0x0500) - DWORD dwSpinCount = 0x80000000; // set high-order bit to use preallocation - if ( ! InitializeCriticalSectionAndSpinCount( (CRITICAL_SECTION*)&_Cs, dwSpinCount ) ) - { - nlerror( "Error entering critical section" ); - } -#else - InitializeCriticalSection( (CRITICAL_SECTION*)&_Cs ); -#endif -} - - -CFairMutex::CFairMutex(const string &name) -{ -#ifdef STORE_MUTEX_NAME - Name = name; -#endif - -#ifdef MUTEX_DEBUG - debugCreateMutex(); -#endif - - // Check that the CRITICAL_SECTION structure has not changed - nlassert( sizeof(TNelRtlCriticalSection)==sizeof(CRITICAL_SECTION) ); - -#if (_WIN32_WINNT >= 0x0500) - DWORD dwSpinCount = 0x80000000; // set high-order bit to use preallocation - if ( ! InitializeCriticalSectionAndSpinCount( (CRITICAL_SECTION*)&_Cs, dwSpinCount ) ) - { - nlerror( "Error entering critical section" ); - } -#else - InitializeCriticalSection( (CRITICAL_SECTION*)&_Cs ); -#endif -} - - - -/* - * Windows version - */ -CFairMutex::~CFairMutex() -{ - DeleteCriticalSection( (CRITICAL_SECTION*)&_Cs ); - - debugDeleteMutex(); -} - - -/* - * Windows version - */ -void CFairMutex::enter() -{ - debugBeginEnter(); - - EnterCriticalSection( (CRITICAL_SECTION*)&_Cs ); - - debugEndEnter(); -} - - -/* - * Windows version - */ -void CFairMutex::leave() -{ - LeaveCriticalSection( (CRITICAL_SECTION*)&_Cs ); - - debugLeave(); -} - -/************* - * Unix code * - *************/ - -#elif defined NL_OS_UNIX - -#include -#include -#include - -#include -#include -#include // System V semaphores - - - -/* - * Clanlib authors say: "We need to do this because the posix threads library - * under linux obviously suck:" - */ -extern "C" -{ - int pthread_mutexattr_setkind_np( pthread_mutexattr_t *attr, int kind ); -} - +#include namespace NLMISC { +// *************************************************************************** -CUnfairMutex::CUnfairMutex() -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init( &attr ); - // Fast mutex. Note: on Windows all mutexes are recursive - pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); - pthread_mutex_init( &mutex, &attr ); - pthread_mutexattr_destroy( &attr ); -} - - -/* - * Unix version - */ -CUnfairMutex::CUnfairMutex(const std::string &name) -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init( &attr ); - // Fast mutex. Note: on Windows all mutexes are recursive - pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); - pthread_mutex_init( &mutex, &attr ); - pthread_mutexattr_destroy( &attr ); -} - - -/* - * Unix version - */ -CUnfairMutex::~CUnfairMutex() +CMutex::CMutex() { - pthread_mutex_destroy( &mutex ); + m_SDLMutex = SDL_CreateMutex(); } - -/* - * Unix version - */ -void CUnfairMutex::enter() +CMutex::CMutex(const std::string &name) { - //cout << getpid() << ": Locking " << &mutex << endl; - if ( pthread_mutex_lock( &mutex ) != 0 ) - { - //cout << "Error locking a mutex " << endl; - nlerror( "Error locking a mutex" ); - } - /*else - { - cout << getpid() << ": Owning " << &mutex << endl; - }*/ + m_SDLMutex = SDL_CreateMutex(); } - -/* - * Unix version - */ -void CUnfairMutex::leave() +CMutex::~CMutex() { - //int errcode; - //cout << getpid() << ": Unlocking " << &mutex << endl; - if ( (/*errcode=*/pthread_mutex_unlock( &mutex )) != 0 ) - { - /* switch ( errcode ) - { - case EINVAL: cout << "INVAL" << endl; break; - case EPERM: cout << "PERM" << endl; break; - default: cout << "OTHER" << endl; - } - */ - //cout << "Error unlocking a mutex " /*<< &mutex*/ << endl; - nlerror( "Error unlocking a mutex" ); - } - /*else - { - cout << getpid() << ": Released " << &mutex << endl; - }*/ + SDL_DestroyMutex(m_SDLMutex); } - -/* - * Unix version - */ -CFairMutex::CFairMutex() +void CMutex::enter() { - sem_init( const_cast(&_Sem), 0, 1 ); + SDL_LockMutex(m_SDLMutex); } - -CFairMutex::CFairMutex( const std::string &name ) +void CMutex::leave() { - sem_init( const_cast(&_Sem), 0, 1 ); + SDL_UnlockMutex(m_SDLMutex); } +// *************************************************************************** -/* - * Unix version - */ -CFairMutex::~CFairMutex() +CAtomicLock::CAtomicLock() : m_SDLSpinLock(0) { - sem_destroy( const_cast(&_Sem) ); // needs that no thread is waiting on the semaphore + } - -/* - * Unix version - */ -void CFairMutex::enter() +CAtomicLock::~CAtomicLock() { - sem_wait( const_cast(&_Sem) ); + } - -/* - * Unix version - */ -void CFairMutex::leave() +void CAtomicLock::init() { - sem_post( const_cast(&_Sem) ); + m_SDLSpinLock = 0; } - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/* - * - */ -CSharedMutex::CSharedMutex() : _SemId(-1) -{} - - - -#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) -/* union semun is defined by including */ -#else -/* according to X/OPEN we have to define it ourselves */ -union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ - unsigned short int *array; /* array for GETALL, SETALL */ - struct seminfo *__buf; /* buffer for IPC_INFO */ -}; -#endif - - -/* - * - */ -bool CSharedMutex::createByKey( int key, bool createNew ) +void CAtomicLock::enter() { - // Create a semaphore set containing one semaphore - /*key_t mykey = ftok(".", 'n'); - _SemId = semget( mykey, 1, IPC_CREAT | IPC_EXCL | 0666 );*/ - - if ( createNew ) - _SemId = semget( key, 1, IPC_CREAT | IPC_EXCL | 0666 ); - else - _SemId = semget( key, 1, 0666 ); - nldebug( "Got semid %d", _SemId ); - if( _SemId == -1 ) - return false; - - // Initialise the semaphore to 1 - union semun arg; - arg.val = 1; - if ( semctl( _SemId, 0, SETVAL, arg ) == -1 ) - { - nlwarning( "semid=%d, err=%s", _SemId, strerror(errno) ); - return false; - } - return true; + SDL_AtomicLock(&m_SDLSpinLock); } - -/* - * - */ -void CSharedMutex::destroy() +void CAtomicLock::leave() { - // Destroy the semaphore - union semun arg; - nlverifyex( semctl( _SemId, 0, IPC_RMID, arg ) != -1, ("semid=%d, err=%s", _SemId, strerror(errno) ) ); - _SemId = -1; -} - - -/* - * - */ -void CSharedMutex::enter() -{ - // Decrement the semaphore - sembuf buf; - buf.sem_num = 0; - buf.sem_op = -1; - nlverify( semop( _SemId, &buf, 1 ) != -1); -} - - -/* - * - */ -void CSharedMutex::leave() -{ - // Increment the semaphore - sembuf buf; - buf.sem_num = 0; - buf.sem_op = 1; - nlverify( semop( _SemId, &buf, 1 ) != -1); -} - - -#endif // NL_OS_WINDOWS/NL_OS_UNIX - - - - - - - -/****************** - * Debugging code * - ******************/ - -#ifdef MUTEX_DEBUG - -map *AcquireTime = NULL; -uint32 NbMutexes = 0; -CFairMutex *ATMutex = NULL; -bool InitAT = true; - - -/// Inits the "mutex debugging info system" -void initAcquireTimeMap() -{ - if ( InitAT ) - { - ATMutex = new CFairMutex("ATMutex"); - AcquireTime = new map; - InitAT = false; - } -} - - -/// Gets the debugging info for all mutexes (call it evenly, e.g. once per second) -map getNewAcquireTimes() -{ - map m; - ATMutex->enter(); - - // Copy map - m = *AcquireTime; - - // Reset map -/* map::iterator im; - for ( im=AcquireTime->begin(); im!=AcquireTime->end(); ++im ) - { - (*im).second.Time = 0; - (*im).second.Nb = 0; - (*im).second.Locked = false; - } -*/ - ATMutex->leave(); - return m; -} - - -//////////////////////// -//////////////////////// - -void CFairMutex::debugCreateMutex() -{ -/* if ( ! InitAT ) - { - ATMutex->enter(); - AcquireTime->insert( make_pair( this, TMutexLocks(NbMutexes) ) ); - NbMutexes++; - ATMutex->leave(); - char dbgstr [256]; -#ifdef STORE_MUTEX_NAME - smprintf( dbgstr, 256, "MUTEX: Creating mutex %p %s (number %u)\n", this, Name.c_str(), NbMutexes-1 ); -#else - smprintf( dbgstr, 256, "MUTEX: Creating mutex %p (number %u)\n", this, NbMutexes-1 ); -#endif -#ifdef NL_OS_WINDOWS - if ( IsDebuggerPresent() ) - OutputDebugString( dbgstr ); -#endif - cout << dbgstr << endl; - } -*/} - -void CFairMutex::debugDeleteMutex() -{ - if ( (this!=ATMutex ) && (ATMutex!=NULL) ) - { - ATMutex->enter(); - (*AcquireTime)[this].Dead = true; - ATMutex->leave(); - } -} - -void CFairMutex::debugBeginEnter() -{ - if ( (this!=ATMutex ) && (ATMutex!=NULL) ) - { - TTicks t = CTime::getPerformanceTime(); - - ATMutex->enter(); - std::map::iterator it = (*AcquireTime).find (this); - if (it == (*AcquireTime).end()) - { - AcquireTime->insert( make_pair( this, TMutexLocks(NbMutexes++) ) ); - char dbgstr [256]; -#ifdef STORE_MUTEX_NAME - smprintf( dbgstr, 256, "MUTEX: Creating mutex %p %s (number %u)\n", this, Name.c_str(), NbMutexes-1 ); -#else - smprintf( dbgstr, 256, "MUTEX: Creating mutex %p (number %u)\n", this, NbMutexes-1 ); -#endif - -#ifdef NL_OS_WINDOWS - if ( IsDebuggerPresent() ) OutputDebugString( dbgstr ); -#endif - cout << dbgstr << endl; - - it = (*AcquireTime).find (this); -#ifdef STORE_MUTEX_NAME - (*it).second.MutexName = Name; -#endif - } - (*it).second.WaitingMutex++; - (*it).second.BeginEnter = t; - ATMutex->leave(); - } -} - - -void CFairMutex::debugEndEnter() -{ -// printf("1"); -/* char str[1024]; - sprintf(str, "enter %8p %8p %8p\n", this, _Mutex, getThreadId ()); - if (_Mutex == (void*)0x88) - { - OutputDebugString (str); - if (entered) __asm int 3; - entered = true; - } -*/ - if ( ( this != ATMutex ) && ( ATMutex != NULL ) ) - { - TTicks t = CTime::getPerformanceTime(); - ATMutex->enter(); - if ((uint32)(t-(*AcquireTime)[this].BeginEnter) > (*AcquireTime)[this].TimeToEnter) - (*AcquireTime)[this].TimeToEnter = (uint32)(t-(*AcquireTime)[this].BeginEnter); - (*AcquireTime)[this].Nb += 1; - (*AcquireTime)[this].WaitingMutex--; - (*AcquireTime)[this].ThreadHavingTheMutex = getThreadId(); - (*AcquireTime)[this].EndEnter = t; - ATMutex->leave(); - } -} - - -void CFairMutex::debugLeave() -{ -// printf( "0" ); -/* char str[1024]; - sprintf(str, "leave %8p %8p %8p\n", this, _Mutex, getThreadId ()); - if (_Mutex == (void*)0x88) - { - OutputDebugString (str); - if (!entered) __asm int 3; - entered = false; - } -*/ - - if ( ( this != ATMutex ) && ( ATMutex != NULL ) ) - { - TTicks Leave = CTime::getPerformanceTime(); - ATMutex->enter(); - if ((uint32)(Leave-(*AcquireTime)[this].EndEnter) > (*AcquireTime)[this].TimeInMutex) - (*AcquireTime)[this].TimeInMutex = (uint32)(Leave-(*AcquireTime)[this].EndEnter); - (*AcquireTime)[this].Nb += 1; - (*AcquireTime)[this].WaitingMutex = false; - (*AcquireTime)[this].ThreadHavingTheMutex = 0xFFFFFFFF; - ATMutex->leave(); - } - + SDL_AtomicUnlock(&m_SDLSpinLock); } -#endif // MUTEX_DEBUG +// *************************************************************************** } // NLMISC diff --git a/code/nel/src/sound/stream_source.cpp b/code/nel/src/sound/stream_source.cpp index 9bd48ff25..beb37e969 100644 --- a/code/nel/src/sound/stream_source.cpp +++ b/code/nel/src/sound/stream_source.cpp @@ -99,7 +99,7 @@ void CStreamSource::releasePhysicalSource() uint32 CStreamSource::getTime() { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); if (hasPhysicalSource()) return getPhysicalSource()->getTime(); @@ -117,7 +117,7 @@ void CStreamSource::setLooping(bool l) { CSourceCommon::setLooping(l); - //CAutoMutex autoMutex(m_BufferMutex); + //CAutoMutex autoMutex(m_BufferMutex); // //CSourceCommon::setLooping(l); //if (hasPhysicalSource()) @@ -150,7 +150,7 @@ void CStreamSource::play() CAudioMixerUser *mixer = CAudioMixerUser::instance(); { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); //if ((mixer->getListenPosVector() - _Position).sqrnorm() > m_StreamSound->getMaxDistance() * m_StreamSound->getMaxDistance()) if ((_RelativeMode ? getPos().sqrnorm() : (mixer->getListenPosVector() - getPos()).sqrnorm()) > m_StreamSound->getMaxDistance() * m_StreamSound->getMaxDistance()) @@ -277,7 +277,7 @@ void CStreamSource::play() void CStreamSource::stopInt() { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); // nldebug("CStreamSource %p : stop", (CAudioMixerUser::IMixerEvent*)this); // nlassert(_Playing); @@ -321,7 +321,7 @@ void CStreamSource::stop() void CStreamSource::setPos(const NLMISC::CVector& pos) { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); CSourceCommon::setPos(pos); if (hasPhysicalSource()) @@ -330,7 +330,7 @@ void CStreamSource::setPos(const NLMISC::CVector& pos) void CStreamSource::setVelocity(const NLMISC::CVector& vel) { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); CSourceCommon::setVelocity(vel); if (hasPhysicalSource()) @@ -342,7 +342,7 @@ void CStreamSource::setVelocity(const NLMISC::CVector& vel) */ void CStreamSource::setDirection(const NLMISC::CVector& dir) { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); CSourceCommon::setDirection(dir); @@ -373,7 +373,7 @@ void CStreamSource::setDirection(const NLMISC::CVector& dir) void CStreamSource::updateFinalGain() { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); if (hasPhysicalSource()) getPhysicalSource()->setGain(getFinalGain()); @@ -381,7 +381,7 @@ void CStreamSource::updateFinalGain() void CStreamSource::setPitch(float pitch) { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); m_PitchInv = 1.0f / pitch; CSourceCommon::setPitch(pitch); if (hasPhysicalSource()) @@ -390,7 +390,7 @@ void CStreamSource::setPitch(float pitch) void CStreamSource::setSourceRelativeMode(bool mode) { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); CSourceCommon::setSourceRelativeMode(mode); if (hasPhysicalSource()) @@ -428,7 +428,7 @@ void CStreamSource::updateAvailableBuffers() /// Get a writable pointer to the buffer of specified size. Use capacity to specify the required bytes. Returns NULL when all the buffer space is already filled. Call setFormat() first. uint8 *CStreamSource::lock(uint capacity) { - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); updateAvailableBuffers(); if (m_FreeBuffers > 0) return m_Buffers[m_NextBuffer]->lock(capacity); @@ -440,7 +440,7 @@ bool CStreamSource::unlock(uint size) { nlassert(m_FreeBuffers > 0); - CAutoMutex autoMutex(m_BufferMutex); + CAutoMutex autoMutex(m_BufferMutex); IBuffer *buffer = m_Buffers[m_NextBuffer]; bool result = buffer->unlock(size); diff --git a/code/ryzom/common/src/game_share/change_tracker_base.h b/code/ryzom/common/src/game_share/change_tracker_base.h index 47ff79c3e..4cd618fb3 100644 --- a/code/ryzom/common/src/game_share/change_tracker_base.h +++ b/code/ryzom/common/src/game_share/change_tracker_base.h @@ -52,7 +52,7 @@ struct TChangeTrackerHeader #ifdef USE_FAST_MUTEX /// Fast mutex (TODO: use multi-processor version) - volatile NLMISC::CFastMutex FastMutex; + NLMISC::CFastMutex FastMutex; #endif /* * Number of values set (used in COUNT_MIRROR_CHANGES mode only, always allocated for mode interoperability) @@ -161,7 +161,7 @@ public: #ifdef USE_FAST_MUTEX /// Return the mutex - volatile NLMISC::CFastMutex& trackerMutex() { return _Header->FastMutex; } + NLMISC::CFastMutex& trackerMutex() { return _Header->FastMutex; } #else /// Return the mutex NLMISC::CSharedMutex& trackerMutex() { return _TrackerMutex; }