summaryrefslogtreecommitdiff
path: root/include/rtems/score/resource.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/rtems/score/resource.h')
-rw-r--r--include/rtems/score/resource.h211
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 */