Small doubt in how chain works in RTEMS

Gedare Bloom gedare at rtems.org
Fri Jul 24 17:59:29 UTC 2020


On Fri, Jul 24, 2020 at 8:27 AM Richi Dubey <richidubey at gmail.com> wrote:
>
> Hi,
>
> I have a doubt regarding this.
>
> We do
>   rtems_chain_append( &chain1, &node1.Node );
>
> And get the node pointer when we use:
>   rtems_chain_node    *p= rtems_chain_first(&chain1),
>
> After this, Do we really need to use the CONTAINER_OF and other such methods?
>
> Can we not simply do:
>   test_node node1=(test_node*) p;
>
>
> Since our structure test_node has the  rtems_chain_node Node; as its first variable, it should work, right?
>

If the Node is the first variable, then it just works without
container-of. But then you need to make sure no one will change the
structure definition (at least, make a comment about it).

The RTEMS Object model makes use of this simplification. The base
'Object' includes a chain Node at the start of the struct, so that
when you include an Object at the start of a struct, you automatically
get a Node at the base address of an instantiated struct.

The downsides of this assumption are that you have to make the struct
layout rigid (as mentioned), and you also can't reuse the same code
base with nodes belonging to multiple data structures, e.g., you can't
put a single struct on two chains, if both chains assume they get the
base address of the struct, since only one Node can possibly be at the
base of the structure.

I hope that makes sense.

> References:
> https://stackoverflow.com/q/3766229
> https://git.rtems.org/rtems/tree/cpukit/score/src/scheduleredfsmp.c#n178
>
> Please let me know.
> Thanks.
>
> On Fri, Jun 12, 2020 at 7:28 PM Gedare Bloom <gedare at rtems.org> wrote:
>>
>> On Fri, Jun 12, 2020 at 7:50 AM Richi Dubey <richidubey at gmail.com> wrote:
>> >
>> > Hi everyone,
>> >
>> > While going through testsuites/sptests/spchain/init.c, I noticed the following code:
>> >
>> > -----------------------------------------------
>> > rtems_task Init(
>> >   rtems_task_argument ignored
>> > )
>> > {
>> >   rtems_chain_control  chain1;
>> >   rtems_chain_node    *p;
>> >   test_node            node1, node2;
>> >   int                  id;
>> >
>> >   TEST_BEGIN();
>> >
>> >   puts( "Init - Initialize chain empty" );
>> >   rtems_chain_initialize_empty( &chain1 );
>> >   rtems_chain_initialize_node( &node1.Node );
>> >   rtems_chain_initialize_node( &node2.Node );
>> >
>> >   /* verify that the chain append and insert work */
>> >   puts( "INIT - Verify rtems_chain_insert" );
>> >   node1.id = 1;
>> >   node2.id = 2;
>> >   rtems_chain_append( &chain1, &node1.Node );
>> >   rtems_chain_insert( &node1.Node, &node2.Node );
>> >
>> >   for ( p = rtems_chain_first(&chain1), id = 1 ;
>> >         !rtems_chain_is_tail(&chain1, p) ;
>> >         p = p->next , id++ ) {
>> >      test_node *t = (test_node *)p;
>> >      if ( id > 2 ) {
>> >        puts( "INIT - TOO MANY NODES ON CHAIN" );
>> >        rtems_test_exit(0);
>> >      }
>> >      if ( t->id != id ) {
>> >        puts( "INIT - ERROR ON CHAIN ID MISMATCH" );
>> >        rtems_test_exit(0);
>> >      }
>> >   }
>> >
>> > -----------------------------------------
>> > Where test_node is defined as:
>> >
>> > typedef struct {
>> >   rtems_chain_node Node;
>> >   int              id;
>> > } test_node;
>> >
>> > ----------------------------------
>> >
>> >
>> > Now when we are inserting or appending our structure into the chain, we are only inserting the part of strucuture correspoing to rtems_chain_node, i.e.:
>> >   rtems_chain_append( &chain1, &node1.Node );
>> >   rtems_chain_insert( &node1.Node, &node2.Node );
>> >
>> > So, how do we ever get our node1.id ? How can we (or how do we ever) access our data from the structure when we are only adding some part of the structure into the node?
>> >
>> > I hope my doubt is not too vague.
>> >
>> Hi Richi,
>>
>> This is an old C programming trick.
>>
>> This looks like a reasonable explanation:
>> https://medium.com/@414apache/kernel-data-structures-linkedlist-b13e4f8de4bf
>>
>> Feel free to write something for rtems ;)
>>
>> > Thanks,
>> > Richi.
>> >
>> >
>> > _______________________________________________
>> > devel mailing list
>> > devel at rtems.org
>> > http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list