1 /* Copyright (c) 2012-2019. 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 <simgrid/msg.h>
9 #include <xbt/RngStream.h>
11 static void task_free(void* data);
13 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_tracker, "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[])
22 xbt_assert(argc == 2, "Wrong number of arguments for the tracker.");
23 // Retrieving end time
24 double deadline = xbt_str_parse_double(argv[1], "Invalid deadline: %s");
25 xbt_assert(deadline > 0, "Wrong deadline supplied");
27 RngStream stream = (RngStream)MSG_host_get_data(MSG_host_self());
28 // Building peers array
29 xbt_dynar_t peers_list = xbt_dynar_new(sizeof(int), NULL);
31 XBT_INFO("Tracker launched.");
33 msg_comm_t comm_received = NULL;
34 msg_task_t task_received = NULL;
36 while (MSG_get_clock() < deadline) {
37 if (comm_received == NULL) {
38 comm_received = MSG_task_irecv(&task_received, TRACKER_MAILBOX);
40 if (MSG_comm_test(comm_received)) {
41 // Check for correct status
42 if (MSG_comm_get_status(comm_received) == MSG_OK) {
43 // Retrieve the data sent by the peer.
44 tracker_task_data_t data = MSG_task_get_data(task_received);
45 // Add the peer to our peer list.
46 if (is_in_list(peers_list, data->peer_id) == 0) {
47 xbt_dynar_push_as(peers_list, int, data->peer_id);
49 // Sending peers to the peer
51 int peers_length = xbt_dynar_length(peers_list);
52 for (int i = 0; i < MAXIMUM_PEERS && i < peers_length; i++) {
54 next_peer = xbt_dynar_get_as(peers_list, RngStream_RandInt(stream, 0, peers_length - 1), int);
55 } while (is_in_list(data->peers, next_peer));
56 xbt_dynar_push_as(data->peers, int, next_peer);
58 // setting the interval
59 data->interval = TRACKER_QUERY_INTERVAL;
60 // sending the task back to the peer.
61 MSG_task_dsend(task_received, data->mailbox, task_free);
62 // destroy the communication.
64 MSG_comm_destroy(comm_received);
71 // Free the remaining communication if any
73 MSG_comm_destroy(comm_received);
75 // Free the peers list
76 xbt_dynar_free(&peers_list);
78 XBT_INFO("Tracker is leaving");
84 * Build a new task for the tracker.
85 * @param issuer_host_name Hostname of the issuer. For debugging purposes
87 tracker_task_data_t tracker_task_data_new(const char* issuer_host_name, const char* mailbox, int peer_id, int uploaded,
88 int downloaded, int left)
90 tracker_task_data_t task = xbt_new(s_tracker_task_data_t, 1);
92 task->type = TRACKER_TASK_QUERY;
93 task->issuer_host_name = issuer_host_name;
94 task->mailbox = mailbox;
95 task->peer_id = peer_id;
96 task->uploaded = uploaded;
97 task->downloaded = downloaded;
100 task->peers = xbt_dynar_new(sizeof(int), NULL);
106 * Free a tracker task that has not successfully been sent.
107 * @param data Task to free
109 static void task_free(void* data)
111 tracker_task_data_t task_data = MSG_task_get_data(data);
112 tracker_task_data_free(task_data);
113 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)
122 xbt_dynar_free(&task->peers);
127 * Returns if the given id is in the peers lsit
128 * @param peers dynar containing the peers
129 * @param id identifier of the peer to test
131 int is_in_list(xbt_dynar_t peers, int id)
133 return xbt_dynar_member(peers, &id);