does method invocation involve a lock?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

does method invocation involve a lock?

Tom Sheffler
This question is for my own research: I’m curious about whether invoking [obj method] can block.  If obj is allocated, and method is simple, does method invocation involve a lock.

I think the answer is YES.  But I looked at the source code for objc_msgSend and didn’t see anything that looked like it acquired a lock.

Thanks for any insights.
-Tom


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: does method invocation involve a lock?

Andreas Fink-2

If I remember correctly, methods are not locked. They can run in parallel multiple times in multiple threads.
The exception are properties with the atomic attribute where the compiler synthesizes the getter/setter and thus makes sure that a getter and setter dont conflict with each other

        @property(atomic)

does this (which is default if I'm not mistaken). But that doesn't apply to methods.



> On 21 Sep 2018, at 16:49, Tom Sheffler <[hidden email]> wrote:
>
> This question is for my own research: I’m curious about whether invoking [obj method] can block.  If obj is allocated, and method is simple, does method invocation involve a lock.
>
> I think the answer is YES.  But I looked at the source code for objc_msgSend and didn’t see anything that looked like it acquired a lock.
>
> Thanks for any insights.
> -Tom
>
>
> _______________________________________________
> Discuss-gnustep mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/discuss-gnustep



_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: does method invocation involve a lock?

Richard Frith-Macdonald-9
In reply to this post by Tom Sheffler
> On 21 Sep 2018, at 15:49, Tom Sheffler <[hidden email]> wrote:
>
> This question is for my own research: I’m curious about whether invoking [obj method] can block.  If obj is allocated, and method is simple, does method invocation involve a lock.
>
> I think the answer is YES.  But I looked at the source code for objc_msgSend and didn’t see anything that looked like it acquired a lock.

The answer is usually NO, but the first time you send any method to a class the +initialize method of that class is implicitly called, and that operation is implicitly lock protected.  If you are worried about that, the simple solution is to make sure that classes you are concerned about are initialised at the start of your program (eg by calling the +class method) , so that code executing later can be confident that there won't be unexpected blocking.
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: does method invocation involve a lock?

David Chisnall-7
In reply to this post by Tom Sheffler
On 21/09/2018 15:49, Tom Sheffler wrote:
> This question is for my own research: I’m curious about whether invoking [obj method] can block.  If obj is allocated, and method is simple, does method invocation involve a lock.

If obj is allocated, obj has not had its isa pointer swizzled to a class
that has not received any messages, and the class of obj implements the
method, then no, the message send itself will not block.

Message sends in the fast path just look up the implementation in the
dtable and jump there.  If the method does not exist, then the first
check will see if there is a dtable for the class (dtables are lazily
allocated on first message send to the class or an instance of the
class).  If there isn't one, then the runtime will try to allocate one
and may need to send a +initialize message to the object.

The +initialize message guarantees that no messages will be sent to the
class or its instances from any other thread until the +initialize
method has returned.  This gets quite exciting inside the runtime if
+initialize throws an exception.  This atomicity guarantee is important
for implementing singletons, because it means that you can have a class
that has methods like this:

```objc
static Singleton *sharedInstance;
+(void)initialize
{
        sharedInstance = [self new];
}
+(Singleton*)sharedInstance
{
        return sharedInstance;
}
```

There is no locking in the +sharedInstance method and none is required,
because the runtime guarantees that +initialize will be called precisely
once before any calls to +sharedInstance.

The other situation where locking can occur is if the message send
invokes any forwarding mechanisms.  For example, with LanguageKit we had
a mode where if you sent a message to an object it would pop up a code
editor, ask you to provide an implementation of the method, JIT compile
it, insert it into the class, and then return the method.  This, of
course, requires blocking the calling thread and so acquires a lock.

Any of the methods such as -forwardingTargetForSelector: and
+instanceMethodForSelector: may acquire locks and can be invoked in
between a caller's message send expression and flow control landing in
the method implementation.

David

_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: does method invocation involve a lock?

Tom Sheffler
Thank you for the great information.
FYI - In my use case, I am most interested in the ‘steady-state’ of the program after all classes have been loaded.
Cheers - T

> On Sep 21, 2018, at 8:26 AM, David Chisnall <[hidden email]> wrote:
>
> On 21/09/2018 15:49, Tom Sheffler wrote:
>> This question is for my own research: I’m curious about whether invoking [obj method] can block.  If obj is allocated, and method is simple, does method invocation involve a lock.
>
> If obj is allocated, obj has not had its isa pointer swizzled to a class that has not received any messages, and the class of obj implements the method, then no, the message send itself will not block.
>
> Message sends in the fast path just look up the implementation in the dtable and jump there.  If the method does not exist, then the first check will see if there is a dtable for the class (dtables are lazily allocated on first message send to the class or an instance of the class).  If there isn't one, then the runtime will try to allocate one and may need to send a +initialize message to the object.
>
> The +initialize message guarantees that no messages will be sent to the class or its instances from any other thread until the +initialize method has returned.  This gets quite exciting inside the runtime if +initialize throws an exception.  This atomicity guarantee is important for implementing singletons, because it means that you can have a class that has methods like this:
>
> ```objc
> static Singleton *sharedInstance;
> +(void)initialize
> {
> sharedInstance = [self new];
> }
> +(Singleton*)sharedInstance
> {
> return sharedInstance;
> }
> ```
>
> There is no locking in the +sharedInstance method and none is required, because the runtime guarantees that +initialize will be called precisely once before any calls to +sharedInstance.
>
> The other situation where locking can occur is if the message send invokes any forwarding mechanisms.  For example, with LanguageKit we had a mode where if you sent a message to an object it would pop up a code editor, ask you to provide an implementation of the method, JIT compile it, insert it into the class, and then return the method.  This, of course, requires blocking the calling thread and so acquires a lock.
>
> Any of the methods such as -forwardingTargetForSelector: and +instanceMethodForSelector: may acquire locks and can be invoked in between a caller's message send expression and flow control landing in the method implementation.
>
> David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep