2 * @file frescan_bwres_threads.c
4 * @brief FRESCAN bandwidth reservation layer: negotiation threads
6 * This module contains the acceptor threads and the master thread for local
7 * negotiations, with functions to create them.
13 * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
18 #include "fosa_threads_and_signals.h" // fosa_thread_attr_init...
19 #include "frescan_bwres_threads.h"
20 #include "frescan_bwres_messages.h"
21 #include "frescan_bwres_requests.h"
22 #include "frescan_bwres_analysis.h"
23 #include "frescan_config.h"
24 #include "frescan_debug.h"
25 #include "frescan_data.h"
26 #include "frescan_servers.h"
29 * frescan_manager_thread_create()
31 * This call creates the manager thread at each node which will be waiting
32 * in a request queue for LOCAL or EXTERNAL requests.
35 static void *frescan_manager_thread(void *arg);
37 int frescan_manager_thread_create(frescan_network_t net)
40 fosa_thread_attr_t attr;
42 ret = fosa_thread_attr_init(&attr);
43 if (ret != 0) return ret;
45 ret = fosa_thread_attr_set_prio(&attr, FRESCAN_NEG_THREAD_PRIO);
46 if (ret != 0) return ret;
48 ret = fosa_thread_create(&the_networks[net].manager_thread_id,
50 frescan_manager_thread,
51 (void *)(uint32_t)net);
52 if (ret != 0) return ret;
54 ret = fosa_thread_attr_destroy(&attr);
55 if (ret != 0) return ret;
61 * frescan_acceptor_thread_create()
63 * This call creates the acceptor thread which will be waiting negotiation
64 * messages from the network and converting them into requests.
67 static void *frescan_acceptor_thread(void *arg);
69 int frescan_acceptor_thread_create(frescan_network_t net)
72 fosa_thread_attr_t attr;
74 ret = fosa_thread_attr_init(&attr);
75 if (ret != 0) return ret;
77 ret = fosa_thread_attr_set_prio(&attr, FRESCAN_ACCEPTOR_THREAD_PRIO);
78 if (ret != 0) return ret;
80 ret = fosa_thread_create(&the_networks[net].acceptor_thread_id,
82 frescan_acceptor_thread,
83 (void *)(uint32_t)net);
84 if (ret != 0) return ret;
86 ret = fosa_thread_attr_destroy(&attr);
87 if (ret != 0) return ret;
93 * frescan_manager_thread
96 static void frescan_manager_neg(frescan_request_data_t *req_data);
97 static void frescan_manager_reneg(frescan_request_data_t *req_data);
98 static void frescan_manager_cancel(frescan_request_data_t *req_data);
99 static void frescan_manager_repneg(frescan_request_data_t *req_data);
101 static void *frescan_manager_thread(void *arg)
104 frescan_request_id_t req;
105 frescan_request_data_t *req_data;
106 frescan_network_t net = (uint32_t)arg;
108 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "manager thread starts\n");
111 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "wait for a request\n");
113 ret = frescan_requests_dequeue(&req);
116 ret = frescan_requests_get_data(req, &req_data);
119 switch(req_data->type) {
120 case FRESCAN_REQ_NEG:
121 frescan_manager_neg(req_data);
123 case FRESCAN_REQ_RENEG:
124 frescan_manager_reneg(req_data);
126 case FRESCAN_REQ_CANCEL:
127 frescan_manager_cancel(req_data);
129 case FRESCAN_REP_NEG:
130 frescan_manager_repneg(req_data);
133 ERROR("request type not supported\n");
137 if(req_data->request_node != the_networks[net].local_node) {
138 ret = frescan_requests_free(req);
145 * frescan_acceptor_thread()
148 static void *frescan_acceptor_thread(void *arg)
151 frescan_request_id_t req;
152 frescan_network_t net = (uint32_t)arg;
154 DEBUG(FRESCAN_ACCEPTOR_ENABLE_DEBUG, "acceptor thread starts\n");
157 ret = frescan_messages_recv_request(net, &req);
160 ret = frescan_requests_enqueue(req);
168 * frescan_manager_neg
171 static void frescan_manager_neg(frescan_request_data_t *req_data)
176 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "negotiation request\n");
178 if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
179 // scheduling analysis
180 ret = frescan_sa_add_contract
181 (&the_networks[req_data->net].scenario,
184 req_data->request_node);
187 ret = frescan_sa_sched_test
188 (&the_networks[req_data->net].scenario,
193 ret = frescan_sa_get_final_values
194 (&the_networks[req_data->net].scenario,
196 req_data->request_node,
197 &req_data->final_values);
199 req_data->return_value = FRESCAN_REQ_ACCEPTED;
201 ret = frescan_sa_remove_contract
202 (&the_networks[req_data->net].scenario,
204 req_data->request_node);
206 req_data->return_value = FRESCAN_REQ_NOT_ACCEPTED;
209 // signal or reply the results
210 if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) {
211 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "master local\n");
212 ret = frescan_bwres_robjs_signal(req_data->robj);
215 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
216 "master external, sending reply\n");
218 req_data->type = FRESCAN_REP_NEG;
219 ret = frescan_messages_send_request(req_data);
223 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
224 "send negotiation request to master\n");
225 ret = frescan_messages_send_request(req_data);
231 * frescan_manager_neg
234 static void frescan_manager_reneg(frescan_request_data_t *req_data)
236 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "renegotiation request\n");
240 * frescan_manager_neg
243 static void frescan_manager_cancel(frescan_request_data_t *req_data)
245 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "cancel request\n");
249 * frescan_manager_neg
252 static void frescan_manager_repneg(frescan_request_data_t *req_data)
255 frescan_request_data_t *neg_req_data;
257 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "reply to neg request\n");
259 ret = frescan_requests_get_data(req_data->req, &neg_req_data);
262 neg_req_data->return_value = req_data->return_value;
263 neg_req_data->final_values = req_data->final_values;
265 ret = frescan_bwres_robjs_signal(neg_req_data->robj);