source: rtems/cpukit/score/src/resourceiterate.c @ 54cf0e34

4.115
Last change on this file since 54cf0e34 was 40dcafa, checked in by Sebastian Huber <sebastian.huber@…>, on 08/02/14 at 14:22:31

Add and use RTEMS_CONTAINER_OF()

  • Property mode set to 100644
File size: 2.9 KB
Line 
1/*
2 * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <rtems/score/resourceimpl.h>
16
17static Resource_Control *_Resource_Rival_head_to_resource( Chain_Node *head )
18{
19  return RTEMS_CONTAINER_OF( head, Resource_Control, Rivals.Head.Node );
20}
21
22static Resource_Node *_Resource_Resource_tail_to_rival( Chain_Node *tail )
23{
24  return RTEMS_CONTAINER_OF( tail, Resource_Node, Resources.Tail.Node );
25}
26
27void _Resource_Iterate(
28  Resource_Node         *top,
29  Resource_Node_visitor  visitor,
30  void                  *arg
31)
32{
33  Chain_Node *resource_tail = _Chain_Tail( &top->Resources );
34  Resource_Control *resource =
35    (Resource_Control *) _Chain_Head( &top->Resources );
36
37  Chain_Node *rival_stop = NULL;
38  Resource_Node *rival = NULL;
39
40  enum {
41    NODE_FORWARD,
42    NODE_BACKWARD,
43    RESOURCE_FORWARD
44  } dir = RESOURCE_FORWARD;
45
46  bool stop = false;
47
48  do {
49    switch ( dir ) {
50      case NODE_FORWARD:
51        while ( !stop && &rival->Node != rival_stop ) {
52          Resource_Node *current = rival;
53
54          rival = (Resource_Node *) _Chain_Next( &rival->Node );
55          stop = ( *visitor )( current, arg );
56        }
57
58        rival_stop = _Chain_Head( &resource->Rivals );
59        dir = NODE_BACKWARD;
60        break;
61      case NODE_BACKWARD:
62        rival = (Resource_Node *) _Chain_Previous( &rival->Node );
63
64        while (
65          &rival->Node != rival_stop
66            && _Chain_Is_empty( &rival->Resources )
67        ) {
68          rival = (Resource_Node *) _Chain_Previous( &rival->Node );
69        }
70
71        if ( &rival->Node != rival_stop ) {
72          resource_tail = _Chain_Tail( &rival->Resources );
73          resource = (Resource_Control *) _Chain_Head( &rival->Resources );
74        } else {
75          resource = _Resource_Rival_head_to_resource( rival_stop );
76          resource_tail = _Chain_Tail( &resource->owner->Resources );
77        }
78
79        dir = RESOURCE_FORWARD;
80        break;
81      case RESOURCE_FORWARD:
82        resource = (Resource_Control *) _Chain_Next( &resource->Node );
83
84        while (
85          &resource->Node != resource_tail
86            && _Chain_Is_empty( &resource->Rivals )
87        ) {
88          resource = (Resource_Control *) _Chain_Next( &resource->Node );
89        }
90
91        if ( &resource->Node != resource_tail ) {
92          rival_stop = _Chain_Tail( &resource->Rivals );
93          rival = (Resource_Node *) _Chain_First( &resource->Rivals );
94          dir = NODE_FORWARD;
95        } else {
96          rival = _Resource_Resource_tail_to_rival( resource_tail );
97          rival_stop = _Chain_Head( &rival->dependency->Rivals );
98          dir = NODE_BACKWARD;
99        }
100
101        break;
102    }
103  } while ( !stop && rival != top );
104}
Note: See TracBrowser for help on using the repository browser.