Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @synchronized, volatile and OSMemoryBarrier() all together. Does one imply the other?

Coming from Java I'm trying to learn thread safety in Objective-C. So far I've leaned that

  • @synchronized blocks prevent concurrent access to the same block of code
  • volatile variables assure visibility of changes accross threads
  • OSMemoryBarrier(); assures proper ordering of access

My question is: Does one of those imply one or more of the others? If I want all three, do I need to use all three techniques?

Example:

volatile int first = 0;
volatile int second = 0;

[...]

@synchronized {
    OSMemoryBarrier();
    first++;
    OSMemoryBarrier();
    second++;
    OSMemoryBarrier();
}

In Java all three are assured when entering and leaving a synchronized block and when reading or writing a volatile variable. True?

like image 673
Twilite Avatar asked Oct 25 '11 13:10

Twilite


2 Answers

The @synchronized directive gets converted as follows...

- (NSString *)myString {
  @synchronized(self) {
    return [[myString retain] autorelease];
  }
}

becomes...

- (NSString *)myString {
  NSString *retval = nil;
  pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
  pthread_mutex_lock(self_mutex);
  retval = [[myString retain] autorelease];
  pthread_mutex_unlock(self_mutex);
  return retval;
}
like image 64
Simon Lee Avatar answered Oct 18 '22 16:10

Simon Lee


@synchronized doesn't protect a block of code from being reentered - it prevents executing any code that also uses @synchronized with the same object. So if you have two methods

- (void)method1 {
    @synchronized (self) { dothis (); }
}
- (void)method2 {
    @synchronized (self) { dothat (); }
}

and two different threads call method1 and method2 for the same object, then dothis() and dothat() will be called one after the other. Of course that's also true if two different threads call method1 for the same object. @synchronized doesn't stop you from entering a block on the same thread though, so in the example above dothis() could call [self method2] and it wouldn't be blocked.

If you are using volatile or OSMemoryBarrier() then I suggest that your design is much, much, much too complicated and you will run into trouble sooner or later.

like image 36
gnasher729 Avatar answered Oct 18 '22 16:10

gnasher729