2 * @file frescan_bwres_requests.c
4 * @brief FRESCAN bandwith reservation layer: requests
6 * This module contains an operation to create the queue, an operation to
7 * enqueue a message (with a request), and an operation to
14 * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
18 #include <misc/freelist.h>
19 #include <misc/linux_list.h>
21 #include "frescan_bwres_requests.h"
22 #include "frescan_config.h"
23 #include "frescan_debug.h"
24 #include "fosa_mutexes_and_condvars.h"
26 static bool is_initialized = false;
31 * We will use a freelist to allocate and free the requests.
36 frescan_request_data_t request_data;
37 struct list_head request_list;
41 static fosa_mutex_t requests_mutex;
42 static fosa_cond_t requests_cond;
44 static struct request_t the_requests_pool[FRESCAN_MX_REQUESTS];
45 static freelist_t freelist;
47 static struct request_t the_requests_list;
50 * frescan_requests_init()
52 * Init the freelist, requests list, cond var and mutex.
56 int frescan_requests_init(int max_ceiling)
60 err = fosa_mutex_init(&requests_mutex, max_ceiling);
61 if (err != 0) return err;
63 err = fosa_cond_init(&requests_cond);
64 if (err != 0) return err;
66 err = freelist_init(&freelist, FRESCAN_MX_REQUESTS);
67 if (err != 0) return err;
69 INIT_LIST_HEAD(&the_requests_list.request_list);
71 is_initialized = true;
76 * frescan_requests_alloc()
78 * Allocate a request with the mutex locked
82 int frescan_requests_alloc(frescan_request_id_t *req)
86 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "alloc\n");
88 if (is_initialized == false) return -1;
90 err = fosa_mutex_lock(&requests_mutex);
91 if (err != 0) return err;
93 pos = freelist_alloc(&freelist);
94 if (pos < 0) goto locked_error;
96 err = fosa_mutex_unlock(&requests_mutex);
97 if (err != 0) return err;
99 *req = (unsigned int)pos;
100 the_requests_pool[*req].pool_pos = pos;
105 fosa_mutex_unlock(&requests_mutex);
110 * frescan_requests_free()
112 * free the request from the pool
116 int frescan_requests_free(frescan_request_id_t req)
120 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "free\n");
122 if (is_initialized == false) return -1;
124 err = fosa_mutex_lock(&requests_mutex);
125 if (err != 0) return err;
127 err = freelist_free(&freelist, req);
128 if (err != 0) goto locked_error;
130 err = fosa_mutex_unlock(&requests_mutex);
131 if (err != 0) return err;
136 fosa_mutex_unlock(&requests_mutex);
141 * frescan_requests_get_data() - gets the data of the request
145 int frescan_requests_get_data(frescan_request_id_t req,
146 frescan_request_data_t **data)
148 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
149 *data = &the_requests_pool[req].request_data;
154 * frescan_requests_enqueue()
158 int frescan_requests_enqueue(frescan_request_id_t req)
162 err = fosa_mutex_lock(&requests_mutex);
163 if (err != 0) return err;
165 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
166 "is list empty A? %d\n",
167 list_empty(&the_requests_list.request_list));
169 list_add_tail(&the_requests_pool[req].request_list,
170 &the_requests_list.request_list);
172 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
173 "is list empty B? %d\n",
174 list_empty(&the_requests_list.request_list));
176 err = fosa_cond_signal(&requests_cond);
177 if (err != 0) goto locked_error;
179 err = fosa_mutex_unlock(&requests_mutex);
180 if (err != 0) return err;
185 fosa_mutex_unlock(&requests_mutex);
190 * frescan_requestqueue_dequeue()
194 int frescan_requests_dequeue(frescan_request_id_t *req)
197 struct list_head *pos;
198 struct request_t *request = NULL;
200 err = fosa_mutex_lock(&requests_mutex);
201 if (err != 0) return err;
203 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "entering\n");
205 while (list_empty(&the_requests_list.request_list)) {
206 err = fosa_cond_wait(&requests_cond, &requests_mutex);
207 if (err != 0) goto locked_error;
208 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "received signal\n");
211 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
213 list_for_each(pos, &the_requests_list.request_list) {
214 request = list_entry(pos, struct request_t, request_list);
218 list_del(&request->request_list);
220 *req = request->pool_pos;
222 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
223 "is list empty now? %d\n",
224 list_empty(&the_requests_list.request_list));
226 err = fosa_mutex_unlock(&requests_mutex);
227 if (err != 0) return err;
232 fosa_mutex_unlock(&requests_mutex);