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 | |
---|
17 | static Resource_Control *_Resource_Rival_head_to_resource( Chain_Node *head ) |
---|
18 | { |
---|
19 | return RTEMS_CONTAINER_OF( head, Resource_Control, Rivals.Head.Node ); |
---|
20 | } |
---|
21 | |
---|
22 | static Resource_Node *_Resource_Resource_tail_to_rival( Chain_Node *tail ) |
---|
23 | { |
---|
24 | return RTEMS_CONTAINER_OF( tail, Resource_Node, Resources.Tail.Node ); |
---|
25 | } |
---|
26 | |
---|
27 | void _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 | } |
---|