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