+ * \brief This function is called periodically. It checks the immediate
+ * successor of the current node.
+ * \param node the current node
+ */
+static void stabilize(node_t node)
+{
+ XBT_DEBUG("Stabilizing node");
+
+ // get the predecessor of my immediate successor
+ int candidate_id;
+ int successor_id = node->fingers[0].id;
+ if (successor_id != node->id) {
+ candidate_id = remote_get_predecessor(node, successor_id);
+ }
+ else {
+ candidate_id = node->pred_id;
+ }
+
+ // this node is a candidate to become my new successor
+ if (candidate_id != -1
+ && is_in_interval(candidate_id, node->id + 1, successor_id - 1)) {
+ set_finger(node, 0, candidate_id);
+ }
+ if (successor_id != node->id) {
+ remote_notify(node, successor_id, node->id);
+ }
+}
+
+/**
+ * \brief Notifies the current node that its predecessor may have changed.
+ * \param node the current node
+ * \param candidate_id the possible new predecessor
+ */
+static void notify(node_t node, int predecessor_candidate_id) {
+
+ if (node->pred_id == -1
+ || is_in_interval(predecessor_candidate_id, node->pred_id + 1, node->id - 1)) {
+
+ set_predecessor(node, predecessor_candidate_id);
+ print_finger_table(node);
+ }
+ else {
+ XBT_DEBUG("I don't have to change my predecessor to %d", predecessor_candidate_id);
+ }
+}
+
+/**
+ * \brief Notifies a remote node that its predecessor may have changed.
+ * \param node the current node
+ * \param notify_id id of the node to notify
+ * \param candidate_id the possible new predecessor
+ */
+static void remote_notify(node_t node, int notify_id, int predecessor_candidate_id) {
+
+ task_data_t req_data = xbt_new0(s_task_data_t, 1);
+ req_data->type = TASK_NOTIFY;
+ req_data->request_id = predecessor_candidate_id;
+ req_data->issuer_host_name = MSG_host_get_name(MSG_host_self());
+
+ // send a "Notify" request to notify_id
+ m_task_t task = MSG_task_create(NULL, COMP_SIZE, COMM_SIZE, req_data);
+ XBT_DEBUG("Sending a 'Notify' request (task %p) to %d", task, notify_id);
+ char mailbox[MAILBOX_NAME_SIZE];
+ get_mailbox(notify_id, mailbox);
+ MSG_task_dsend(task, mailbox, task_free);
+}
+
+/**
+ * \brief This function is called periodically.
+ * It refreshes the finger table of the current node.
+ * \param node the current node
+ */
+static void fix_fingers(node_t node) {
+
+ XBT_DEBUG("Fixing fingers");
+ int i = node->next_finger_to_fix;
+ int id = find_successor(node, node->id + powers2[i]);
+ if (id != -1) {
+
+ if (id != node->fingers[i].id) {
+ set_finger(node, i, id);
+ print_finger_table(node);
+ }
+ node->next_finger_to_fix = (i + 1) % nb_bits;
+ }
+}
+
+/**
+ * \brief This function is called periodically.
+ * It checks whether the predecessor has failed
+ * \param node the current node