diff options
Diffstat (limited to 'include/rtems/score/resource.h')
-rw-r--r-- | include/rtems/score/resource.h | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/include/rtems/score/resource.h b/include/rtems/score/resource.h new file mode 100644 index 0000000000..ecf84a7275 --- /dev/null +++ b/include/rtems/score/resource.h @@ -0,0 +1,211 @@ +/* + * 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. + */ + +#ifndef _RTEMS_SCORE_RESOURCE_H +#define _RTEMS_SCORE_RESOURCE_H + +#include <rtems/score/basedefs.h> +#include <rtems/score/chain.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup ScoreResource Resource Handler + * + * @ingroup Score + * + * @brief Support for resource dependency management. + * + * A resource is something that has at most one owner at a time and may have + * multiple rivals in case an owner is present. The owner and rivals are + * impersonated via resource nodes. A resource is represented via the resource + * control structure. The resource controls and nodes are organized as trees. + * It is possible to detect deadlocks via such a resource tree. The + * _Resource_Iterate() function can be used to iterate through such a resource + * tree starting at a top node. + * + * The following diagram shows an example resource tree with sixteen resource + * nodes n0 up to n15 and sixteen resources r0 up to r15. The root of this + * tree is n0. As a use case threads can be associated with resource nodes. + * In this case a thread represented by node n0 owns resources r0, r1, r2, r3, + * r6, r11 and r12 and is in the ready state. The threads represented by nodes + * n1 up to n15 wait directly or indirectly via resources owned by n0 and are + * in a blocked state. + * + * @dot + * digraph { + * n0 [style=filled, fillcolor=green]; + * n0 -> r0; + * subgraph { + * rank=same; + * n1 [style=filled, fillcolor=green]; + * r0 -> n1; + * n2 [style=filled, fillcolor=green]; + * n1 -> n2; + * n4 [style=filled, fillcolor=green]; + * n2 -> n4; + * n6 [style=filled, fillcolor=green]; + * n4 -> n6; + * n8 [style=filled, fillcolor=green]; + * n6 -> n8; + * n15 [style=filled, fillcolor=green]; + * n8 -> n15; + * } + * n1 -> r5; + * subgraph { + * rank=same; + * n3 [style=filled, fillcolor=green]; + * r5 -> n3; + * n12 [style=filled, fillcolor=green]; + * n3 -> n12; + * } + * n3 -> r10; + * r10 -> r13; + * r13 -> r15; + * subgraph { + * rank=same; + * n10 [style=filled, fillcolor=green]; + * r15 -> n10; + * } + * r5 -> r7; + * subgraph { + * rank=same; + * n11 [style=filled, fillcolor=green]; + * r7 -> n11; + * n14 [style=filled, fillcolor=green]; + * n11 -> n14; + * } + * n14 -> r4; + * r7 -> r8; + * subgraph { + * rank=same; + * n13 [style=filled, fillcolor=green]; + * r8 -> n13; + * } + * r8 -> r9; + * n8 -> r14; + * r0 -> r1; + * subgraph { + * rank=same; + * n7 [style=filled, fillcolor=green]; + * r1 -> n7; + * } + * r1 -> r2; + * r2 -> r3; + * r3 -> r6; + * r6 -> r11; + * r11 -> r12; + * subgraph { + * rank=same; + * n5 [style=filled, fillcolor=green]; + * r12 -> n5; + * n9 [style=filled, fillcolor=green]; + * n5 -> n9; + * } + * } + * @enddot + * + * The following example illustrates a deadlock situation. The root of the + * tree tries to get ownership of a resource owned by one of its children. + * + * @dot + * digraph { + * n0 [style=filled, fillcolor=green]; + * n0 -> r0; + * subgraph { + * rank=same; + * n1 [style=filled, fillcolor=green]; + * r0 -> n1; + * } + * n1 -> r1; + * n0 -> r1 [label=deadlock, style=dotted]; + * } + * @enddot + * + * @{ + */ + +typedef struct Resource_Node Resource_Node; + +typedef struct Resource_Control Resource_Control; + +/** + * @brief Resource node to reflect ownership of resources and a dependency on a + * resource. + */ +struct Resource_Node { + /** + * @brief Node to build a chain of rivals depending on a resource. + * + * @see Resource_Control::Rivals. + */ + Chain_Node Node; + + /** + * @brief A chain of resources owned by this node. + * + * @see Resource_Control::Node. + */ + Chain_Control Resources; + + /** + * @brief Reference to a resource in case this node has to wait for ownership + * of this resource. + * + * It is @c NULL in case this node has no open resource dependency. + */ + Resource_Control *dependency; + + /** + * @brief Reference to the root of the resource tree. + * + * The root references itself. + */ + Resource_Node *root; +}; + +/** + * @brief Resource control to manage ownership and rival nodes depending on a + * resource. + */ +struct Resource_Control { + /** + * @brief Node to build a chain of resources owned by a resource node. + * + * @see Resource_Node::Resources. + */ + Chain_Node Node; + + /** + * @brief A chain of rivals waiting for resource ownership. + * + * @see Resource_Node::Node. + */ + Chain_Control Rivals; + + /** + * @brief The owner of this resource. + */ + Resource_Node *owner; +}; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_SCORE_RESOURCE_H */ |