Interval *remove_interval(Interval **root, Interval *node) { Interval *snip, *child; /* If the node to remove does not have two children, we will snip it, otherwise we will swap it with its successor and snip that one */ if (!node->left_child || !node->right_child) { snip = node; } else { snip = next_interval(node); } /* If the node to snip has a child, make its parent link point to the snipped node's parent */ if (snip->left_child) { child = snip->left_child; } else { child = snip->right_child; } if (child) { child->parent = snip->parent; } /* If the snipped node has no parent, it is the root node and we use the provided root pointer to point to the child. Otherwise, we find if the snipped node was a left or right child and set the appropriate link in the parent node */ if (!snip->parent) { *root = child; } else if (snip == snip->parent->left_child) { snip->parent->left_child = child; } else { snip->parent->right_child = child; } /* Swap the contents of the node passed in to remove with the one chosen to be snipped */ if (snip != node) { void *old_data = node->data; node->low = snip->low; node->high = snip->high; node->data = snip->data; snip->data = old_data; } return snip; }
void *monitor_run(void *ptr) { struct mt_context *thread_context = (struct mt_context *) ptr; struct monitor_ctx *monitor_context = (struct monitor_ctx *) thread_context->param; struct rtgtargets *targets = monitor_context->targets; struct rtgconf *config = monitor_context->config; unsigned poll_interval = config->interval; /* Use the specified next iteration value. * If it is set to zero, we'll run as soon as possible. */ curms_t next_iteration = monitor_context->next_iteration; curms_t this_iteration = 0; struct timespec loopdelay = { 0, 250 * 1000 * 1000 }; nanosleep(&loopdelay, NULL); while (!thread_stop_requested) { curms_t now = curms(); /* If there are no threads running and it's time for a new iteration, * start a new iteration. */ if (active_threads == 0 && now >= next_iteration) { start_iteration(targets); this_iteration = now; next_iteration = next_interval(now, poll_interval); } /* Give the threads a chance to start, so we don't * mistakenly think they're all done already. */ nanosleep(&loopdelay, NULL); /* If there are no threads running, and we have started a iteration, * then we are done. End the iteration. */ if (active_threads == 0 && this_iteration) { end_iteration(next_iteration, this_iteration); this_iteration = 0; } } /* Save next iteration value, so we can reuse it if necessary. */ monitor_context->next_iteration = next_iteration; return NULL; }