Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove commented code from surf_routing_cluster
[simgrid.git] / examples / msg / bittorrent / tracker.c
1 /* Copyright (c) 2012. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "tracker.h"
7 #include <msg/msg.h>
8 #include <xbt/RngStream.h>
9
10 static void task_free(void *data);
11
12 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_tracker, "Messages specific for the tracker");
13 /**
14  * Tracker main function
15  * @param argc number of arguments
16  * @param argv arguments
17  */
18 int tracker(int argc, char *argv[])
19 {
20   int i;
21
22   RngStream stream = RngStream_CreateStream("tracker");
23
24   //Checking arguments
25   xbt_assert(argc == 2, "Wrong number of arguments for the tracker.");
26   //Retrieving end time
27   double deadline = atof(argv[1]);
28   xbt_assert(deadline > 0, "Wrong deadline supplied");
29   //Building peers array
30   xbt_dynar_t peers_list = xbt_dynar_new(sizeof(int), NULL);
31
32   XBT_INFO("Tracker launched.");
33
34   msg_comm_t comm_received = NULL;
35   msg_task_t task_received = NULL;
36
37   while (MSG_get_clock() < deadline) {
38     if (comm_received == NULL) {
39       comm_received = MSG_task_irecv(&task_received, TRACKER_MAILBOX);
40     }
41     if (MSG_comm_test(comm_received)) {
42       //Check for correct status
43       if (MSG_comm_get_status(comm_received) == MSG_OK) {
44         //Retrieve the data sent by the peer.
45         tracker_task_data_t data = MSG_task_get_data(task_received);
46         //Add the peer to our peer list.
47         if (!is_in_list(peers_list, data->peer_id)) {
48           xbt_dynar_push_as(peers_list, int, data->peer_id);
49         }
50         //Sending peers to the peer
51         int next_peer;
52         int peers_length = xbt_dynar_length(peers_list);
53         for (i = 0; i < MAXIMUM_PAIRS && i < peers_length; i++) {
54           do {
55             next_peer =
56                 xbt_dynar_get_as(peers_list,
57                                  RngStream_RandInt(stream, 0, peers_length - 1),
58                                  int);
59           } while (is_in_list(data->peers, next_peer));
60           xbt_dynar_push_as(data->peers, int, next_peer);
61         }
62         //setting the interval
63         data->interval = TRACKER_QUERY_INTERVAL;
64         //sending the task back to the peer.
65         MSG_task_dsend(task_received, data->mailbox, task_free);
66         //destroy the communication.
67       }
68       MSG_comm_destroy(comm_received);
69       comm_received = NULL;
70       task_received = NULL;
71     } else {
72       MSG_process_sleep(1);
73     }
74   }
75   //Free the remaining communication if any
76   if (comm_received) {
77     MSG_comm_destroy(comm_received);
78   }
79   //Free the peers list
80   xbt_dynar_free(&peers_list);
81   //Free the RngStream object.
82   RngStream_DeleteStream(&stream);
83
84   XBT_INFO("Tracker is leaving");
85
86   return 0;
87 }
88
89 /**
90  * Build a new task for the tracker.
91  * @param issuer_host_name Hostname of the issuer. For debugging purposes
92  */
93 tracker_task_data_t tracker_task_data_new(const char *issuer_host_name,
94                                           const char *mailbox, int peer_id,
95                                           int uploaded, int downloaded,
96                                           int left)
97 {
98   tracker_task_data_t task = xbt_new(s_tracker_task_data_t, 1);
99
100   task->type = TRACKER_TASK_QUERY;
101   task->issuer_host_name = issuer_host_name;
102   task->mailbox = mailbox;
103   task->peer_id = peer_id;
104   task->uploaded = uploaded;
105   task->downloaded = downloaded;
106   task->left = left;
107
108   task->peers = xbt_dynar_new(sizeof(int), NULL);
109
110   return task;
111 }
112
113 /**
114  * Free a tracker task that has not succefully been sent.
115  * @param data Task to free
116  */
117 static void task_free(void *data)
118 {
119   tracker_task_data_t task_data = MSG_task_get_data(data);
120   tracker_task_data_free(task_data);
121   MSG_task_destroy(data);
122 }
123
124 /**
125  * Free the data structure of a tracker task.
126  * @param task data to free
127  */
128 void tracker_task_data_free(tracker_task_data_t task)
129 {
130   xbt_dynar_free(&task->peers);
131   xbt_free(task);
132 }
133
134 /**
135  * Returns if the given id is in the peers lsit
136  * @param peers dynar containing the peers
137  * @param id identifier of the peer to test
138  */
139 int is_in_list(xbt_dynar_t peers, int id)
140 {
141   unsigned i;
142   int elm;
143   xbt_dynar_foreach(peers, i, elm) {
144     if (elm == id) {
145       return 1;
146     }
147   }
148   return 0;
149 }