1 /* Copyright (c) 2012-2020. 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>
10 static void task_free(void* data);
12 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_tracker, "Messages specific for the tracker");
14 * Tracker main function
15 * @param argc number of arguments
16 * @param argv arguments
18 int tracker(int argc, char* argv[])
21 xbt_assert(argc == 2, "Wrong number of arguments for the tracker.");
22 // Retrieving end time
23 double deadline = xbt_str_parse_double(argv[1], "Invalid deadline: %s");
24 xbt_assert(deadline > 0, "Wrong deadline supplied");
26 // Building peers array
27 xbt_dynar_t peers_list = xbt_dynar_new(sizeof(int), NULL);
29 XBT_INFO("Tracker launched.");
31 msg_comm_t comm_received = NULL;
32 msg_task_t task_received = NULL;
34 while (MSG_get_clock() < deadline) {
35 if (comm_received == NULL) {
36 comm_received = MSG_task_irecv(&task_received, TRACKER_MAILBOX);
38 if (MSG_comm_test(comm_received)) {
39 // Check for correct status
40 if (MSG_comm_get_status(comm_received) == MSG_OK) {
41 // Retrieve the data sent by the peer.
42 tracker_task_data_t data = MSG_task_get_data(task_received);
43 // Add the peer to our peer list.
44 if (!is_in_list(peers_list, data->peer_id)) {
45 xbt_dynar_push_as(peers_list, int, data->peer_id);
47 // Sending peers to the peer
49 int peers_length = xbt_dynar_length(peers_list);
50 for (int i = 0; i < MAXIMUM_PEERS && i < peers_length; i++) {
52 next_peer = xbt_dynar_get_as(peers_list, rand() % peers_length, int);
53 } while (is_in_list(data->peers, next_peer));
54 xbt_dynar_push_as(data->peers, int, next_peer);
56 // setting the interval
57 data->interval = TRACKER_QUERY_INTERVAL;
58 // sending the task back to the peer.
59 MSG_task_dsend(task_received, data->mailbox, task_free);
60 // destroy the communication.
62 MSG_comm_destroy(comm_received);
69 // Free the remaining communication if any
71 MSG_comm_destroy(comm_received);
73 // Free the peers list
74 xbt_dynar_free(&peers_list);
76 XBT_INFO("Tracker is leaving");
82 * Build a new task for the tracker.
83 * @param issuer_host_name Hostname of the issuer. For debugging purposes
85 tracker_task_data_t tracker_task_data_new(const char* issuer_host_name, const char* mailbox, int peer_id, int uploaded,
86 int downloaded, int left)
88 tracker_task_data_t task = xbt_new(s_tracker_task_data_t, 1);
90 task->type = TRACKER_TASK_QUERY;
91 task->issuer_host_name = issuer_host_name;
92 task->mailbox = mailbox;
93 task->peer_id = peer_id;
94 task->uploaded = uploaded;
95 task->downloaded = downloaded;
98 task->peers = xbt_dynar_new(sizeof(int), NULL);
104 * Free a tracker task that has not successfully been sent.
105 * @param data Task to free
107 static void task_free(void* data)
109 tracker_task_data_t task_data = MSG_task_get_data(data);
110 tracker_task_data_free(task_data);
111 MSG_task_destroy(data);
115 * Free the data structure of a tracker task.
116 * @param task data to free
118 void tracker_task_data_free(tracker_task_data_t task)
120 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(const_xbt_dynar_t peers, int id)
131 return xbt_dynar_member(peers, &id);