From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tristan Savatier To: "Bossom, John" Cc: "'pthreads-win32@sources.redhat.com'" Subject: Re: Mutex implementation questions Date: Thu, 05 Oct 2000 19:55:00 -0000 Message-id: <39DD417E.FD05A413@mpegtv.com> References: <430F887D415DD1118C2700805F31ECF1037F1394@SOTA0005> X-SW-Source: 2000/msg00122.html Bossom, John wrote: > > You are correct... critical sections are almost 100 times faster than > actual kernel based mutexes... however... That's right. Regarding pthread-win32 running on WinCE (PocketPC), I was able to get a very significant gain of performances on the overall application (5% to 15%) now that our mutexes use critical sections (TryEnterCriticalSection works on WinCE 3.0 / Pocket PC). Note that we had to make a minor change to fix mutexes on WinCE: #ifdef UNDER_CE _pthread_h_kernel32 = LoadLibrary(TEXT("COREDLL.DLL")); #else _pthread_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); #endif Because on WinCE, the symbol TryEnterCriticalSection is part of COREDLL.DLL (there is no KERNEL32.DLL). > 1) Mutexes (i.e. kernel based) are useful in that you can support a > lock-with-timeout... a feature that is being pondered as an upgrade > to pthreads. true. > 2) Mutexes can use WaitForMultipleObjects (sp?) which allows you to simulate > a cancel by waiting on a cancel event as well as the mutex. true, but in some cases cancellation is not a problem, and performances is critical. > 3) TryEnterCriticalSection is not supported on Win95/98 (originally it was > completely left out... then they added a stub that simply returns > "function not supported", thus there is no way to implement > pthread_mutex_trylock; hence if you need "trylock" you need to use a > real mutex. true. but it works on NT/2000 (and WinCE 3.0) > 4) By eliminating the DllMain, whose purpose was to perform > behind the scenes cleanup of the "self" structure as well as calling > all the destructors for thread-specific data keys, what alternate > approach did you take for doing this thread-based cleanup? > (i.e. I leveraged the fact that DllMain is called each time a thread > is started/finished to perform thread based initialization/cleanup) You are right. One thing that can be done is to make sure that all thread terminate by calling pthread_exit(void *), and do not "fall through the bottom" of the threan entry-point routine (which is allowed by the standard). That's what we do, and to make it work, we modified pthread_exit by replacing: _pthread_callUserDestroyRoutines((pthread_t) pthread_getspecific(_pthread_selfThreadKey)); by: _pthread_threadDestroy((pthread_t) pthread_getspecific(_pthread_selfThreadKey)); which calls _pthread_callUserDestroyRoutines and then does the necessary cleanup of the thread TSD. That takes are of the thread cleanup. Regarding the process cleanup, I suppose that _pthread_processTerminate() should be called explicitely if the dll is not used. Now, maybe you wonder why we prefer to link statically rather that to use the DLL (pthread.dll). The reason is that Windows does not support dll versionning, i.e. if several applications rely on pthread.dll, but on various versions of it, things break. There would be a solution which is to place the dll in the same directory as the application, rather than in the \Windows directory, but this also breaks due to the stupid rule used by Windows to look for dll's: first it looks in \Windows, then in the other places... which means that if another application places an incompatible pthread.dll in \windows, it will break you application (we had the experience with applications using xaudio.dll). And pthread is so small that the gain of having it shared (compared to the trouble) is small. That's why we think that using pthread.dll is a BAD idea, and that static linking with pthread.lib is a safer solution... -t > I hope this clears up some of your questions. > > Cheers, > > John. > > -----Original Message----- > From: Tristan Savatier [ mailto:tristan@mpegtv.com ] > Sent: Monday, October 02, 2000 6:10 PM > To: 'pthreads-win32@sources.redhat.com' > Subject: Mutex implementation questions > > I noticed that if _pthread_try_enter_critical_section has been set > to a non-NULL value by DllMain, Mutexes are implemented using > critical sections (InitializeCriticalSection) instead of > CreateMutex, regardless of the value of the implemetation-specific > forcecs > mutex attribute. > > According to "Win32 programming", critical sections are light weight > compared to mutexes, they are not managed by the kernel, and they > are much faster than mutexes. So why no use critical sections > all the time to implement pthread mutexes ? > > Are there cases where critical sections are not available or > wouldn't work well ? > > The DllMain seems to do some tests to check if InitializeCriticalSection > exists and works. What are the cases where critical sections > would not be available ? > > Also, I have a suggestion: > > It might be a good idea to add a compile flag to > allow the use of pthread-win32 with static linking > (i.e. to make just a pthread.lib, no dll). > > In this case, a compilation flag should be added to exclude the DllMain > routine. Also, the code that sets _pthread_try_enter_critical_section > should be moved from DllMain to _pthread_processInitialize. The > _pthread_processInitialize should be made global and it should > be called by the application to initialize pthread. > > We had to change the pthread code to do all that in our > WinCE application. > > -t -- Regards, -- Tristan Savatier (President, MpegTV LLC) MpegTV: http://www.mpegtv.com - Tel: (415) 864 6466 PocketTV: http://www.pockettv.com - Fax: (415) 704 3224