Re: [boost] [thread] Win32 call_once

I have continued to think about the call_once() mechanism because many uses I can think of for it could require that it be called a lot. Therefore, I think we want the "normal" path to be as quick as possible. To that end, I was trying to come up with a way to use critical sections instead of named semaphores for the guard. I think I have managed that now, but it also occurs to me that we can test the flag up front to see if it has been set and if it has, we don't need to get any sort of guard. In the case that it hasn't, we can then acquire a guard (of some sort), re-test the flag (in case we have two threads running in parallel), and then execute the function. It looks a little uglier because of the double test, but it would execute faster because most of the time it would never have to get the guard. Hopefully there is something useful here. :) joe

"Greer, Joe" <jgreer@nsisoftware.com> writes:
I have continued to think about the call_once() mechanism because many uses I can think of for it could require that it be called a lot. Therefore, I think we want the "normal" path to be as quick as possible. To that end, I was trying to come up with a way to use critical sections instead of named semaphores for the guard. I think I have managed that now, but it also occurs to me that we can test the flag up front to see if it has been set and if it has, we don't need to get any sort of guard. In the case that it hasn't, we can then acquire a guard (of some sort), re-test the flag (in case we have two threads running in parallel), and then execute the function. It looks a little uglier because of the double test, but it would execute faster because most of the time it would never have to get the guard. Hopefully there is something useful here. :)
Thanks, Joe. That's pretty much the technique used by the version I committed to CVS, except that it uses a mutex rather than a critical section. Having the initial check prior to acquiring the mutex dramatically speeds up the "happy path", by a factor of about 100. The benefit of using a mutex rather than a critical section is twofold. Firstly the mutex is specific to the once_flag, rather than shared between all once_flags that invoke the same template specialization, and secondly it eliminates the possibility of priority inversion problems --- Sleep(0) does not yield correctly under all circumstances, and can therefore lead to this thread always running, whilst the thread with the lock doesn't get any work done, so can't release it. Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
participants (2)
-
Anthony Williams
-
Greer, Joe