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); // acceptor request
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)
238 frescan_contract_t old_contract;
240 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "renegotiation request\n");
242 if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
243 // scheduling analysis
244 ret = frescan_sa_update_contract
245 (&the_networks[req_data->net].scenario,
247 req_data->request_node,
252 ret = frescan_sa_sched_test
253 (&the_networks[req_data->net].scenario,
258 ret = frescan_sa_get_final_values
259 (&the_networks[req_data->net].scenario,
261 req_data->request_node,
262 &req_data->final_values);
264 req_data->return_value = FRESCAN_REQ_ACCEPTED;
266 ret = frescan_sa_update_contract
267 (&the_networks[req_data->net].scenario,
269 req_data->request_node,
273 req_data->return_value = FRESCAN_REQ_NOT_ACCEPTED;
276 // signal or reply the results
277 if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) {
278 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "master local\n");
279 ret = frescan_bwres_robjs_signal(req_data->robj);
282 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
283 "master external, sending reply\n");
285 req_data->type = FRESCAN_REP_NEG;
286 ret = frescan_messages_send_request(req_data);
290 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
291 "send renegotiation request to master\n");
292 ret = frescan_messages_send_request(req_data);
298 * frescan_manager_cancel
301 static void frescan_manager_cancel(frescan_request_data_t *req_data)
305 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "cancel request\n");
307 if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
308 ret = frescan_sa_remove_contract
309 (&the_networks[req_data->net].scenario,
311 req_data->request_node);
314 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
315 "send cancel request to master\n");
316 ret = frescan_messages_send_request(req_data);
320 if (req_data->request_node == the_networks[req_data->net].local_node) {
321 ret = frescan_bwres_robjs_signal(req_data->robj);
327 * frescan_manager_repneg
330 static void frescan_manager_repneg(frescan_request_data_t *req_data)
333 frescan_request_data_t *neg_req_data;
335 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "reply to neg request\n");
337 ret = frescan_requests_get_data(req_data->req, &neg_req_data);
340 neg_req_data->return_value = req_data->return_value;
341 neg_req_data->final_values = req_data->final_values;
343 ret = frescan_bwres_robjs_signal(neg_req_data->robj);