• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Thread safety question
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Thread safety question


  • Subject: Re: Thread safety question
  • From: Shawn Erickson <email@hidden>
  • Date: Fri, 18 Feb 2005 09:27:35 -0800

On Feb 18, 2005, at 8:33 AM, Ernesto Corvi wrote:

Hi Steve.

The problem you might encounter here, if you have global register allocation turned on, is that the compiler might cache 'variable_initialized' in a register.
So let's contemplate this scenario:
Thread1 -> Caches variable_initialized into R2, gets swapped out between the 'if ( !variable_initialized )' and the '[myLock lock]'.
Thread2 -> Executes the entire function and initializes the variable.
Thread1 -> Resumes execution, but since it cached 'variable_initialized' into R2, it still thinks its unitialized, and initializes again.


A portable solution to this problem is to declare 'variable_initialized' as:

volatile BOOL variable_initialized=NO;

The 'volatile' keyword hints the compiler not to cache the variable and force direct access to the variable every time it's accessed.

Actually this isn't correct.

Calling lock (in fact any function) will force the compiler to reload the external variable for all following code since the function call could have changed it (threads doesn't affect this requirement).

So the use of volatile shouldn't be needed nor is it really that portable because of the freedoms of implementation that exist for the keyword volatile (however it is likely going to do exactly what you are expecting). It can also come with overhead depending on how your volatile var is used.

See...
<http://groups.google.com/groups?selm=email@hidden>
...and...
<http://lists.apple.com/archives/darwin-development/2004/Mar/ msg00154.html>


Calling lock will put out a memory barrier so it will insure that data is written/read in order such that "myVariable" will be correct to the current state while inside of lock bracketing (assuming all other writes to that variable are also protected by the same lock, other reads should be wrapped as well but that is not important here). In other words it is best to use provided locking constructs when having to do shared access like this from multiple threads (of course sometimes the checking of a boolean, etc. for say an exit from a working loop doesn't always require the use of any locking or even volatile depending on what is needed and how things function).

The fast check pathway however could result in a bogus pointer getting returned if the write of a pointer to the variable isn't atomic but on PPC for a 32b value I believe it will be (won't get a partial pointer read out of it, all or nothing) but it is a fragile thing to be doing without consideration for future/different system architectures.

I question if the use of this fast check is really needed...? Do you know how often this function is called such that avoiding locking is actually gaining you anything? Often best to go with simpler code when possible. If it is a hot function why not move initialization to some up front function call and then have all later use just assume the variable has been initialized.

If on 10.3 or later consider...

static void* mySingletonObject = 0;

void* instance(void)
{
// possibly use self in the following if this is actually going to be a class or instance method
@synchronized(someObjectOrUniqueValue) {
if (mySingletonObject == nil) {
mySingletonObject = allocateObject();
}
}


	return mySingletonObject;
}

-Shawn

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Thread safety question
      • From: Rich Seibel <email@hidden>
References: 
 >Thread safety question (From: Steve Gehrman <email@hidden>)
 >Re: Thread safety question (From: Ernesto Corvi <email@hidden>)

  • Prev by Date: Re: Thread safety question
  • Next by Date: Re: login item for all users
  • Previous by thread: Re: Thread safety question
  • Next by thread: Re: Thread safety question
  • Index(es):
    • Date
    • Thread