1 /* Copyright (c) 2012. The SimGrid Team.
2 * All rights reserved. */
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. */
8 #include <xbt/RngStream.h>
10 static void task_free(void *data);
12 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_tracker,
13 "Messages specific for the tracker");
15 * Tracker main function
16 * @param argc number of arguments
17 * @param argv arguments
19 int tracker(int argc, char *argv[]) {
24 RngStream stream = RngStream_CreateStream("tracker");
27 xbt_assert(argc == 2, "Wrong number of arguments for the tracker.");
29 double deadline = atof(argv[1]);
30 xbt_assert(deadline > 0, "Wrong deadline supplied");
31 //Building peers array
32 xbt_dynar_t peers_list = xbt_dynar_new(sizeof(int), NULL);
34 XBT_INFO("Tracker launched.");
36 msg_comm_t comm_received = NULL;
37 msg_task_t task_received = NULL;
39 while (MSG_get_clock() < deadline) {
40 if (comm_received == NULL) {
41 comm_received = MSG_task_irecv(&task_received,TRACKER_MAILBOX);
43 if (MSG_comm_test(comm_received)) {
44 //Check for correct status
45 if (MSG_comm_get_status(comm_received) == MSG_OK) {
46 //Retrieve the data sent by the peer.
47 tracker_task_data_t data = MSG_task_get_data(task_received);
48 //Add the peer to our peer list.
49 if (!is_in_list(peers_list,data->peer_id)) {
50 xbt_dynar_push_as(peers_list, int, data->peer_id);
52 //Sending peers to the peer
53 int nb_peers = 0, next_peer;
54 int peers_length = xbt_dynar_length(peers_list);
55 for (i = 0; i < MAXIMUM_PAIRS && i < peers_length; i++) {
57 next_peer = xbt_dynar_get_as(peers_list,RngStream_RandInt(stream, 0, peers_length - 1),int);
58 } while (is_in_list(data->peers, next_peer));
59 xbt_dynar_push_as(data->peers,int,next_peer);
61 //setting the interval
62 data->interval = TRACKER_QUERY_INTERVAL;
63 //sending the task back to the peer.
64 MSG_task_dsend(task_received,data->mailbox, task_free);
65 //destroy the communication.
67 MSG_comm_destroy(comm_received);
75 //Free the remaining communication if any
77 MSG_comm_destroy(comm_received);
80 xbt_dynar_free(&peers_list);
81 //Free the RngStream object.
82 RngStream_DeleteStream(&stream);
84 XBT_INFO("Tracker is leaving");
89 * Build a new task for the tracker.
90 * @param issuer_host_name Hostname of the issuer. For debugging purposes
92 tracker_task_data_t tracker_task_data_new(const char *issuer_host_name, const char *mailbox, int peer_id, int uploaded, int downloaded, int left) {
93 tracker_task_data_t task = xbt_new(s_tracker_task_data_t, 1);
95 task->type = TRACKER_TASK_QUERY;
96 task->issuer_host_name = issuer_host_name;
97 task->mailbox = mailbox;
98 task->peer_id = peer_id;
99 task->uploaded = uploaded;
100 task->downloaded = downloaded;
103 task->peers = xbt_dynar_new(sizeof(int),NULL);
108 * Free a tracker task that has not succefully been sent.
109 * @param data Task to free
111 static void task_free(void *data) {
112 tracker_task_data_t task_data = MSG_task_get_data(data);
113 tracker_task_data_free(task_data);
114 MSG_task_destroy(data);
117 * Free the data structure of a tracker task.
118 * @param task data to free
120 void tracker_task_data_free(tracker_task_data_t task) {
121 xbt_dynar_free(&task->peers);
125 * Returns if the given id is in the peers lsit
126 * @param peers dynar containing the peers
127 * @param id identifier of the peer to test
129 int is_in_list(xbt_dynar_t peers, int id) {
131 xbt_dynar_foreach(peers, i, elm ) {