Reputation: 1094
Could somebody, please, explain me why I get error EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) in dispatch_semaphore_wait in the following code:
-(void) initialize {
dispatch_queue_t queue = dispatch_queue_create("My queue", NULL);
dispatch_semaphore_t sem = dispatch_semaphore_create(1);
self.queue = queue;
self.sem = sem;
self.myarray = [[NSMutableArray alloc]init];
[self.myarray addObject: [[MyObject alloc] init]];
}
-(MyObject *) method1 {
//do something
dispatch_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
MyObject *obj = [self.myarray objectAtIndex:0];
dispatch_barrier_sync(self.queue, ^{
[self.myarray removeObjectAtIndex:0];
});
return obj;
}
-(void) method2:(MyObject *)object {
//do something
dispatch_barrier_async(self.queue, ^{
[self.myarray addObject:object];
dispatch_semaphore_signal(self.sem);
});
}
I found similar question Why does this code cause "EXC_BAD_INSTRUCTION"?, but in my case I am using ARC and I do not write explicitly nowhere dispatch_release(sem);
Upvotes: 1
Views: 11828
Reputation: 90571
You are allowing simultaneous access to the array self.myarray
without sufficient protection. You modify the array with -addObject:
and -removeObjectAtIndex:
on the serial queue self.queue
but you read from it using -objectAtIndex:
without any protection. That means you may be reading from it at the same time you're writing to it, which is not safe. You need to also put the -objectAtIndex:
call on the serial queue.
Also, you are using barrier functions with a serial queue, which doesn't make any sense.
-(MyObject *) method1 {
//do something
dispatch_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
__block MyObject *obj;
dispatch_sync(self.queue, ^{
obj = [self.myarray objectAtIndex:0];
[self.myarray removeObjectAtIndex:0];
});
return obj;
}
-(void) method2:(MyObject *)object {
//do something
dispatch_async(self.queue, ^{
[self.myarray addObject:object];
dispatch_semaphore_signal(self.sem);
});
}
Upvotes: 1
Reputation: 3116
This kind of crash will happen when you are running a (vector)extension which is not supported on your CPU.
For example, in xcode 5 under "project-settings / build-settings / Code Generation, set the "Enable Additional Vector extensions" to "AVX2". Build your executable.
Now run it on an:
Upvotes: 0
Reputation: 29906
The sem
you created in your initialize
method is locally scoped to that method. It needs to be accessible to the other methods. If you have an iVar named sem
that you're attempting to assign, you're shadowing it by declaring a local variable in initialize
. (Same thing with queue
, by the way.)
Also, you appear to have a typo here, in that you call dispatch_semaphore_wait(sen, DISPATCH_TIME_FOREVER);
(i.e. se n vs se m)
Upvotes: 2