kernelnewbies.kernelnewbies.org archive mirror
 help / color / mirror / Atom feed
* Struct Inheritance in drivers/ata/
@ 2011-05-26 20:46 Peter Hamilton
  2011-05-27  1:23 ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Hamilton @ 2011-05-26 20:46 UTC (permalink / raw)
  To: kernelnewbies

The code in drivers/ata/ uses an implementation of inheritance that I have
not seen before.  It's only briefly explained in the header file (
include/linux/libata.h:885):

/*
 * ->inherits must be the last field and all the preceding
 * fields must be pointers.
 */

The structs are then initialized with .inherits assigned first:

drivers/ata/sata_nv.c:475

static struct ata_port_operations nv_nf2_ops = {

        .inherits               = &nv_generic_ops,
        .freeze                 = nv_nf2_freeze,

        .thaw                   = nv_nf2_thaw,

};


Is this actually implementing inheritance?  Why do all preceding fields need
to be pointers?

As far as I can tell, this style is only found in the ata drivers.

Could anyone explain how this works?

Thanks,
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110526/3c1f4f32/attachment.html 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Struct Inheritance in drivers/ata/
  2011-05-26 20:46 Struct Inheritance in drivers/ata/ Peter Hamilton
@ 2011-05-27  1:23 ` Greg KH
  2011-05-27  2:20   ` Peter Hamilton
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2011-05-27  1:23 UTC (permalink / raw)
  To: kernelnewbies

On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote:
> The code in drivers/ata/ uses an implementation of inheritance that I have not
> seen before. ?It's only briefly explained in the header file ( include/linux/
> libata.h:885):
> 
> /* ?
> ?* ->inherits must be the last field and all the preceding
> ?* fields must be pointers.
> ?*/
> 
> The structs are then initialized with .inherits assigned first:
> 
> drivers/ata/sata_nv.c:475
> 
> static struct ata_port_operations nv_nf2_ops = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
> ? ? ? ? .inherits ? ? ? ? ? ? ? = &nv_generic_ops,
> ? ? ? ? .freeze ? ? ? ? ? ? ? ? = nv_nf2_freeze, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
> ? ? ? ? .thaw ? ? ? ? ? ? ? ? ? = nv_nf2_thaw, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
> }; ? ? ?
> 
> 
> Is this actually implementing inheritance? ?Why do all preceding fields need to
> be pointers?
> 
> As far as I can tell, this style is only found in the ata drivers. ?

I think you are right, but more subsystems need to emulate it, it is
very powerful and works very well.  I have been wanting to convert the
usb-serial layer to use the same thing one of these days.

> Could anyone explain how this works?

The code is all there that shows it, but basically the driver is telling
the core to "use this type of functions, but if I set any others, use
them instead."  It's a nicer way of doing inheritance in C than we do in
other places in the kernel where we are a bit more "verbose" in making
it happen.

hope this helps,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Struct Inheritance in drivers/ata/
  2011-05-27  1:23 ` Greg KH
@ 2011-05-27  2:20   ` Peter Hamilton
  2011-05-27  4:49     ` Ankit Jain
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Hamilton @ 2011-05-27  2:20 UTC (permalink / raw)
  To: kernelnewbies

I see that it works, but I'm not exactly following how.  Maybe I just don't
have enough C experience.  But I can't seem to duplicate that functionality.


I understand the way I've normally seen inheritance, where:

struct Child {
  struct Parent p;
  int somethingOnlyForChildren;
}

Or something similar.  Then the Child struct can be casted as a Parent, and
since there is no padding before the first piece of data in a struct, every
parent attribute is accessed as though the struct were a Parent.

I see how it all lines up in memory, but in the case of the kernel code I
can't quite follow it.  Wouldn't everything assigned to 'inherits' be so
much farther down in memory?  I feel like I'm missing something.  Is there a
special way they all need to be accessed?

- Peter

On Thu, May 26, 2011 at 7:23 PM, Greg KH <greg@kroah.com> wrote:

> On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote:
> > The code in drivers/ata/ uses an implementation of inheritance that I
> have not
> > seen before.  It's only briefly explained in the header file (
> include/linux/
> > libata.h:885):
> >
> > /*
> >  * ->inherits must be the last field and all the preceding
> >  * fields must be pointers.
> >  */
> >
> > The structs are then initialized with .inherits assigned first:
> >
> > drivers/ata/sata_nv.c:475
> >
> > static struct ata_port_operations nv_nf2_ops = {
>
> >         .inherits               = &nv_generic_ops,
> >         .freeze                 = nv_nf2_freeze,
>
> >         .thaw                   = nv_nf2_thaw,
>
> > };
> >
> >
> > Is this actually implementing inheritance?  Why do all preceding fields
> need to
> > be pointers?
> >
> > As far as I can tell, this style is only found in the ata drivers.
>
> I think you are right, but more subsystems need to emulate it, it is
> very powerful and works very well.  I have been wanting to convert the
> usb-serial layer to use the same thing one of these days.
>
> > Could anyone explain how this works?
>
> The code is all there that shows it, but basically the driver is telling
> the core to "use this type of functions, but if I set any others, use
> them instead."  It's a nicer way of doing inheritance in C than we do in
> other places in the kernel where we are a bit more "verbose" in making
> it happen.
>
> hope this helps,
>
> greg k-h
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110526/a66e84ee/attachment-0001.html 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Struct Inheritance in drivers/ata/
  2011-05-27  2:20   ` Peter Hamilton
@ 2011-05-27  4:49     ` Ankit Jain
  0 siblings, 0 replies; 4+ messages in thread
From: Ankit Jain @ 2011-05-27  4:49 UTC (permalink / raw)
  To: kernelnewbies

On Fri, May 27, 2011 at 7:50 AM, Peter Hamilton
<peterghamilton@gmail.com> wrote:
> I see that it works, but I'm not exactly following how. ?Maybe I just don't
> have enough C experience. ?But I can't seem to duplicate that functionality.
>
> I understand the way I've normally seen inheritance, where:
> struct Child {
> ? struct Parent p;
> ? int somethingOnlyForChildren;
> }
>
> Or something similar. ?Then the Child struct can be casted as a Parent, and
> since there is no padding before the first piece of data in a struct, every
> parent attribute is accessed as though the struct were a Parent.
> I see how it all lines up in memory, but in the case of the kernel code I
> can't quite follow it. ?Wouldn't everything assigned to 'inherits' be so
> much farther down in memory? ?I feel like I'm missing something. ?Is there a
> special way they all need to be accessed?

I think an example should clear this.

//class type
struct klass {
  void (*foo)();
  void (*bar)(int x);

  struct parent *inherits;
};

//object 1, parent
struct klass klass_a {
   //no .inherits
   .foo = a_foo,
   .bar = a_bar,
};

//object 2, child, inherits klass_a
struct klass klass_b {
   .inherits = &klass_a,
   .foo = b_foo,
};

klass_b inherits klass_a. klass_b "overrides" only foo "member", so klass_b
will have the new overriden foo (b_foo), and will "inherit" bar from its parent,
a_bar. The relationship is setup as shown above, by using the .inherits field,
and final pointers are setup by ata_finalize_port_ops in
drivers/ata/libata-core.c .

Once the pointers of the various objects have been set to their final values,
while honoring the inheritance relationship, the 'inherits' field is
no longer required,
and the pointers can be used directly.

This function is called whenever an ata host is started.
See the comments on that function and read the code, should make things
clearer.

I also just read that code and then replying here, so I could have missed or
misunderstood something.

-Ankit

> - Peter
> On Thu, May 26, 2011 at 7:23 PM, Greg KH <greg@kroah.com> wrote:
>>
>> On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote:
>> > The code in drivers/ata/ uses an implementation of inheritance that I
>> > have not
>> > seen before. ?It's only briefly explained in the header file (
>> > include/linux/
>> > libata.h:885):
>> >
>> > /*
>> > ?* ->inherits must be the last field and all the preceding
>> > ?* fields must be pointers.
>> > ?*/
>> >
>> > The structs are then initialized with .inherits assigned first:
>> >
>> > drivers/ata/sata_nv.c:475
>> >
>> > static struct ata_port_operations nv_nf2_ops = {
>> >
>> > ? ? ? ? .inherits ? ? ? ? ? ? ? = &nv_generic_ops,
>> > ? ? ? ? .freeze ? ? ? ? ? ? ? ? = nv_nf2_freeze,
>> >
>> > ? ? ? ? .thaw ? ? ? ? ? ? ? ? ? = nv_nf2_thaw,
>> >
>> > };
>> >
>> >
>> > Is this actually implementing inheritance? ?Why do all preceding fields
>> > need to
>> > be pointers?
>> >
>> > As far as I can tell, this style is only found in the ata drivers.
>>
>> I think you are right, but more subsystems need to emulate it, it is
>> very powerful and works very well. ?I have been wanting to convert the
>> usb-serial layer to use the same thing one of these days.
>>
>> > Could anyone explain how this works?
>>
>> The code is all there that shows it, but basically the driver is telling
>> the core to "use this type of functions, but if I set any others, use
>> them instead." ?It's a nicer way of doing inheritance in C than we do in
>> other places in the kernel where we are a bit more "verbose" in making
>> it happen.
>>
>> hope this helps,
>>
>> greg k-h
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-05-27  4:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-26 20:46 Struct Inheritance in drivers/ata/ Peter Hamilton
2011-05-27  1:23 ` Greg KH
2011-05-27  2:20   ` Peter Hamilton
2011-05-27  4:49     ` Ankit Jain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).