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 if (is_initialized == false) return -1;
88 err = fosa_mutex_lock(&requests_mutex);
89 if (err != 0) return err;
91 pos = freelist_alloc(&freelist);
92 if (pos < 0) goto locked_error;
94 err = fosa_mutex_unlock(&requests_mutex);
95 if (err != 0) return err;
97 *req = (unsigned int)pos;
98 the_requests_pool[*req].pool_pos = pos;
103 fosa_mutex_unlock(&requests_mutex);
108 * frescan_requests_free()
110 * free the request from the pool
114 int frescan_requests_free(frescan_request_id_t req)
118 if (is_initialized == false) return -1;
120 err = fosa_mutex_lock(&requests_mutex);
121 if (err != 0) return err;
123 err = freelist_free(&freelist, req);
124 if (err != 0) goto locked_error;
126 err = fosa_mutex_unlock(&requests_mutex);
127 if (err != 0) return err;
132 fosa_mutex_unlock(&requests_mutex);
137 * frescan_requests_get_data() - gets the data of the request
141 int frescan_requests_get_data(frescan_request_id_t req,
142 frescan_request_data_t **data)
144 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
145 *data = &the_requests_pool[req].request_data;
150 * frescan_requests_enqueue()
154 int frescan_requests_enqueue(frescan_request_id_t req)
158 err = fosa_mutex_lock(&requests_mutex);
159 if (err != 0) return err;
161 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
162 "is list empty A? %d\n",
163 list_empty(&the_requests_list.request_list));
165 list_add_tail(&the_requests_pool[req].request_list,
166 &the_requests_list.request_list);
168 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
169 "is list empty B? %d\n",
170 list_empty(&the_requests_list.request_list));
172 err = fosa_cond_signal(&requests_cond);
173 if (err != 0) goto locked_error;
175 err = fosa_mutex_unlock(&requests_mutex);
176 if (err != 0) return err;
181 fosa_mutex_unlock(&requests_mutex);
186 * frescan_requestqueue_dequeue()
190 int frescan_requests_dequeue(frescan_request_id_t *req)
193 struct list_head *pos;
194 struct request_t *request = NULL;
196 err = fosa_mutex_lock(&requests_mutex);
197 if (err != 0) return err;
199 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "entering\n");
201 while (list_empty(&the_requests_list.request_list)) {
202 err = fosa_cond_wait(&requests_cond, &requests_mutex);
203 if (err != 0) goto locked_error;
204 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "received signal\n");
207 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
209 list_for_each(pos, &the_requests_list.request_list) {
210 request = list_entry(pos, struct request_t, request_list);
214 list_del(&request->request_list);
216 *req = request->pool_pos;
218 DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
219 "is list empty now? %d\n",
220 list_empty(&the_requests_list.request_list));
222 err = fosa_mutex_unlock(&requests_mutex);
223 if (err != 0) return err;
228 fosa_mutex_unlock(&requests_mutex);