From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/mutex_8cpp-source.html | 593 ++++++++++++++++++++++++++++++++ 1 file changed, 593 insertions(+) create mode 100644 docs/doxygen/nel/mutex_8cpp-source.html (limited to 'docs/doxygen/nel/mutex_8cpp-source.html') diff --git a/docs/doxygen/nel/mutex_8cpp-source.html b/docs/doxygen/nel/mutex_8cpp-source.html new file mode 100644 index 00000000..f64fd635 --- /dev/null +++ b/docs/doxygen/nel/mutex_8cpp-source.html @@ -0,0 +1,593 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

mutex.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "stdmisc.h"
+00027 
+00028 #ifndef _GNU_SOURCE
+00029 #define _GNU_SOURCE
+00030 #endif // _GNU_SOURCE
+00031 
+00032 #include "nel/misc/mutex.h"
+00033 #include "nel/misc/time_nl.h"
+00034 
+00035 #ifdef MUTEX_DEBUG
+00036 #include <iostream>
+00037 #endif
+00038 
+00039 using namespace std;
+00040 
+00041 #ifndef MUTEX_DEBUG
+00042 #define debugCreateMutex() ;
+00043 #define debugBeginEnter() ;
+00044 #define debugEndEnter() ;
+00045 #define debugLeave() ;
+00046 #define debugDeleteMutex() ;
+00047 #endif
+00048 
+00049 
+00050 /****************
+00051  * Windows code *
+00052  ****************/
+00053 
+00054 #ifdef NL_OS_WINDOWS
+00055 
+00056 // these defines are for IsDebuggerPresent(). It'll not compile on windows 95
+00057 // just comment this and the IsDebuggerPresent to compile on windows 95
+00058 #define _WIN32_WINDOWS  0x0410
+00059 #define WINVER                  0x0400
+00060 #include <windows.h>
+00061 
+00062 
+00063 namespace NLMISC {
+00064 
+00065 
+00066 /*
+00067  * Windows version
+00068  */
+00069 
+00070 CUnfairMutex::CUnfairMutex()
+00071 {
+00072         // Create a mutex with no initial owner.
+00073         Mutex = (void *) CreateMutex (NULL, FALSE, NULL);
+00074         nlassert (Mutex != NULL);
+00075 }
+00076 
+00077 
+00078 CUnfairMutex::CUnfairMutex(const std::string &name)
+00079 {
+00080         // Create a mutex with no initial owner.
+00081         Mutex = (void *) CreateMutex (NULL, FALSE, NULL);
+00082         nlassert (Mutex != NULL);
+00083 }
+00084 
+00085 
+00086 /*
+00087  * Windows version
+00088  */
+00089 CUnfairMutex::~CUnfairMutex()
+00090 {
+00091         CloseHandle( Mutex );
+00092 }
+00093 
+00094 
+00095 /*
+00096  * Windows version
+00097  */
+00098 void CUnfairMutex::enter()
+00099 {
+00100 #ifdef NL_DEBUG
+00101         DWORD timeout;
+00102         if ( IsDebuggerPresent() )
+00103                 timeout = INFINITE;
+00104         else
+00105                 timeout = 10000;
+00106 
+00107     // Request ownership of mutex
+00108         DWORD dwWaitResult = WaitForSingleObject (Mutex, timeout);
+00109 #else
+00110     // Request ownership of mutex during 10s
+00111         DWORD dwWaitResult = WaitForSingleObject (Mutex, 10000);
+00112 #endif // NL_DEBUG
+00113         switch (dwWaitResult)
+00114         {
+00115         // The thread got mutex ownership.
+00116         case WAIT_OBJECT_0:             break;
+00117         // Cannot get mutex ownership due to time-out.
+00118         case WAIT_TIMEOUT:              nlerror ("Dead lock in a mutex (or more that 10s for the critical section");
+00119         // Got ownership of the abandoned mutex object.
+00120         case WAIT_ABANDONED:    nlerror ("A thread forgot to release the mutex");
+00121     }
+00122 }
+00123 
+00124 
+00125 /*
+00126  * Windows version
+00127  */
+00128 void CUnfairMutex::leave()
+00129 {
+00130         if (ReleaseMutex(Mutex) == 0)
+00131         {
+00132                 nlerror ("error while releasing the mutex (0x%x %d), %p", GetLastError(), GetLastError(), Mutex);
+00133         }
+00134 }
+00135 
+00136 
+00137 /*
+00138  * Windows version
+00139  */
+00140 CFairMutex::CFairMutex()
+00141 {
+00142         Name = "unset mutex name";
+00143 
+00144         debugCreateMutex();
+00145 
+00146         // Check that the CRITICAL_SECTION structure has not changed
+00147         nlassert( sizeof(TNelRtlCriticalSection)==sizeof(CRITICAL_SECTION) );
+00148 
+00149 #if (_WIN32_WINNT >= 0x0500)
+00150         DWORD dwSpinCount = 0x80000000; // set high-order bit to use preallocation
+00151         if ( ! InitializeCriticalSectionAndSpinCount( &_Cs, dwSpinCount ) )
+00152         {
+00153                 nlerror( "Error entering critical section" );
+00154         }
+00155 #else
+00156         InitializeCriticalSection( (CRITICAL_SECTION*)&_Cs );
+00157 #endif
+00158 }
+00159 
+00160 
+00161 CFairMutex::CFairMutex(const string &name)
+00162 {
+00163         Name = name;
+00164 
+00165 #ifdef MUTEX_DEBUG
+00166         debugCreateMutex();
+00167 #endif
+00168 
+00169         // Check that the CRITICAL_SECTION structure has not changed
+00170         nlassert( sizeof(TNelRtlCriticalSection)==sizeof(CRITICAL_SECTION) );
+00171 
+00172 #if (_WIN32_WINNT >= 0x0500)
+00173         DWORD dwSpinCount = 0x80000000; // set high-order bit to use preallocation
+00174         if ( ! InitializeCriticalSectionAndSpinCount( &_Cs, dwSpinCount ) )
+00175         {
+00176                 nlerror( "Error entering critical section" );
+00177         }
+00178 #else
+00179         InitializeCriticalSection( (CRITICAL_SECTION*)&_Cs );
+00180 #endif
+00181 }
+00182 
+00183 
+00184 
+00185 /*
+00186  * Windows version
+00187  */
+00188 CFairMutex::~CFairMutex()
+00189 {
+00190         DeleteCriticalSection( (CRITICAL_SECTION*)&_Cs );
+00191 
+00192         debugDeleteMutex();
+00193 }
+00194 
+00195 
+00196 /*
+00197  * Windows version
+00198  */
+00199 void CFairMutex::enter()
+00200 {
+00201         debugBeginEnter();
+00202 
+00203         EnterCriticalSection( (CRITICAL_SECTION*)&_Cs );
+00204 
+00205         debugEndEnter();
+00206 }
+00207 
+00208 
+00209 /*
+00210  * Windows version
+00211  */
+00212 void CFairMutex::leave()
+00213 {
+00214         LeaveCriticalSection( (CRITICAL_SECTION*)&_Cs );
+00215 
+00216         debugLeave();
+00217 }
+00218 
+00219 
+00220 
+00221 
+00222 
+00223 
+00224 
+00225 
+00226 /*************
+00227  * Unix code *
+00228  *************/
+00229 
+00230 #elif defined NL_OS_UNIX
+00231 
+00232 #include <pthread.h>
+00233 #include <errno.h>
+00234 
+00235 
+00236 /*
+00237  * Clanlib authors say: "We need to do this because the posix threads library
+00238  * under linux obviously suck:"
+00239  */
+00240 extern "C"
+00241 {
+00242         int pthread_mutexattr_setkind_np( pthread_mutexattr_t *attr, int kind );
+00243 }
+00244 
+00245 
+00246 namespace NLMISC {
+00247 
+00248 
+00249 /*
+00250  * Unix version
+00251  */
+00252 CUnfairMutex::CUnfairMutex(const std::string &name)
+00253 {
+00254         pthread_mutexattr_t attr;
+00255         pthread_mutexattr_init( &attr );
+00256         // Fast mutex. Note: on Windows all mutexes are recursive
+00257         pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ADAPTIVE_NP ); //PTHREAD_MUTEX_ERRORCHECK_NP );//PTHREAD_MUTEX_ADAPTIVE_NP );//PTHREAD_MUTEX_RECURSIVE_NP );
+00258         pthread_mutex_init( &mutex, &attr );
+00259         pthread_mutexattr_destroy( &attr );
+00260 }
+00261 
+00262 
+00263 /*
+00264  * Unix version
+00265  */
+00266 CUnfairMutex::~CUnfairMutex()
+00267 {
+00268         pthread_mutex_destroy( &mutex );
+00269 }
+00270 
+00271 
+00272 /*
+00273  * Unix version
+00274  */
+00275 void CUnfairMutex::enter()
+00276 {
+00277         //cout << getpid() << ": Locking " << &mutex << endl;
+00278         if ( pthread_mutex_lock( &mutex ) != 0 )
+00279         {
+00280           //cout << "Error locking a mutex " << endl;
+00281                 nlerror( "Error locking a mutex" );
+00282         }
+00283         /*else
+00284         {
+00285           cout << getpid() << ": Owning " << &mutex << endl;
+00286         }*/
+00287 }
+00288 
+00289 
+00290 /*
+00291  * Unix version
+00292  */
+00293 void CUnfairMutex::leave()
+00294 {
+00295         //int errcode;
+00296         //cout << getpid() << ": Unlocking " << &mutex << endl;
+00297         if ( (/*errcode=*/pthread_mutex_unlock( &mutex )) != 0 )
+00298         {
+00299          /* switch ( errcode )
+00300             {
+00301             case EINVAL: cout << "INVAL" << endl; break;
+00302             case EPERM: cout << "PERM" << endl; break;
+00303             default: cout << "OTHER" << endl;
+00304             }
+00305           */
+00306           //cout << "Error unlocking a mutex " /*<< &mutex*/ << endl;
+00307                 nlerror( "Error unlocking a mutex" );
+00308         }
+00309         /*else
+00310         {
+00311           cout << getpid() << ": Released " << &mutex << endl;
+00312         }*/
+00313 }
+00314 
+00315 
+00316 /*
+00317  * Unix version
+00318  */
+00319 CFairMutex::CFairMutex()
+00320 {
+00321         sem_init( const_cast<sem_t*>(&_Sem), 0, 1 );
+00322 }
+00323 
+00324 
+00325 CFairMutex::CFairMutex( const std::string &name )
+00326 {
+00327         sem_init( const_cast<sem_t*>(&_Sem), 0, 1 );
+00328 }
+00329 
+00330 
+00331 /*
+00332  * Unix version
+00333  */
+00334 CFairMutex::~CFairMutex()
+00335 {
+00336         sem_destroy( const_cast<sem_t*>(&_Sem) ); // needs that no thread is waiting on the semaphore
+00337 }
+00338 
+00339 
+00340 /*
+00341  * Unix version
+00342  */
+00343 void CFairMutex::enter()
+00344 {
+00345         sem_wait( const_cast<sem_t*>(&_Sem) );
+00346 }
+00347 
+00348 
+00349 /*
+00350  * Unix version
+00351  */
+00352 void CFairMutex::leave()
+00353 {
+00354         sem_post( const_cast<sem_t*>(&_Sem) );
+00355 }
+00356 
+00357 
+00358 #endif // NL_OS_WINDOWS/NL_OS_LINUX
+00359 
+00360 
+00361 
+00362 
+00363 
+00364 
+00365 
+00366 /******************
+00367  * Debugging code *
+00368  ******************/
+00369         
+00370 #ifdef MUTEX_DEBUG
+00371 
+00372 map<CFairMutex*,TMutexLocks>    *AcquireTime = NULL;
+00373 uint32                                          NbMutexes = 0;
+00374 CFairMutex                                              *ATMutex = NULL;
+00375 bool                                            InitAT = true;
+00376 
+00377 
+00379 void initAcquireTimeMap()
+00380 {
+00381         if ( InitAT )
+00382         {
+00383                 ATMutex = new CFairMutex("ATMutex");
+00384                 AcquireTime = new map<CFairMutex*,TMutexLocks>;
+00385                 InitAT = false;
+00386         }
+00387 }
+00388 
+00389 
+00391 map<CFairMutex*,TMutexLocks>    getNewAcquireTimes()
+00392 {
+00393         map<CMutex*,TMutexLocks>        m;
+00394         ATMutex->enter();
+00395 
+00396         // Copy map
+00397         m = *AcquireTime;
+00398 
+00399         // Reset map
+00400 /*      map<CMutex*,TMutexLocks>::iterator im;
+00401         for ( im=AcquireTime->begin(); im!=AcquireTime->end(); ++im )
+00402         {
+00403                 (*im).second.Time = 0;
+00404                 (*im).second.Nb = 0;
+00405                 (*im).second.Locked = false;
+00406         }
+00407 */
+00408         ATMutex->leave();
+00409         return m;
+00410 }
+00411 
+00412 
+00415 
+00416 void CFairMutex::debugCreateMutex()
+00417 {
+00418 /*      if ( ! InitAT )
+00419         {
+00420                 ATMutex->enter();
+00421                 AcquireTime->insert( make_pair( this, TMutexLocks(NbMutexes) ) );
+00422                 NbMutexes++;
+00423                 ATMutex->leave();
+00424                 char dbgstr [256];
+00425                 smprintf( dbgstr, 256, "MUTEX: Creating mutex %p %s (number %u)\n", this, Name.c_str(), NbMutexes-1 );
+00426 #ifdef NL_OS_WINDOWS
+00427                 if ( IsDebuggerPresent() )
+00428                         OutputDebugString( dbgstr );
+00429 #endif
+00430                 cout << dbgstr << endl;
+00431         }
+00432 */}
+00433 
+00434 void CFairMutex::debugDeleteMutex()
+00435 {
+00436         if ( (this!=ATMutex ) && (ATMutex!=NULL) )
+00437         {
+00438                 ATMutex->enter();
+00439                 (*AcquireTime)[this].Dead = true;
+00440                 ATMutex->leave();
+00441         }
+00442 }
+00443 
+00444 void CFairMutex::debugBeginEnter()
+00445 {
+00446         if ( (this!=ATMutex ) && (ATMutex!=NULL) )
+00447         {
+00448                 TTicks t = CTime::getPerformanceTime();
+00449 
+00450                 ATMutex->enter();
+00451                 std::map<CMutex*,TMutexLocks>::iterator it = (*AcquireTime).find (this);
+00452                 if (it == (*AcquireTime).end())
+00453                 {
+00454                         AcquireTime->insert( make_pair( this, TMutexLocks(NbMutexes++) ) );
+00455                         char dbgstr [256];
+00456                         smprintf( dbgstr, 256, "MUTEX: Creating mutex %p %s (number %u)\n", this, Name.c_str(), NbMutexes-1 );
+00457 #ifdef NL_OS_WINDOWS
+00458                         if ( IsDebuggerPresent() ) OutputDebugString( dbgstr );
+00459 #endif
+00460                         cout << dbgstr << endl;
+00461 
+00462                         it = (*AcquireTime).find (this);
+00463                         (*it).second.MutexName = Name;
+00464                 }
+00465                 (*it).second.WaitingMutex++;
+00466                 (*it).second.BeginEnter = t;
+00467                 ATMutex->leave();
+00468         }
+00469 }
+00470 
+00471 
+00472 void CFairMutex::debugEndEnter()
+00473 {
+00474 //      printf("1");
+00475 /*      char str[1024];
+00476         sprintf(str, "enter %8p %8p %8p\n", this, Mutex, getThreadId ());
+00477         if (Mutex == (void*)0x88)
+00478         {
+00479                 OutputDebugString (str);
+00480                 if (entered) __asm int 3;
+00481                 entered = true;
+00482         }
+00483 */
+00484         if ( ( this != ATMutex ) && ( ATMutex != NULL ) )
+00485         {
+00486                 TTicks t = CTime::getPerformanceTime();
+00487                 ATMutex->enter();
+00488                 if ((uint32)(t-(*AcquireTime)[this].BeginEnter) > (*AcquireTime)[this].TimeToEnter)
+00489                         (*AcquireTime)[this].TimeToEnter = (uint32)(t-(*AcquireTime)[this].BeginEnter);
+00490                 (*AcquireTime)[this].Nb += 1;
+00491                 (*AcquireTime)[this].WaitingMutex--;
+00492                 (*AcquireTime)[this].ThreadHavingTheMutex = getThreadId();
+00493                 (*AcquireTime)[this].EndEnter = t;
+00494                 ATMutex->leave();
+00495         }
+00496 }
+00497 
+00498 
+00499 void CFairMutex::debugLeave()
+00500 {
+00501 //      printf( "0" );
+00502 /*      char str[1024];
+00503         sprintf(str, "leave %8p %8p %8p\n", this, Mutex, getThreadId ());
+00504         if (Mutex == (void*)0x88)
+00505         {
+00506                 OutputDebugString (str);
+00507                 if (!entered) __asm int 3;
+00508                 entered = false;
+00509         }
+00510 */
+00511 
+00512         if ( ( this != ATMutex ) && ( ATMutex != NULL ) )
+00513         {
+00514                 TTicks Leave = CTime::getPerformanceTime();
+00515                 ATMutex->enter();
+00516                 if ((uint32)(Leave-(*AcquireTime)[this].EndEnter) > (*AcquireTime)[this].TimeInMutex)
+00517                         (*AcquireTime)[this].TimeInMutex = (uint32)(Leave-(*AcquireTime)[this].EndEnter);
+00518                 (*AcquireTime)[this].Nb += 1;
+00519                 (*AcquireTime)[this].WaitingMutex = false;
+00520                 (*AcquireTime)[this].ThreadHavingTheMutex = 0xFFFFFFFF;
+00521                 ATMutex->leave();
+00522         }
+00523 
+00524 }
+00525 
+00526 #endif // MUTEX_DEBUG
+00527 
+00528 } // NLMISC
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1