Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: IOTimerEventSource behavior



Ah Lance welcome to the wonderful world of C++ ABI.

All non-static member functions in C++ have an implied 'first' argument that is a this pointer.

Hence the C++ function declaration of
    virtual void timeoutOccurred(IOTimerEventSource *sender);

is equivalent to the C declaration (with some poetic licence) :-
struct MY_CLASS_NAME_vtable {
struct MY_BASE_CLASS_vtable supervtable;
...
void (*timeoutOccurred)(MY_CLASS_NAME *this, IOTimerEventSource *sender);
...
);


In IOKit we chose to mostly use C function pointers in our Target/ Action/Parameter (TAP) idiom. This means that a conversion must be made from C++ to C, this is easy and direct for static member functions but is indirect for non-static member functions.

Now the C++ police get very upset with me when I start doing this, as they would like the flexibility of being able to arbitrarily change the ABI for non-static member functions. However they operate in a cloud-cuckoo-land where ever piece of C++ code is recompiled every time a new compiler is used or a header changes and sometimes even an implementation changes. This is implied with the egregious 'template' concept.

Unfortunately in the real world we had to provide binary compatibility in a cross module way. This implied that the C++ ABI was locked down from the moment that IOKit was released (causing angst). Since we have locked down this ABI it is perfectly safe to use our knowledge of the C++ ABI to call a member function from a C TAP. This also causes angst.

IYAI: There are to mechanisms in C++ for dealing with function pointers. The is the classic C style pointer to a function and there is the C++ pointer to member function. One would think that the conversion of C++ to C pointers would be unstable against new compilers and so it has proved at a source code level, however at the ABI level it has been rock solid. However the pointer to member function code broke at the ABI level, we needed get a compiler change made to support 10.0 & 10.1 drivers.

Godfrey

On 05/25/2005, at 12:03 , Lance Drake wrote:

The answer depends on what type of function timeoutOccured is.
Action is defined as
typedef void (*Action)(OSObject *owner, IOTimerEventSource *sender);
1> It is a static member function. In this case the owner and sender arguments are what you would expect.
2> You are using a normal member function or virtual member function. In this case the owner argument is passed to you in the 'this' pointer. Eg
virtual void timeoutOccurred(IOTimerEventSource *sender) is the correct declaration and you use OSCastMemberFunction to convert it into a IOTimerEventSource::Action, then in your
void MY_CLASS_NAME::(IOTimerEventSource *sender)
{
#if DEBUG
if (!OSDynamicCast(MY_CLASS_NAME, this))
; // We have a problem log it.
#endif
}
Godfrey




Hi Godfrey,

Thank you so much for responding. I note two interesting things in your example.

1) There is only one argument for the timeouthandler - which is different from the sample code where there are two arguments - as in "void TimerEventSample::timeoutHandler(OSObject *owner, IOTimerEventSource *sender)"

2) if (!OSDynamicCast(MY_CLASS_NAME, this)) refers to 'this' and not the incoming argument of 'sender'.

Is this all represented as you would wish?

Thanks,

Lance



_______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-drivers mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-drivers/email@hidden

This email sent to email@hidden
References: 
 >IOTimerEventSource behavior (From: Lance Drake <email@hidden>)
 >Re: IOTimerEventSource behavior (From: Godfrey van der Linden <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.