summaryrefslogtreecommitdiff
path: root/ACE/ace/Live_P_Strategy.inl
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Live_P_Strategy.inl')
-rw-r--r--ACE/ace/Live_P_Strategy.inl194
1 files changed, 194 insertions, 0 deletions
diff --git a/ACE/ace/Live_P_Strategy.inl b/ACE/ace/Live_P_Strategy.inl
new file mode 100644
index 00000000000..973de90d219
--- /dev/null
+++ b/ACE/ace/Live_P_Strategy.inl
@@ -0,0 +1,194 @@
+#include <climits>
+
+/*
+ Much of this is credited to "Efficient Distrubuted Deadlock
+ Avoidance with Liveness Guarentees" by Sanchez, Sipma, and Manna,
+ EMSOFT 2006
+*/
+
+struct AnnotationNode {
+ AnnotationNode()
+ :count(0), size(0), larger(0), larger_me(0), larger_left(INT_MAX), larger_right(INT_MAX)
+ {
+ }
+ int count; //number of processes with this annotation
+ int size; //total number of processes in subtree including this node
+ int larger; //minimum of larger_left, larger_me, and, larger_right
+ int larger_me;
+ int larger_left;
+ int larger_right;
+};
+
+class Live_P_Tree : public ACE_RB_Tree<int, AnnotationNode, ACE_Equal_To<int>, ACE_ThreadMutex> {
+
+public:
+ Live_P_Tree(int maxThreads);
+ virtual ~Live_P_Tree();
+ int bind(const int& ext_id,
+ const AnnotationNode& int_id,
+ ACE_RB_Tree_Node<int, AnnotationNode>*& entry);
+ int unbind (const EXT_ID &ext_id);
+ int calc_max() const;
+private:
+ void recalculate_augmentation(ACE_RB_Tree_Node<int, AnnotationNode>* nodePtr);
+ void recalculate_augmentation_up(ACE_RB_Tree_Node<int, AnnotationNode>* x);
+ int calc_max_i(ACE_RB_Tree_Node<int, AnnotationNode>* nodePtr, int extra) const;
+ static int MIN(int a, int b) { return (a<b)?a:b; }
+ static int MIN_THREE(int a, int b, int c) {
+ return (a<b)?MIN(a,c):MIN(b,c);
+ }
+ int T_;
+};
+
+ACE_INLINE
+Live_P_Tree::Live_P_Tree(int maxThreads)
+:ACE_RB_Tree(),
+ T_(maxThreads) {
+
+}
+
+ACE_INLINE
+Live_P_Tree::~Live_P_Tree() {
+}
+
+ACE_INLINE
+Live_P_Tree::bind(const int& ext_id)
+{
+ ACE_RB_Tree_Node<int, AnnotationNode>* entry = 0;
+ RB_SearchResult result = LEFT;
+ entry = find_node (ext_id, result);
+ // If there is a matching node, don't add a new one, just mod the existing one
+ if (entry && result == EXACT) {
+ entry->item.count++;
+ } else {
+ RB_Tree::bind(ext_id, AnnotationNode(), entry);
+ }
+ recalculate_augmentation_up(entry);
+
+}
+
+ACE_INLINE
+Live_P_Tree::unbind(const int& ext_id)
+{
+ ACE_RB_Tree_Node<int, AnnotationNode>* entry = 0;
+ RB_SearchResult result = LEFT;
+ entry = find_node (ext_id, result);
+ // If there is a matching node, don't add a new one, just mod the existing one
+ if (entry && result == EXACT) {
+ entry->item.count--;
+ if (count == 0) {
+ entry = entry->parent;
+ RB_Tree::unbind(ext_id);
+ }
+ } else {
+ //exception? probably bad if we try to unbind something not in the tree
+ }
+ if (entry) {
+ recalculate_augmentation_up(entry);
+ }
+
+}
+
+
+ACE_INLINE void
+Live_P_Tree::recalculate_augmentation(ACE_RB_Tree_Node<int, AnnotationNode>* nodePtr) {
+
+ AnnotationNode& node = n->item;
+ AnnotationNode& left = nodePtr->left ? AnnotationNode() : nodePtr->left->item;
+ AnnotationNode& right = nodePtr->right ? AnnotationNode() : nodePtr->right->item;
+
+ // (1) size
+ node.size = left.size + right.size + node.count;
+
+ // (2) larger_me
+ node.larger_me = ProcessCount(T_) - (node.count + right.size/* + node.alpha*/);
+ //^^^^^^^^^^^^^ not sure what this is for
+ // (3) larger_right
+ Node.larger_right = right.larger;
+
+ // (4) larger_left
+ Node.larger_left = left.larger - (right.size + node.count);
+
+ //(5) larger
+ Node.larger = MIN_THREE(x.larger_me, x.larger_left, x.larger_right);
+}
+
+ACE_INLINE void
+Live_P_Tree::recalculate_augmentation_up(ACE_RB_Tree_Node<int, AnnotationNode>* x) {
+ while (x) {
+ recalculate_augmentation(x);
+ x = x->parent;
+ }
+}
+
+ACE_INLINE int
+Live_P_Tree::calc_max() const {
+ //note: need to add get_root method to RB_Tree
+ return calc_max_i(get_root(), 0);
+}
+
+ACE_INLINE int
+Live_P_Tree::calc_max_i(ACE_RB_Tree_Node<int, AnnotationNode>* nodePtr, int extra) const {
+ AnnotationNode n = nodePtr->item;
+
+ if ( n.larger_left - extra==0) {
+ return calc_max_i(nodePtr->left, extra + nodePtr->right->item.size + n.count); }
+ else if (n->larger_me - extra==0) { return (nodePtr->key); }
+ else if (n->larger_right - extra==0) { return calc_max_i(nodePtr->right, extra); }
+ else { return T_; }
+}
+
+template <typename AnnotationId>
+ACE_INLINE
+Live_P_Strategy<AnnotationId>::Live_P_Strategy(int maxThreads)
+:DA_Strategy_Base(maxThreads)
+{
+}
+
+template <typename AnnotationId>
+ACE_INLINE
+Live_P_Strategy<AnnotationId>::~Live_P_Strategy()
+{
+}
+
+
+
+template <typename AnnotationId>
+ACE_INLINE
+bool
+Live_P_Strategy<AnnotationId>::is_deadlock_potential(AnnotationId handle)
+{
+ int min_illegal = getMaxThreads();
+ int annotation = getAnnotation(handle);
+
+ if (!min_ilegal_is_computed_)
+ {
+ if (tree_->current_size() > 1)
+ {
+ min_ilegal_ = calc_max();
+ }
+ min_ilegal_is_computed_ = true;
+ }
+
+ return annotation >= min_ilegal_;
+}
+
+template <typename AnnotationId>
+ACE_INLINE
+void
+Live_P_Strategy<AnnotationId>::grant(AnnotationId handle)
+{
+ int annotation = getAnnotation(handle);
+ tree_pimpl_->bind(annotation);
+ min_ilegal_is_computed_ = false;
+}
+
+template <typename AnnotationId>
+ACE_INLINE
+void
+Live_P_Strategy<AnnotationId>::release(AnnotationId handle)
+{
+ min_ilegal_is_computed_ = false;
+ int annotation = getAnnotation(handle);
+ tree_pimpl_->unbind(annotation);
+} \ No newline at end of file