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_config.h"
23 #include "frescan_debug.h"
24 #include "frescan_data.h"
25 #include "frescan_servers.h"
28 * frescan_manager_thread_create()
30 * This call creates the manager thread at each node which will be waiting
31 * in a request queue for LOCAL or EXTERNAL requests.
34 static void *frescan_manager_thread(void *arg);
36 int frescan_manager_thread_create(frescan_network_t net)
39 fosa_thread_attr_t attr;
41 ret = fosa_thread_attr_init(&attr);
42 if (ret != 0) return ret;
44 ret = fosa_thread_attr_set_prio(&attr, FRESCAN_NEG_THREAD_PRIO);
45 if (ret != 0) return ret;
47 ret = fosa_thread_create(&the_networks[net].manager_thread_id,
49 frescan_manager_thread,
50 (void *)(uint32_t)net);
51 if (ret != 0) return ret;
53 ret = fosa_thread_attr_destroy(&attr);
54 if (ret != 0) return ret;
60 * frescan_acceptor_thread_create()
62 * This call creates the acceptor thread which will be waiting negotiation
63 * messages from the network and converting them into requests.
66 static void *frescan_acceptor_thread(void *arg);
68 int frescan_acceptor_thread_create(frescan_network_t net)
71 fosa_thread_attr_t attr;
73 ret = fosa_thread_attr_init(&attr);
74 if (ret != 0) return ret;
76 ret = fosa_thread_attr_set_prio(&attr, FRESCAN_ACCEPTOR_THREAD_PRIO);
77 if (ret != 0) return ret;
79 ret = fosa_thread_create(&the_networks[net].acceptor_thread_id,
81 frescan_acceptor_thread,
82 (void *)(uint32_t)net);
83 if (ret != 0) return ret;
85 ret = fosa_thread_attr_destroy(&attr);
86 if (ret != 0) return ret;
92 * frescan_manager_thread
95 static void frescan_manager_neg(frescan_request_data_t *req_data);
96 static void frescan_manager_reneg(frescan_request_data_t *req_data);
97 static void frescan_manager_cancel(frescan_request_data_t *req_data);
98 static void frescan_manager_repneg(frescan_request_data_t *req_data);
100 static void *frescan_manager_thread(void *arg)
103 frescan_request_id_t req;
104 frescan_request_data_t *req_data;
105 frescan_network_t net = (uint32_t)arg;
107 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "manager thread starts\n");
110 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "wait for a request\n");
112 ret = frescan_requests_dequeue(&req);
115 ret = frescan_requests_get_data(req, &req_data);
118 switch(req_data->type) {
119 case FRESCAN_REQ_NEG:
120 frescan_manager_neg(req_data);
122 case FRESCAN_REQ_RENEG:
123 frescan_manager_reneg(req_data);
125 case FRESCAN_REQ_CANCEL:
126 frescan_manager_cancel(req_data);
128 case FRESCAN_REP_NEG:
129 frescan_manager_repneg(req_data);
132 ERROR("request type not supported\n");
136 if(req_data->request_node != the_networks[net].local_node) {
137 ret = frescan_requests_free(req);
144 * frescan_acceptor_thread()
147 static void *frescan_acceptor_thread(void *arg)
150 frescan_request_id_t req;
151 frescan_network_t net = (uint32_t)arg;
153 DEBUG(FRESCAN_ACCEPTOR_ENABLE_DEBUG, "acceptor thread starts\n");
156 ret = frescan_messages_recv_request(net, &req);
159 ret = frescan_requests_enqueue(req);
167 * frescan_manager_neg
170 static void frescan_manager_neg(frescan_request_data_t *req_data)
175 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "negotiation request\n");
177 if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) {
179 // NOTE: req_data->ss is an INPUT parameter
180 accepted = true; // TODO: sched analysis
181 ret = 0; // TODO: sched analysis
184 req_data->return_value = FRESCAN_REQ_ACCEPTED;
186 req_data->return_value = (ret == 0) ?
187 FRESCAN_REQ_NOT_ACCEPTED :
191 if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) {
192 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "master local\n");
193 ret = frescan_bwres_robjs_signal(req_data->robj);
196 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
197 "master external, sending reply\n");
199 req_data->type = FRESCAN_REP_NEG;
200 ret = frescan_messages_send_request(req_data);
204 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
205 "send negotiation request to master\n");
206 ret = frescan_messages_send_request(req_data);
212 * frescan_manager_neg
215 static void frescan_manager_reneg(frescan_request_data_t *req_data)
217 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "renegotiation request\n");
221 * frescan_manager_neg
224 static void frescan_manager_cancel(frescan_request_data_t *req_data)
226 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "cancel request\n");
230 * frescan_manager_neg
233 static void frescan_manager_repneg(frescan_request_data_t *req_data)
236 frescan_request_data_t *neg_req_data;
238 DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "reply to neg request\n");
240 ret = frescan_requests_get_data(req_data->req, &neg_req_data);
243 neg_req_data->return_value = req_data->return_value;
245 ret = frescan_bwres_robjs_signal(neg_req_data->robj);