]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_requests.c
4ab7de7b229a93be06caa6a33e1635b5c00c95d3
[frescor/fna.git] / src_frescan / frescan_bwres_requests.c
1 /*!
2  * @file frescan_bwres_requests.c
3  *
4  * @brief FRESCAN bandwith reservation layer: requests
5  *
6  * This module contains an operation to create the queue, an operation to
7  * enqueue a message (with a request), and an operation to
8  * dequeue a message.
9  *
10  * @version 0.01
11  *
12  * @date 1-Apr-2008
13  *
14  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
15  *
16  */
17
18 #include <misc/freelist.h>
19 #include <misc/linux_list.h>
20 #include "frescan.h"
21 #include "frescan_bwres_requests.h"
22 #include "frescan_config.h"
23 #include "frescan_debug.h"
24 #include "fosa_mutexes_and_condvars.h"
25
26 static bool is_initialized = false;
27
28 /**
29  * the_requests_pool
30  *
31  * We will use a freelist to allocate and free the requests.
32  *
33  **/
34
35 struct request_t {
36         frescan_request_data_t request_data;
37         struct list_head       request_list;
38         int pool_pos;
39 };
40
41 static fosa_mutex_t requests_mutex;
42 static fosa_cond_t  requests_cond;
43
44 static struct request_t the_requests_pool[FRESCAN_MX_REQUESTS];
45 static freelist_t freelist;
46
47 static struct request_t the_requests_list;
48
49 /**
50  * frescan_requests_init()
51  *
52  * Init the freelist, requests list, cond var and mutex.
53  *
54  **/
55
56 int frescan_requests_init(int max_ceiling)
57 {
58         int err;
59
60         err = fosa_mutex_init(&requests_mutex, max_ceiling);
61         if (err != 0) return err;
62
63         err = fosa_cond_init(&requests_cond);
64         if (err != 0) return err;
65
66         err = freelist_init(&freelist, FRESCAN_MX_REQUESTS);
67         if (err != 0) return err;
68
69         INIT_LIST_HEAD(&the_requests_list.request_list);
70
71         is_initialized = true;
72         return 0;
73 }
74
75 /**
76  * frescan_requests_alloc()
77  *
78  * Allocate a request with the mutex locked
79  *
80  **/
81
82 int frescan_requests_alloc(frescan_request_id_t *req)
83 {
84         int err, pos;
85
86         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "alloc\n");
87
88         if (is_initialized == false) return -1;
89
90         err = fosa_mutex_lock(&requests_mutex);
91         if (err != 0) return err;
92
93                 pos = freelist_alloc(&freelist);
94                 if (pos < 0) goto locked_error;
95
96         err = fosa_mutex_unlock(&requests_mutex);
97         if (err != 0) return err;
98
99         *req = (unsigned int)pos;
100         the_requests_pool[*req].pool_pos = pos;
101
102         return 0;
103
104 locked_error:
105         fosa_mutex_unlock(&requests_mutex);
106         return pos;
107 }
108
109 /**
110  * frescan_requests_free()
111  *
112  * free the request from the pool
113  *
114  **/
115
116 int frescan_requests_free(frescan_request_id_t req)
117 {
118         int err;
119
120         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "free\n");
121
122         if (is_initialized == false) return -1;
123
124         err = fosa_mutex_lock(&requests_mutex);
125         if (err != 0) return err;
126
127                 err = freelist_free(&freelist, req);
128                 if (err != 0) goto locked_error;
129
130         err = fosa_mutex_unlock(&requests_mutex);
131         if (err != 0) return err;
132
133         return 0;
134
135 locked_error:
136         fosa_mutex_unlock(&requests_mutex);
137         return err;
138 }
139
140 /**
141  * frescan_requests_get_data() - gets the data of the request
142  *
143  */
144
145 int frescan_requests_get_data(frescan_request_id_t   req,
146                               frescan_request_data_t **data)
147 {
148         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
149         *data = &the_requests_pool[req].request_data;
150         return 0;
151 }
152
153 /**
154  * frescan_requests_enqueue()
155  *
156  **/
157
158 int frescan_requests_enqueue(frescan_request_id_t req)
159 {
160         int err;
161
162         err = fosa_mutex_lock(&requests_mutex);
163         if (err != 0) return err;
164
165         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
166               "is list empty A? %d\n",
167               list_empty(&the_requests_list.request_list));
168
169         list_add_tail(&the_requests_pool[req].request_list,
170                       &the_requests_list.request_list);
171
172         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
173               "is list empty B? %d\n",
174               list_empty(&the_requests_list.request_list));
175
176         err = fosa_cond_signal(&requests_cond);
177         if (err != 0) goto locked_error;
178
179         err = fosa_mutex_unlock(&requests_mutex);
180         if (err != 0) return err;
181
182         return 0;
183
184 locked_error:
185         fosa_mutex_unlock(&requests_mutex);
186         return err;
187 }
188
189 /**
190  * frescan_requestqueue_dequeue()
191  *
192  **/
193
194 int frescan_requests_dequeue(frescan_request_id_t *req)
195 {
196         int err;
197         struct list_head *pos;
198         struct request_t *request = NULL;
199
200         err = fosa_mutex_lock(&requests_mutex);
201         if (err != 0) return err;
202
203         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "entering\n");
204
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");
209         }
210
211         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
212
213         list_for_each(pos, &the_requests_list.request_list) {
214                 request = list_entry(pos, struct request_t, request_list);
215                 break;
216         }
217
218         list_del(&request->request_list);
219
220         *req = request->pool_pos;
221
222         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
223               "is list empty now? %d\n",
224               list_empty(&the_requests_list.request_list));
225
226         err = fosa_mutex_unlock(&requests_mutex);
227         if (err != 0) return err;
228
229         return 0;
230
231 locked_error:
232         fosa_mutex_unlock(&requests_mutex);
233         return err;
234 }