]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_requests.c
renamings... redo the request and messages part... also now there will be two threads...
[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         if (is_initialized == false) return -1;
87
88         err = fosa_mutex_lock(&requests_mutex);
89         if (err != 0) return err;
90
91                 pos = freelist_alloc(&freelist);
92                 if (pos < 0) goto locked_error;
93
94         err = fosa_mutex_unlock(&requests_mutex);
95         if (err != 0) return err;
96
97         *req = (unsigned int)pos;
98         the_requests_pool[*req].pool_pos = pos;
99
100         return 0;
101
102 locked_error:
103         fosa_mutex_unlock(&requests_mutex);
104         return pos;
105 }
106
107 /**
108  * frescan_requests_free()
109  *
110  * free the request from the pool
111  *
112  **/
113
114 int frescan_requests_free(frescan_request_id_t req)
115 {
116         int err;
117
118         if (is_initialized == false) return -1;
119
120         err = fosa_mutex_lock(&requests_mutex);
121         if (err != 0) return err;
122
123                 err = freelist_free(&freelist, req);
124                 if (err != 0) goto locked_error;
125
126         err = fosa_mutex_unlock(&requests_mutex);
127         if (err != 0) return err;
128
129         return 0;
130
131 locked_error:
132         fosa_mutex_unlock(&requests_mutex);
133         return err;
134 }
135
136 /**
137  * frescan_requests_get_data() - gets the data of the request
138  *
139  */
140
141 int frescan_requests_get_data(frescan_request_id_t   req,
142                               frescan_request_data_t **data)
143 {
144         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
145         *data = &the_requests_pool[req].request_data;
146         return 0;
147 }
148
149 /**
150  * frescan_requests_enqueue()
151  *
152  **/
153
154 int frescan_requests_enqueue(frescan_request_id_t req)
155 {
156         int err;
157
158         err = fosa_mutex_lock(&requests_mutex);
159         if (err != 0) return err;
160
161         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
162               "is list empty A? %d\n",
163               list_empty(&the_requests_list.request_list));
164
165         list_add_tail(&the_requests_pool[req].request_list,
166                       &the_requests_list.request_list);
167
168         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
169               "is list empty B? %d\n",
170               list_empty(&the_requests_list.request_list));
171
172         err = fosa_cond_signal(&requests_cond);
173         if (err != 0) goto locked_error;
174
175         err = fosa_mutex_unlock(&requests_mutex);
176         if (err != 0) return err;
177
178         return 0;
179
180 locked_error:
181         fosa_mutex_unlock(&requests_mutex);
182         return err;
183 }
184
185 /**
186  * frescan_requestqueue_dequeue()
187  *
188  **/
189
190 int frescan_requests_dequeue(frescan_request_id_t *req)
191 {
192         int err;
193         struct list_head *pos;
194         struct request_t *request = NULL;
195
196         err = fosa_mutex_lock(&requests_mutex);
197         if (err != 0) return err;
198
199         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "entering\n");
200
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");
205         }
206
207         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
208
209         list_for_each(pos, &the_requests_list.request_list) {
210                 request = list_entry(pos, struct request_t, request_list);
211                 break;
212         }
213
214         list_del(&request->request_list);
215
216         *req = request->pool_pos;
217
218         DEBUG(FRESCAN_REQUESTS_ENABLE_DEBUG,
219               "is list empty now? %d\n",
220               list_empty(&the_requests_list.request_list));
221
222         err = fosa_mutex_unlock(&requests_mutex);
223         if (err != 0) return err;
224
225         return 0;
226
227 locked_error:
228         fosa_mutex_unlock(&requests_mutex);
229         return err;
230 }