Statistics
| Branch: | Revision:

root / src / xseg.c @ a86ebfc3

History | View | Annotate | Download (44.2 kB)

1 6830c9ff Filippos Giannakos
/*
2 6830c9ff Filippos Giannakos
 * Copyright 2012 GRNET S.A. All rights reserved.
3 6830c9ff Filippos Giannakos
 *
4 6830c9ff Filippos Giannakos
 * Redistribution and use in source and binary forms, with or
5 6830c9ff Filippos Giannakos
 * without modification, are permitted provided that the following
6 6830c9ff Filippos Giannakos
 * conditions are met:
7 6830c9ff Filippos Giannakos
 *
8 6830c9ff Filippos Giannakos
 *   1. Redistributions of source code must retain the above
9 6830c9ff Filippos Giannakos
 *      copyright notice, this list of conditions and the following
10 6830c9ff Filippos Giannakos
 *      disclaimer.
11 6830c9ff Filippos Giannakos
 *   2. Redistributions in binary form must reproduce the above
12 6830c9ff Filippos Giannakos
 *      copyright notice, this list of conditions and the following
13 6830c9ff Filippos Giannakos
 *      disclaimer in the documentation and/or other materials
14 6830c9ff Filippos Giannakos
 *      provided with the distribution.
15 6830c9ff Filippos Giannakos
 *
16 6830c9ff Filippos Giannakos
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 6830c9ff Filippos Giannakos
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 6830c9ff Filippos Giannakos
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 6830c9ff Filippos Giannakos
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 6830c9ff Filippos Giannakos
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 6830c9ff Filippos Giannakos
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 6830c9ff Filippos Giannakos
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 6830c9ff Filippos Giannakos
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 6830c9ff Filippos Giannakos
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 6830c9ff Filippos Giannakos
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 6830c9ff Filippos Giannakos
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 6830c9ff Filippos Giannakos
 * POSSIBILITY OF SUCH DAMAGE.
28 6830c9ff Filippos Giannakos
 *
29 6830c9ff Filippos Giannakos
 * The views and conclusions contained in the software and
30 6830c9ff Filippos Giannakos
 * documentation are those of the authors and should not be
31 6830c9ff Filippos Giannakos
 * interpreted as representing official policies, either expressed
32 6830c9ff Filippos Giannakos
 * or implied, of GRNET S.A.
33 6830c9ff Filippos Giannakos
 */
34 6830c9ff Filippos Giannakos
35 6d486cc0 Georgios D. Tsoukalas
#include <xseg/xseg.h>
36 6e0a3771 Georgios D. Tsoukalas
#include <xseg/domain.h>
37 51eafc68 Filippos Giannakos
#include <xseg/util.h>
38 51eafc68 Filippos Giannakos
#include <string.h>
39 6d486cc0 Georgios D. Tsoukalas
40 6d486cc0 Georgios D. Tsoukalas
#ifndef NULL
41 6d486cc0 Georgios D. Tsoukalas
#define NULL ((void *)0)
42 6d486cc0 Georgios D. Tsoukalas
#endif
43 6d486cc0 Georgios D. Tsoukalas
44 6d486cc0 Georgios D. Tsoukalas
#define XSEG_NR_TYPES 16
45 6d486cc0 Georgios D. Tsoukalas
#define XSEG_NR_PEER_TYPES 64
46 6d486cc0 Georgios D. Tsoukalas
#define XSEG_MIN_PAGE_SIZE 4096
47 6d486cc0 Georgios D. Tsoukalas
48 6d486cc0 Georgios D. Tsoukalas
static struct xseg_type *__types[XSEG_NR_TYPES];
49 6d486cc0 Georgios D. Tsoukalas
static unsigned int __nr_types;
50 6d486cc0 Georgios D. Tsoukalas
static struct xseg_peer *__peer_types[XSEG_NR_PEER_TYPES];
51 6d486cc0 Georgios D. Tsoukalas
static unsigned int __nr_peer_types;
52 6d486cc0 Georgios D. Tsoukalas
53 6d486cc0 Georgios D. Tsoukalas
static void __lock_segment(struct xseg *xseg)
54 6d486cc0 Georgios D. Tsoukalas
{
55 85b37014 gtsouk
        volatile uint64_t *flags;
56 6d486cc0 Georgios D. Tsoukalas
        flags = &xseg->shared->flags;
57 6d486cc0 Georgios D. Tsoukalas
        while (__sync_fetch_and_or(flags, XSEG_F_LOCK));
58 6d486cc0 Georgios D. Tsoukalas
}
59 6d486cc0 Georgios D. Tsoukalas
60 6d486cc0 Georgios D. Tsoukalas
static void __unlock_segment(struct xseg *xseg)
61 6d486cc0 Georgios D. Tsoukalas
{
62 85b37014 gtsouk
        volatile uint64_t *flags;
63 6d486cc0 Georgios D. Tsoukalas
        flags = &xseg->shared->flags;
64 6d486cc0 Georgios D. Tsoukalas
        __sync_fetch_and_and(flags, ~XSEG_F_LOCK);
65 6d486cc0 Georgios D. Tsoukalas
}
66 6d486cc0 Georgios D. Tsoukalas
67 6d486cc0 Georgios D. Tsoukalas
static struct xseg_type *__find_type(const char *name, long *index)
68 6d486cc0 Georgios D. Tsoukalas
{
69 6d486cc0 Georgios D. Tsoukalas
        long i;
70 6d486cc0 Georgios D. Tsoukalas
        for (i = 0; (*index = i) < __nr_types; i++)
71 6d486cc0 Georgios D. Tsoukalas
                if (!strncmp(__types[i]->name, name, XSEG_TNAMESIZE))
72 6d486cc0 Georgios D. Tsoukalas
                        return __types[i];
73 6d486cc0 Georgios D. Tsoukalas
        return NULL;
74 6d486cc0 Georgios D. Tsoukalas
}
75 6d486cc0 Georgios D. Tsoukalas
76 6e0a3771 Georgios D. Tsoukalas
static struct xseg_peer *__find_peer_type(const char *name, int64_t *index)
77 6d486cc0 Georgios D. Tsoukalas
{
78 6e0a3771 Georgios D. Tsoukalas
        int64_t i;
79 6d486cc0 Georgios D. Tsoukalas
        for (i = 0; (*index = i) < __nr_peer_types; i++) {
80 6d486cc0 Georgios D. Tsoukalas
                if (!strncmp(__peer_types[i]->name, name, XSEG_TNAMESIZE))
81 6d486cc0 Georgios D. Tsoukalas
                        return __peer_types[i];
82 6d486cc0 Georgios D. Tsoukalas
        }
83 6d486cc0 Georgios D. Tsoukalas
        return NULL;
84 6d486cc0 Georgios D. Tsoukalas
}
85 6d486cc0 Georgios D. Tsoukalas
86 6d486cc0 Georgios D. Tsoukalas
void xseg_report_peer_types(void)
87 6d486cc0 Georgios D. Tsoukalas
{
88 6d486cc0 Georgios D. Tsoukalas
        long i;
89 6e0a3771 Georgios D. Tsoukalas
        XSEGLOG("total %u peer types:\n", __nr_peer_types);
90 6d486cc0 Georgios D. Tsoukalas
        for (i = 0; i < __nr_peer_types; i++)
91 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("%ld: '%s'\n", i, __peer_types[i]->name);
92 6d486cc0 Georgios D. Tsoukalas
}
93 6d486cc0 Georgios D. Tsoukalas
94 6d486cc0 Georgios D. Tsoukalas
static struct xseg_type *__find_or_load_type(const char *name)
95 6d486cc0 Georgios D. Tsoukalas
{
96 6d486cc0 Georgios D. Tsoukalas
        long i;
97 6d486cc0 Georgios D. Tsoukalas
        struct xseg_type *type = __find_type(name, &i);
98 6d486cc0 Georgios D. Tsoukalas
        if (type)
99 6d486cc0 Georgios D. Tsoukalas
                return type;
100 6d486cc0 Georgios D. Tsoukalas
101 6d486cc0 Georgios D. Tsoukalas
        __load_plugin(name);
102 6d486cc0 Georgios D. Tsoukalas
        return __find_type(name, &i);
103 6d486cc0 Georgios D. Tsoukalas
}
104 6d486cc0 Georgios D. Tsoukalas
105 6d486cc0 Georgios D. Tsoukalas
static struct xseg_peer *__find_or_load_peer_type(const char *name)
106 6d486cc0 Georgios D. Tsoukalas
{
107 6e0a3771 Georgios D. Tsoukalas
        int64_t i;
108 6d486cc0 Georgios D. Tsoukalas
        struct xseg_peer *peer_type = __find_peer_type(name, &i);
109 6d486cc0 Georgios D. Tsoukalas
        if (peer_type)
110 6d486cc0 Georgios D. Tsoukalas
                return peer_type;
111 6d486cc0 Georgios D. Tsoukalas
112 6d486cc0 Georgios D. Tsoukalas
        __load_plugin(name);
113 6d486cc0 Georgios D. Tsoukalas
        return __find_peer_type(name, &i);
114 6d486cc0 Georgios D. Tsoukalas
}
115 6d486cc0 Georgios D. Tsoukalas
116 6d486cc0 Georgios D. Tsoukalas
static struct xseg_peer *__get_peer_type(struct xseg *xseg, uint32_t serial)
117 6d486cc0 Georgios D. Tsoukalas
{
118 b0a46d91 Georgios D. Tsoukalas
        char *name;
119 6d486cc0 Georgios D. Tsoukalas
        struct xseg_peer *type;
120 6e0a3771 Georgios D. Tsoukalas
        struct xseg_private *priv = xseg->priv;
121 e005b6d7 Giannakos Filippos
        char (*shared_peer_types)[XSEG_TNAMESIZE];
122 6d486cc0 Georgios D. Tsoukalas
123 4d1da778 Georgios D. Tsoukalas
        if (serial >= xseg->max_peer_types) {
124 4d1da778 Georgios D. Tsoukalas
                XSEGLOG("invalid peer type serial %d >= %d\n",
125 4d1da778 Georgios D. Tsoukalas
                         serial, xseg->max_peer_types);
126 6d486cc0 Georgios D. Tsoukalas
                return NULL;
127 4d1da778 Georgios D. Tsoukalas
        }
128 6d486cc0 Georgios D. Tsoukalas
129 6e0a3771 Georgios D. Tsoukalas
        type = priv->peer_types[serial];
130 6d486cc0 Georgios D. Tsoukalas
        if (type)
131 6d486cc0 Georgios D. Tsoukalas
                return type;
132 6d486cc0 Georgios D. Tsoukalas
133 b0a46d91 Georgios D. Tsoukalas
        /* xseg->shared->peer_types is an append-only array,
134 b0a46d91 Georgios D. Tsoukalas
         * therefore this should be safe
135 b0a46d91 Georgios D. Tsoukalas
         * without either locking or string copying. */
136 18f02d02 Filippos Giannakos
        shared_peer_types = XPTR_TAKE(xseg->shared->peer_types, xseg->segment);
137 b0a46d91 Georgios D. Tsoukalas
        name = shared_peer_types[serial];
138 4d1da778 Georgios D. Tsoukalas
        if (!*name) {
139 4d1da778 Georgios D. Tsoukalas
                XSEGLOG("nonexistent peer type serial %d\n", serial);
140 6d486cc0 Georgios D. Tsoukalas
                return NULL;
141 4d1da778 Georgios D. Tsoukalas
        }
142 6d486cc0 Georgios D. Tsoukalas
143 6d486cc0 Georgios D. Tsoukalas
        type = __find_or_load_peer_type(name);
144 4d1da778 Georgios D. Tsoukalas
        if (!type)
145 4d1da778 Georgios D. Tsoukalas
                XSEGLOG("could not find driver for peer type %d [%s]\n",
146 4d1da778 Georgios D. Tsoukalas
                         serial, name);
147 3b07b042 Stratos Psomadakis
148 6e0a3771 Georgios D. Tsoukalas
        priv->peer_types[serial] = type;
149 6d486cc0 Georgios D. Tsoukalas
        return type;
150 6d486cc0 Georgios D. Tsoukalas
}
151 6d486cc0 Georgios D. Tsoukalas
152 44c41348 Giannakos Filippos
static void * __get_peer_type_data(struct xseg *xseg, uint32_t serial)
153 17590774 Giannakos Filippos
{
154 17590774 Giannakos Filippos
        char *name;
155 44c41348 Giannakos Filippos
        void *data;
156 17590774 Giannakos Filippos
        struct xseg_private *priv = xseg->priv;
157 17590774 Giannakos Filippos
        char (*shared_peer_types)[XSEG_TNAMESIZE];
158 17590774 Giannakos Filippos
        xptr *shared_peer_type_data;
159 17590774 Giannakos Filippos
160 17590774 Giannakos Filippos
        if (serial >= xseg->max_peer_types) {
161 17590774 Giannakos Filippos
                XSEGLOG("invalid peer type serial %d >= %d\n",
162 17590774 Giannakos Filippos
                         serial, xseg->max_peer_types);
163 17590774 Giannakos Filippos
                return 0;
164 17590774 Giannakos Filippos
        }
165 17590774 Giannakos Filippos
166 17590774 Giannakos Filippos
        data = priv->peer_type_data[serial];
167 17590774 Giannakos Filippos
        if (data)
168 17590774 Giannakos Filippos
                return data;
169 17590774 Giannakos Filippos
170 17590774 Giannakos Filippos
        shared_peer_types = XPTR_TAKE(xseg->shared->peer_types, xseg->segment);
171 17590774 Giannakos Filippos
        name = shared_peer_types[serial];
172 17590774 Giannakos Filippos
        if (!*name) {
173 17590774 Giannakos Filippos
                XSEGLOG("nonexistent peer type serial %d\n", serial);
174 17590774 Giannakos Filippos
                return 0;
175 17590774 Giannakos Filippos
        }
176 17590774 Giannakos Filippos
        shared_peer_type_data = XPTR_TAKE(xseg->shared->peer_type_data, xseg->segment);
177 17590774 Giannakos Filippos
178 17590774 Giannakos Filippos
        priv->peer_type_data[serial] = XPTR_TAKE(shared_peer_type_data[serial], xseg->segment);
179 17590774 Giannakos Filippos
        return priv->peer_type_data[serial];
180 17590774 Giannakos Filippos
}
181 17590774 Giannakos Filippos
182 6d486cc0 Georgios D. Tsoukalas
static inline int __validate_port(struct xseg *xseg, uint32_t portno)
183 6d486cc0 Georgios D. Tsoukalas
{
184 6d486cc0 Georgios D. Tsoukalas
        return portno < xseg->config.nr_ports;
185 6d486cc0 Georgios D. Tsoukalas
}
186 6d486cc0 Georgios D. Tsoukalas
187 29040276 Filippos Giannakos
static inline int __validate_ptr(struct xseg *xseg, xptr ptr)
188 29040276 Filippos Giannakos
{
189 29040276 Filippos Giannakos
        return ptr < xseg->segment_size;
190 29040276 Filippos Giannakos
}
191 29040276 Filippos Giannakos
192 6d486cc0 Georgios D. Tsoukalas
/* type:name:nr_ports:nr_requests:request_size:extra_size:page_shift */
193 6d486cc0 Georgios D. Tsoukalas
194 6d486cc0 Georgios D. Tsoukalas
#define TOK(s, sp, def) \
195 6d486cc0 Georgios D. Tsoukalas
        (s) = (sp); \
196 6d486cc0 Georgios D. Tsoukalas
        for (;;) { \
197 6d486cc0 Georgios D. Tsoukalas
                switch (*(sp)) { \
198 6d486cc0 Georgios D. Tsoukalas
                case 0: \
199 6d486cc0 Georgios D. Tsoukalas
                        s = (def); \
200 6d486cc0 Georgios D. Tsoukalas
                        break; \
201 6d486cc0 Georgios D. Tsoukalas
                case ':': \
202 6d486cc0 Georgios D. Tsoukalas
                        *(sp)++ = 0; \
203 6d486cc0 Georgios D. Tsoukalas
                        break; \
204 6d486cc0 Georgios D. Tsoukalas
                default: \
205 6d486cc0 Georgios D. Tsoukalas
                        (sp) ++; \
206 6d486cc0 Georgios D. Tsoukalas
                        continue; \
207 6d486cc0 Georgios D. Tsoukalas
                } \
208 6d486cc0 Georgios D. Tsoukalas
                break; \
209 6d486cc0 Georgios D. Tsoukalas
        } \
210 6d486cc0 Georgios D. Tsoukalas
211 6d486cc0 Georgios D. Tsoukalas
static unsigned long strul(char *s)
212 6d486cc0 Georgios D. Tsoukalas
{
213 6d486cc0 Georgios D. Tsoukalas
        unsigned long n = 0;
214 6d486cc0 Georgios D. Tsoukalas
        for (;;) {
215 6d486cc0 Georgios D. Tsoukalas
                unsigned char c = *s - '0';
216 6d486cc0 Georgios D. Tsoukalas
                if (c >= 10)
217 6d486cc0 Georgios D. Tsoukalas
                        break;
218 6d486cc0 Georgios D. Tsoukalas
                n = n * 10 + c;
219 6d486cc0 Georgios D. Tsoukalas
                s ++;
220 6d486cc0 Georgios D. Tsoukalas
        }
221 6d486cc0 Georgios D. Tsoukalas
        return n;
222 6d486cc0 Georgios D. Tsoukalas
}
223 6d486cc0 Georgios D. Tsoukalas
224 6d486cc0 Georgios D. Tsoukalas
/*
225 6d486cc0 Georgios D. Tsoukalas
static char *strncopy(char *dest, const char *src, uint32_t n)
226 6d486cc0 Georgios D. Tsoukalas
{
227 6d486cc0 Georgios D. Tsoukalas
        uint32_t i;
228 6d486cc0 Georgios D. Tsoukalas
        char c;
229 6d486cc0 Georgios D. Tsoukalas
        for (i = 0; i < n; i++) {
230 6d486cc0 Georgios D. Tsoukalas
                c = src[i];
231 6d486cc0 Georgios D. Tsoukalas
                dest[i] = c;
232 6d486cc0 Georgios D. Tsoukalas
                if (!c)
233 6d486cc0 Georgios D. Tsoukalas
                        break;
234 6d486cc0 Georgios D. Tsoukalas
        }
235 6d486cc0 Georgios D. Tsoukalas
        dest[n-1] = 0;
236 6d486cc0 Georgios D. Tsoukalas
        return dest;
237 6d486cc0 Georgios D. Tsoukalas
}
238 6d486cc0 Georgios D. Tsoukalas
*/
239 6d486cc0 Georgios D. Tsoukalas
240 6d486cc0 Georgios D. Tsoukalas
int xseg_parse_spec(char *segspec, struct xseg_config *config)
241 6d486cc0 Georgios D. Tsoukalas
{
242 0f944d14 Filippos Giannakos
        /* default: "posix:globalxseg:64:128:256:12" */
243 6d486cc0 Georgios D. Tsoukalas
        char *s = segspec, *sp = segspec;
244 6d486cc0 Georgios D. Tsoukalas
245 6d486cc0 Georgios D. Tsoukalas
        /* type */
246 6d486cc0 Georgios D. Tsoukalas
        TOK(s, sp, "posix");
247 6d486cc0 Georgios D. Tsoukalas
        strncpy(config->type, s, XSEG_TNAMESIZE);
248 6d486cc0 Georgios D. Tsoukalas
        config->type[XSEG_TNAMESIZE-1] = 0;
249 6d486cc0 Georgios D. Tsoukalas
250 6d486cc0 Georgios D. Tsoukalas
        /* name */
251 6d486cc0 Georgios D. Tsoukalas
        TOK(s, sp, "globalxseg");
252 6d486cc0 Georgios D. Tsoukalas
        strncpy(config->name, s, XSEG_NAMESIZE);
253 6d486cc0 Georgios D. Tsoukalas
        config->name[XSEG_NAMESIZE-1] = 0;
254 6d486cc0 Georgios D. Tsoukalas
255 0f944d14 Filippos Giannakos
        /* dynports */
256 0f944d14 Filippos Giannakos
        TOK(s, sp, "64");
257 0f944d14 Filippos Giannakos
        config->dynports = strul(s);
258 0f944d14 Filippos Giannakos
259 6d486cc0 Georgios D. Tsoukalas
        /* nr_ports */
260 0f944d14 Filippos Giannakos
        TOK(s, sp, "128");
261 6d486cc0 Georgios D. Tsoukalas
        config->nr_ports = strul(s);
262 6d486cc0 Georgios D. Tsoukalas
263 0f944d14 Filippos Giannakos
264 0a5d10a9 Filippos Giannakos
        /* heap_size */
265 0a5d10a9 Filippos Giannakos
        TOK(s, sp, "256");
266 0a5d10a9 Filippos Giannakos
        config->heap_size = (uint64_t) (strul(s) * 1024UL * 1024UL);
267 6d486cc0 Georgios D. Tsoukalas
268 6d486cc0 Georgios D. Tsoukalas
        /* page_shift */
269 6d486cc0 Georgios D. Tsoukalas
        TOK(s, sp, "12");
270 6d486cc0 Georgios D. Tsoukalas
        config->page_shift = strul(s);
271 6d486cc0 Georgios D. Tsoukalas
        return 0;
272 6d486cc0 Georgios D. Tsoukalas
}
273 6d486cc0 Georgios D. Tsoukalas
274 6d486cc0 Georgios D. Tsoukalas
int xseg_register_type(struct xseg_type *type)
275 6d486cc0 Georgios D. Tsoukalas
{
276 6d486cc0 Georgios D. Tsoukalas
        long i;
277 6e0a3771 Georgios D. Tsoukalas
        int r = -1;
278 6e0a3771 Georgios D. Tsoukalas
        struct xseg_type *__type;
279 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
280 6e0a3771 Georgios D. Tsoukalas
        __type = __find_type(type->name, &i);
281 6d486cc0 Georgios D. Tsoukalas
        if (__type) {
282 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("type %s already exists\n", type->name);
283 6e0a3771 Georgios D. Tsoukalas
                goto out;
284 6d486cc0 Georgios D. Tsoukalas
        }
285 6d486cc0 Georgios D. Tsoukalas
286 6d486cc0 Georgios D. Tsoukalas
        if (__nr_types >= XSEG_NR_TYPES) {
287 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("maximum type registrations reached: %u\n", __nr_types);
288 6e0a3771 Georgios D. Tsoukalas
                r -= 1;
289 6e0a3771 Georgios D. Tsoukalas
                goto out;
290 6d486cc0 Georgios D. Tsoukalas
        }
291 6d486cc0 Georgios D. Tsoukalas
292 6d486cc0 Georgios D. Tsoukalas
        type->name[XSEG_TNAMESIZE-1] = 0;
293 6d486cc0 Georgios D. Tsoukalas
        __types[__nr_types] = type;
294 6d486cc0 Georgios D. Tsoukalas
        __nr_types += 1;
295 6e0a3771 Georgios D. Tsoukalas
        r = 0;
296 6e0a3771 Georgios D. Tsoukalas
out:
297 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
298 6e0a3771 Georgios D. Tsoukalas
        return r;
299 6d486cc0 Georgios D. Tsoukalas
}
300 6d486cc0 Georgios D. Tsoukalas
301 6d486cc0 Georgios D. Tsoukalas
int xseg_unregister_type(const char *name)
302 6d486cc0 Georgios D. Tsoukalas
{
303 6d486cc0 Georgios D. Tsoukalas
        long i;
304 6e0a3771 Georgios D. Tsoukalas
        int r = -1;
305 6e0a3771 Georgios D. Tsoukalas
        struct xseg_type *__type;
306 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
307 6e0a3771 Georgios D. Tsoukalas
        __type = __find_type(name, &i);
308 6d486cc0 Georgios D. Tsoukalas
        if (!__type) {
309 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("segment type '%s' does not exist\n", name);
310 6e0a3771 Georgios D. Tsoukalas
                goto out;
311 6d486cc0 Georgios D. Tsoukalas
        }
312 6d486cc0 Georgios D. Tsoukalas
313 6d486cc0 Georgios D. Tsoukalas
        __nr_types -= 1;
314 6d486cc0 Georgios D. Tsoukalas
        __types[i] = __types[__nr_types];
315 6d486cc0 Georgios D. Tsoukalas
        __types[__nr_types] = NULL;
316 6e0a3771 Georgios D. Tsoukalas
        r = 0;
317 6e0a3771 Georgios D. Tsoukalas
out:
318 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
319 6e0a3771 Georgios D. Tsoukalas
        return r;
320 6d486cc0 Georgios D. Tsoukalas
}
321 6d486cc0 Georgios D. Tsoukalas
322 6d486cc0 Georgios D. Tsoukalas
int xseg_register_peer(struct xseg_peer *peer_type)
323 6d486cc0 Georgios D. Tsoukalas
{
324 6e0a3771 Georgios D. Tsoukalas
        int64_t i;
325 6e0a3771 Georgios D. Tsoukalas
        int r = -1;
326 6e0a3771 Georgios D. Tsoukalas
        struct xseg_peer *type;
327 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
328 6e0a3771 Georgios D. Tsoukalas
        type = __find_peer_type(peer_type->name, &i);
329 6d486cc0 Georgios D. Tsoukalas
        if (type) {
330 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("peer type '%s' already exists\n", type->name);
331 6e0a3771 Georgios D. Tsoukalas
                goto out;
332 6d486cc0 Georgios D. Tsoukalas
        }
333 6d486cc0 Georgios D. Tsoukalas
334 6d486cc0 Georgios D. Tsoukalas
        if (__nr_peer_types >= XSEG_NR_PEER_TYPES) {
335 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("maximum peer type registrations reached: %u",
336 6d486cc0 Georgios D. Tsoukalas
                        __nr_peer_types);
337 6e0a3771 Georgios D. Tsoukalas
                r -= 1;
338 6e0a3771 Georgios D. Tsoukalas
                goto out;
339 6d486cc0 Georgios D. Tsoukalas
        }
340 6d486cc0 Georgios D. Tsoukalas
341 9fb0f83b Filippos Giannakos
        if (peer_type->peer_ops.remote_signal_init()) {
342 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("peer type '%s': signal initialization failed\n",
343 6d486cc0 Georgios D. Tsoukalas
                        peer_type->name);
344 6e0a3771 Georgios D. Tsoukalas
                r -= 1;
345 6e0a3771 Georgios D. Tsoukalas
                goto out;
346 6d486cc0 Georgios D. Tsoukalas
        }
347 1b52f571 Stratos Psomadakis
348 6d486cc0 Georgios D. Tsoukalas
        peer_type->name[XSEG_TNAMESIZE-1] = 0;
349 6d486cc0 Georgios D. Tsoukalas
        __peer_types[__nr_peer_types] = peer_type;
350 6d486cc0 Georgios D. Tsoukalas
        __nr_peer_types += 1;
351 6e0a3771 Georgios D. Tsoukalas
        r = 0;
352 1b52f571 Stratos Psomadakis
353 6e0a3771 Georgios D. Tsoukalas
out:
354 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
355 6e0a3771 Georgios D. Tsoukalas
        return r;
356 6d486cc0 Georgios D. Tsoukalas
}
357 6d486cc0 Georgios D. Tsoukalas
358 6d486cc0 Georgios D. Tsoukalas
int xseg_unregister_peer(const char *name)
359 6d486cc0 Georgios D. Tsoukalas
{
360 6e0a3771 Georgios D. Tsoukalas
        int64_t i;
361 6e0a3771 Georgios D. Tsoukalas
        struct xseg_peer *driver;
362 6e0a3771 Georgios D. Tsoukalas
        int r = -1;
363 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
364 6e0a3771 Georgios D. Tsoukalas
        driver = __find_peer_type(name, &i);
365 6e0a3771 Georgios D. Tsoukalas
        if (!driver) {
366 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("peer type '%s' does not exist\n", name);
367 6e0a3771 Georgios D. Tsoukalas
                goto out;
368 6d486cc0 Georgios D. Tsoukalas
        }
369 6d486cc0 Georgios D. Tsoukalas
370 6d486cc0 Georgios D. Tsoukalas
        __nr_peer_types -= 1;
371 6d486cc0 Georgios D. Tsoukalas
        __peer_types[i] = __peer_types[__nr_peer_types];
372 6d486cc0 Georgios D. Tsoukalas
        __peer_types[__nr_peer_types] = NULL;
373 9fb0f83b Filippos Giannakos
        driver->peer_ops.remote_signal_quit();
374 6e0a3771 Georgios D. Tsoukalas
        r = 0;
375 6e0a3771 Georgios D. Tsoukalas
out:
376 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
377 6e0a3771 Georgios D. Tsoukalas
        return r;
378 6d486cc0 Georgios D. Tsoukalas
}
379 6d486cc0 Georgios D. Tsoukalas
380 6e0a3771 Georgios D. Tsoukalas
int64_t __enable_driver(struct xseg *xseg, struct xseg_peer *driver)
381 6d486cc0 Georgios D. Tsoukalas
{
382 6e0a3771 Georgios D. Tsoukalas
        int64_t r;
383 6d486cc0 Georgios D. Tsoukalas
        char (*drivers)[XSEG_TNAMESIZE];
384 44c41348 Giannakos Filippos
        xptr *ptd;
385 6d486cc0 Georgios D. Tsoukalas
        uint32_t max_drivers = xseg->max_peer_types;
386 17590774 Giannakos Filippos
        void *data;
387 17590774 Giannakos Filippos
        xptr peer_type_data;
388 6d486cc0 Georgios D. Tsoukalas
389 6d486cc0 Georgios D. Tsoukalas
        if (xseg->shared->nr_peer_types >= max_drivers) {
390 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("cannot register '%s': driver namespace full\n",
391 6d486cc0 Georgios D. Tsoukalas
                        driver->name);
392 6d486cc0 Georgios D. Tsoukalas
                return -1;
393 6d486cc0 Georgios D. Tsoukalas
        }
394 6d486cc0 Georgios D. Tsoukalas
395 18f02d02 Filippos Giannakos
        drivers = XPTR_TAKE(xseg->shared->peer_types, xseg->segment);
396 6d486cc0 Georgios D. Tsoukalas
        for (r = 0; r < max_drivers; r++) {
397 6d486cc0 Georgios D. Tsoukalas
                if (!*drivers[r])
398 6d486cc0 Georgios D. Tsoukalas
                        goto bind;
399 44c41348 Giannakos Filippos
                if (!strncmp(drivers[r], driver->name, XSEG_TNAMESIZE)){
400 44c41348 Giannakos Filippos
                        data = __get_peer_type_data(xseg, r);
401 6d486cc0 Georgios D. Tsoukalas
                        goto success;
402 44c41348 Giannakos Filippos
                }
403 6d486cc0 Georgios D. Tsoukalas
        }
404 6d486cc0 Georgios D. Tsoukalas
405 6d486cc0 Georgios D. Tsoukalas
        /* Unreachable */
406 6d486cc0 Georgios D. Tsoukalas
        return -666;
407 6d486cc0 Georgios D. Tsoukalas
408 6d486cc0 Georgios D. Tsoukalas
bind:
409 6d486cc0 Georgios D. Tsoukalas
        /* assert(xseg->shared->nr_peer_types == r); */
410 17590774 Giannakos Filippos
        data = driver->peer_ops.alloc_data(xseg);
411 17590774 Giannakos Filippos
        if (!data)
412 17590774 Giannakos Filippos
                return -1;
413 17590774 Giannakos Filippos
        peer_type_data = XPTR_MAKE(data, xseg->segment);
414 44c41348 Giannakos Filippos
        ptd = XPTR_TAKE(xseg->shared->peer_type_data, xseg->segment);
415 44c41348 Giannakos Filippos
        ptd[r] = peer_type_data;
416 6d486cc0 Georgios D. Tsoukalas
        xseg->shared->nr_peer_types = r + 1;
417 6d486cc0 Georgios D. Tsoukalas
        strncpy(drivers[r], driver->name, XSEG_TNAMESIZE);
418 6d486cc0 Georgios D. Tsoukalas
        drivers[r][XSEG_TNAMESIZE-1] = 0;
419 6d486cc0 Georgios D. Tsoukalas
420 6d486cc0 Georgios D. Tsoukalas
success:
421 6e0a3771 Georgios D. Tsoukalas
        xseg->priv->peer_types[r] = driver;
422 44c41348 Giannakos Filippos
        xseg->priv->peer_type_data[r] = data;
423 e005b6d7 Giannakos Filippos
        return r;
424 6d486cc0 Georgios D. Tsoukalas
}
425 6d486cc0 Georgios D. Tsoukalas
426 6e0a3771 Georgios D. Tsoukalas
int64_t xseg_enable_driver(struct xseg *xseg, const char *name)
427 6d486cc0 Georgios D. Tsoukalas
{
428 6e0a3771 Georgios D. Tsoukalas
        int64_t r = -1;
429 6e0a3771 Georgios D. Tsoukalas
        struct xseg_peer *driver;
430 6d486cc0 Georgios D. Tsoukalas
431 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
432 6e0a3771 Georgios D. Tsoukalas
        driver = __find_peer_type(name, &r);
433 6d486cc0 Georgios D. Tsoukalas
        if (!driver) {
434 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("driver '%s' not found\n", name);
435 6e0a3771 Georgios D. Tsoukalas
                goto out;
436 6d486cc0 Georgios D. Tsoukalas
        }
437 6d486cc0 Georgios D. Tsoukalas
438 6d486cc0 Georgios D. Tsoukalas
        __lock_segment(xseg);
439 6d486cc0 Georgios D. Tsoukalas
        r = __enable_driver(xseg, driver);
440 6d486cc0 Georgios D. Tsoukalas
        __unlock_segment(xseg);
441 6e0a3771 Georgios D. Tsoukalas
out:
442 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
443 6d486cc0 Georgios D. Tsoukalas
        return r;
444 6d486cc0 Georgios D. Tsoukalas
}
445 6d486cc0 Georgios D. Tsoukalas
446 6d486cc0 Georgios D. Tsoukalas
int xseg_disable_driver(struct xseg *xseg, const char *name)
447 6d486cc0 Georgios D. Tsoukalas
{
448 6e0a3771 Georgios D. Tsoukalas
        int64_t i;
449 6e0a3771 Georgios D. Tsoukalas
        int r = -1;
450 6e0a3771 Georgios D. Tsoukalas
        struct xseg_private *priv = xseg->priv;
451 6e0a3771 Georgios D. Tsoukalas
        struct xseg_peer *driver;
452 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
453 6e0a3771 Georgios D. Tsoukalas
        driver =  __find_peer_type(name, &i);
454 6d486cc0 Georgios D. Tsoukalas
        if (!driver) {
455 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("driver '%s' not found\n", name);
456 6e0a3771 Georgios D. Tsoukalas
                goto out;
457 6d486cc0 Georgios D. Tsoukalas
        }
458 6d486cc0 Georgios D. Tsoukalas
459 6d486cc0 Georgios D. Tsoukalas
        for (i = 0; i < xseg->max_peer_types; i++)
460 6e0a3771 Georgios D. Tsoukalas
                if (priv->peer_types[i] == driver)
461 6e0a3771 Georgios D. Tsoukalas
                        priv->peer_types[i] = NULL;
462 6e0a3771 Georgios D. Tsoukalas
        r = 0;
463 6e0a3771 Georgios D. Tsoukalas
out:
464 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
465 6e0a3771 Georgios D. Tsoukalas
        return r;
466 6d486cc0 Georgios D. Tsoukalas
}
467 6d486cc0 Georgios D. Tsoukalas
468 6d486cc0 Georgios D. Tsoukalas
/* NOTE: calculate_segment_size() and initialize_segment()
469 6d486cc0 Georgios D. Tsoukalas
 * must always be exactly in sync!
470 6d486cc0 Georgios D. Tsoukalas
*/
471 6d486cc0 Georgios D. Tsoukalas
472 6d486cc0 Georgios D. Tsoukalas
static uint64_t calculate_segment_size(struct xseg_config *config)
473 6d486cc0 Georgios D. Tsoukalas
{
474 6d486cc0 Georgios D. Tsoukalas
        uint64_t size = 0;
475 6d486cc0 Georgios D. Tsoukalas
        uint32_t page_size, page_shift = config->page_shift;
476 6d486cc0 Georgios D. Tsoukalas
477 6d486cc0 Georgios D. Tsoukalas
        /* assert(sizeof(struct xseg) <= (1 << 9)); */
478 6d486cc0 Georgios D. Tsoukalas
479 6d486cc0 Georgios D. Tsoukalas
        if (page_shift < 9) {
480 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("page_shift must be >= %d\n", 9);
481 6d486cc0 Georgios D. Tsoukalas
                return 0;
482 6d486cc0 Georgios D. Tsoukalas
        }
483 6d486cc0 Georgios D. Tsoukalas
484 6d486cc0 Georgios D. Tsoukalas
        page_size = 1 << page_shift;
485 6d486cc0 Georgios D. Tsoukalas
486 0bf9fcf7 Filippos Giannakos
        /* struct xseg itself + struct xheap */
487 0bf9fcf7 Filippos Giannakos
        size += 2*page_size + config->heap_size;
488 6d486cc0 Georgios D. Tsoukalas
        size = __align(size, page_shift);
489 29040276 Filippos Giannakos
        
490 6d486cc0 Georgios D. Tsoukalas
        return size;
491 6d486cc0 Georgios D. Tsoukalas
}
492 6d486cc0 Georgios D. Tsoukalas
493 6d486cc0 Georgios D. Tsoukalas
static long initialize_segment(struct xseg *xseg, struct xseg_config *cfg)
494 6d486cc0 Georgios D. Tsoukalas
{
495 6d486cc0 Georgios D. Tsoukalas
        uint32_t page_shift = cfg->page_shift, page_size = 1 << page_shift;
496 6d486cc0 Georgios D. Tsoukalas
        struct xseg_shared *shared;
497 6d486cc0 Georgios D. Tsoukalas
        char *segment = (char *)xseg;
498 0a5d10a9 Filippos Giannakos
        uint64_t size = page_size, i;
499 0bf9fcf7 Filippos Giannakos
        void *mem;
500 0bf9fcf7 Filippos Giannakos
        struct xheap *heap;
501 0bf9fcf7 Filippos Giannakos
        struct xobject_h *obj_h;
502 0bf9fcf7 Filippos Giannakos
        int r;
503 441202a7 Filippos Giannakos
        xptr *ports;
504 9a418f2f Filippos Giannakos
        xport *gw;
505 29040276 Filippos Giannakos
506 6d486cc0 Georgios D. Tsoukalas
507 6d486cc0 Georgios D. Tsoukalas
        if (page_size < XSEG_MIN_PAGE_SIZE)
508 6d486cc0 Georgios D. Tsoukalas
                return -1;
509 6d486cc0 Georgios D. Tsoukalas
510 8ed1ddbb Filippos Giannakos
        xseg->version = XSEG_VERSION;
511 18f02d02 Filippos Giannakos
        xseg->segment_size = 2 * page_size + cfg->heap_size;
512 441202a7 Filippos Giannakos
        xseg->segment = (struct xseg *) segment;
513 6d486cc0 Georgios D. Tsoukalas
514 29040276 Filippos Giannakos
        /* build heap */
515 441202a7 Filippos Giannakos
        xseg->heap = (struct xheap *) XPTR_MAKE(segment + size, segment);
516 0bf9fcf7 Filippos Giannakos
        size += sizeof(struct xheap);
517 6d486cc0 Georgios D. Tsoukalas
        size = __align(size, page_shift);
518 6d486cc0 Georgios D. Tsoukalas
519 0bf9fcf7 Filippos Giannakos
        heap = XPTR_TAKE(xseg->heap, segment);
520 18f02d02 Filippos Giannakos
        r = xheap_init(heap, cfg->heap_size, page_shift, segment+size);
521 0bf9fcf7 Filippos Giannakos
        if (r < 0)
522 0bf9fcf7 Filippos Giannakos
                return -1;
523 6d486cc0 Georgios D. Tsoukalas
524 29040276 Filippos Giannakos
        /* build object_handler handler */
525 0a5d10a9 Filippos Giannakos
        mem = xheap_allocate(heap, sizeof(struct xobject_h));
526 29040276 Filippos Giannakos
        if (!mem)
527 29040276 Filippos Giannakos
                return -1;
528 441202a7 Filippos Giannakos
        xseg->object_handlers = (struct xobject_h *) XPTR_MAKE(mem, segment);
529 0bf9fcf7 Filippos Giannakos
        obj_h = mem;
530 0bf9fcf7 Filippos Giannakos
        r = xobj_handler_init(obj_h, segment, MAGIC_OBJH, 
531 0bf9fcf7 Filippos Giannakos
                        sizeof(struct xobject_h), heap);
532 18f02d02 Filippos Giannakos
        if (r < 0)
533 29040276 Filippos Giannakos
                return -1;
534 6d486cc0 Georgios D. Tsoukalas
535 29040276 Filippos Giannakos
        //now that we have object handlers handler, use that to allocate
536 29040276 Filippos Giannakos
        //new object handlers
537 29040276 Filippos Giannakos
        
538 29040276 Filippos Giannakos
        //allocate requests handler
539 4494b184 Filippos Giannakos
        mem = xobj_get_obj(obj_h, X_ALLOC);
540 29040276 Filippos Giannakos
        if (!mem)
541 29040276 Filippos Giannakos
                return -1;
542 0bf9fcf7 Filippos Giannakos
        obj_h = mem;
543 0bf9fcf7 Filippos Giannakos
        r = xobj_handler_init(obj_h, segment, MAGIC_REQ, 
544 0bf9fcf7 Filippos Giannakos
                        sizeof(struct xseg_request), heap);
545 18f02d02 Filippos Giannakos
        if (r < 0)
546 29040276 Filippos Giannakos
                return -1;
547 441202a7 Filippos Giannakos
        xseg->request_h = (struct xobject_h *) XPTR_MAKE(obj_h, segment);
548 29040276 Filippos Giannakos
        
549 29040276 Filippos Giannakos
        //allocate ports handler
550 0bf9fcf7 Filippos Giannakos
        obj_h = XPTR_TAKE(xseg->object_handlers, segment);
551 4494b184 Filippos Giannakos
        mem = xobj_get_obj(obj_h, X_ALLOC);
552 29040276 Filippos Giannakos
        if (!mem)
553 29040276 Filippos Giannakos
                return -1;
554 0bf9fcf7 Filippos Giannakos
        obj_h = mem;
555 0bf9fcf7 Filippos Giannakos
        r = xobj_handler_init(obj_h, segment, MAGIC_PORT, 
556 0bf9fcf7 Filippos Giannakos
                        sizeof(struct xseg_port), heap);
557 18f02d02 Filippos Giannakos
        if (r < 0)
558 29040276 Filippos Giannakos
                return -1;
559 441202a7 Filippos Giannakos
        xseg->port_h = (struct xobject_h *) XPTR_MAKE(mem, segment);
560 4494b184 Filippos Giannakos
561 4494b184 Filippos Giannakos
        //allocate xptr port array to be used as a map
562 4494b184 Filippos Giannakos
        //portno <--> xptr port
563 0a5d10a9 Filippos Giannakos
        mem = xheap_allocate(heap, sizeof(xptr)*cfg->nr_ports);
564 4494b184 Filippos Giannakos
        if (!mem)
565 4494b184 Filippos Giannakos
                return -1;
566 441202a7 Filippos Giannakos
        ports = mem;
567 0a5d10a9 Filippos Giannakos
        for (i = 0; i < cfg->nr_ports; i++) {
568 4494b184 Filippos Giannakos
                ports[i]=0;
569 4494b184 Filippos Giannakos
        }
570 441202a7 Filippos Giannakos
        xseg->ports = (xptr *) XPTR_MAKE(mem, segment);
571 9a418f2f Filippos Giannakos
572 9a418f2f Filippos Giannakos
        //allocate {src,dst} gws
573 9a418f2f Filippos Giannakos
        mem = xheap_allocate(heap, sizeof(xport) * cfg->nr_ports);
574 9a418f2f Filippos Giannakos
        if (!mem)
575 9a418f2f Filippos Giannakos
                return -1;
576 9a418f2f Filippos Giannakos
        gw = mem;
577 9a418f2f Filippos Giannakos
        for (i = 0; i < cfg->nr_ports; i++) {
578 e3052736 Filippos Giannakos
                gw[i] = NoPort;
579 9a418f2f Filippos Giannakos
        }
580 e3052736 Filippos Giannakos
        xseg->path_next = (xport *) XPTR_MAKE(mem, segment);
581 9a418f2f Filippos Giannakos
582 9a418f2f Filippos Giannakos
        mem = xheap_allocate(heap, sizeof(xport) * cfg->nr_ports);
583 9a418f2f Filippos Giannakos
        if (!mem)
584 9a418f2f Filippos Giannakos
                return -1;
585 9a418f2f Filippos Giannakos
        gw = mem;
586 9a418f2f Filippos Giannakos
        for (i = 0; i < cfg->nr_ports; i++) {
587 e3052736 Filippos Giannakos
                gw[i] = NoPort;
588 9a418f2f Filippos Giannakos
        }
589 9a418f2f Filippos Giannakos
        xseg->dst_gw = (xport *) XPTR_MAKE(mem, segment);
590 29040276 Filippos Giannakos
        
591 29040276 Filippos Giannakos
        //allocate xseg_shared memory
592 4494b184 Filippos Giannakos
        mem = xheap_allocate(heap, sizeof(struct xseg_shared));
593 29040276 Filippos Giannakos
        if (!mem)
594 29040276 Filippos Giannakos
                return -1;
595 0bf9fcf7 Filippos Giannakos
        shared = (struct xseg_shared *) mem;
596 6d486cc0 Georgios D. Tsoukalas
        shared->flags = 0;
597 6d486cc0 Georgios D. Tsoukalas
        shared->nr_peer_types = 0;
598 441202a7 Filippos Giannakos
        xseg->shared = (struct xseg_shared *) XPTR_MAKE(mem, segment);
599 29040276 Filippos Giannakos
        
600 4494b184 Filippos Giannakos
        mem = xheap_allocate(heap, page_size);
601 29040276 Filippos Giannakos
        if (!mem)
602 29040276 Filippos Giannakos
                return -1;
603 441202a7 Filippos Giannakos
        shared->peer_types = (char **) XPTR_MAKE(mem, segment);
604 0bf9fcf7 Filippos Giannakos
        xseg->max_peer_types = xheap_get_chunk_size(mem) / XSEG_TNAMESIZE;
605 44c41348 Giannakos Filippos
        mem = xheap_allocate(heap, xseg->max_peer_types * sizeof(xptr));
606 17590774 Giannakos Filippos
        if (!mem)
607 17590774 Giannakos Filippos
                return -1;
608 b911a183 Giannakos Filippos
        memset(mem, 0, xheap_get_chunk_size(mem));
609 17590774 Giannakos Filippos
        shared->peer_type_data = (xptr *) XPTR_MAKE(mem, segment);
610 6d486cc0 Georgios D. Tsoukalas
611 6d486cc0 Georgios D. Tsoukalas
        memcpy(&xseg->config, cfg, sizeof(struct xseg_config));
612 1b52f571 Stratos Psomadakis
613 1b52f571 Stratos Psomadakis
        xseg->counters.req_cnt = 0;
614 1b52f571 Stratos Psomadakis
        xseg->counters.avg_req_lat = 0;
615 1b52f571 Stratos Psomadakis
616 6d486cc0 Georgios D. Tsoukalas
        return 0;
617 6d486cc0 Georgios D. Tsoukalas
}
618 6d486cc0 Georgios D. Tsoukalas
619 6d486cc0 Georgios D. Tsoukalas
int xseg_create(struct xseg_config *cfg)
620 6d486cc0 Georgios D. Tsoukalas
{
621 6d486cc0 Georgios D. Tsoukalas
        struct xseg *xseg = NULL;
622 6d486cc0 Georgios D. Tsoukalas
        struct xseg_type *type;
623 6d486cc0 Georgios D. Tsoukalas
        struct xseg_operations *xops;
624 6d486cc0 Georgios D. Tsoukalas
        uint64_t size;
625 6d486cc0 Georgios D. Tsoukalas
        long r;
626 6d486cc0 Georgios D. Tsoukalas
627 f942419e Filippos Giannakos
        if (cfg->dynports >= cfg->nr_ports) {
628 f942419e Filippos Giannakos
                XSEGLOG("Invalid config: Dynamic ports >= Total number of ports");
629 f942419e Filippos Giannakos
                goto out_err;
630 f942419e Filippos Giannakos
        }
631 f942419e Filippos Giannakos
632 6d486cc0 Georgios D. Tsoukalas
        type = __find_or_load_type(cfg->type);
633 6d486cc0 Georgios D. Tsoukalas
        if (!type) {
634 6d486cc0 Georgios D. Tsoukalas
                cfg->type[XSEG_TNAMESIZE-1] = 0;
635 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("type '%s' does not exist\n", cfg->type);
636 6d486cc0 Georgios D. Tsoukalas
                goto out_err;
637 6d486cc0 Georgios D. Tsoukalas
        }
638 6d486cc0 Georgios D. Tsoukalas
639 6d486cc0 Georgios D. Tsoukalas
        size = calculate_segment_size(cfg);
640 6d486cc0 Georgios D. Tsoukalas
        if (!size) {
641 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("invalid config!\n");
642 6d486cc0 Georgios D. Tsoukalas
                goto out_err;
643 6d486cc0 Georgios D. Tsoukalas
        }
644 6d486cc0 Georgios D. Tsoukalas
645 6d486cc0 Georgios D. Tsoukalas
        xops = &type->ops;
646 6d486cc0 Georgios D. Tsoukalas
        cfg->name[XSEG_NAMESIZE-1] = 0;
647 d5b20e14 Filippos Giannakos
//        XSEGLOG("creating segment of size %llu\n", size);
648 6d486cc0 Georgios D. Tsoukalas
        r = xops->allocate(cfg->name, size);
649 6d486cc0 Georgios D. Tsoukalas
        if (r) {
650 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("cannot allocate segment!\n");
651 6d486cc0 Georgios D. Tsoukalas
                goto out_err;
652 6d486cc0 Georgios D. Tsoukalas
        }
653 6d486cc0 Georgios D. Tsoukalas
654 7ce25cf6 Stratos Psomadakis
        xseg = xops->map(cfg->name, size, NULL);
655 6d486cc0 Georgios D. Tsoukalas
        if (!xseg) {
656 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("cannot map segment!\n");
657 6d486cc0 Georgios D. Tsoukalas
                goto out_deallocate;
658 6d486cc0 Georgios D. Tsoukalas
        }
659 6d486cc0 Georgios D. Tsoukalas
660 6d486cc0 Georgios D. Tsoukalas
        r = initialize_segment(xseg, cfg);
661 6d486cc0 Georgios D. Tsoukalas
        xops->unmap(xseg, size);
662 6d486cc0 Georgios D. Tsoukalas
        if (r) {
663 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("cannot initilize segment!\n");
664 6d486cc0 Georgios D. Tsoukalas
                goto out_deallocate;
665 6d486cc0 Georgios D. Tsoukalas
        }
666 6d486cc0 Georgios D. Tsoukalas
667 1b52f571 Stratos Psomadakis
668 6d486cc0 Georgios D. Tsoukalas
        return 0;
669 6d486cc0 Georgios D. Tsoukalas
670 6d486cc0 Georgios D. Tsoukalas
out_deallocate:
671 6d486cc0 Georgios D. Tsoukalas
        xops->deallocate(cfg->name);
672 6d486cc0 Georgios D. Tsoukalas
out_err:
673 6d486cc0 Georgios D. Tsoukalas
        return -1;
674 6d486cc0 Georgios D. Tsoukalas
}
675 6d486cc0 Georgios D. Tsoukalas
676 6d486cc0 Georgios D. Tsoukalas
void xseg_destroy(struct xseg *xseg)
677 6d486cc0 Georgios D. Tsoukalas
{
678 7ce25cf6 Stratos Psomadakis
        struct xseg_type *type;
679 7ce25cf6 Stratos Psomadakis
680 7ce25cf6 Stratos Psomadakis
        __lock_domain();
681 7ce25cf6 Stratos Psomadakis
        type = __find_or_load_type(xseg->config.type);
682 6d486cc0 Georgios D. Tsoukalas
        if (!type) {
683 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("no segment type '%s'\n", xseg->config.type);
684 7ce25cf6 Stratos Psomadakis
                goto out;
685 6d486cc0 Georgios D. Tsoukalas
        }
686 6d486cc0 Georgios D. Tsoukalas
687 6d486cc0 Georgios D. Tsoukalas
        /* should destroy() leave() first? */
688 6d486cc0 Georgios D. Tsoukalas
        type->ops.deallocate(xseg->config.name);
689 7ce25cf6 Stratos Psomadakis
out:
690 7ce25cf6 Stratos Psomadakis
        __unlock_domain();
691 6d486cc0 Georgios D. Tsoukalas
}
692 6d486cc0 Georgios D. Tsoukalas
693 0bf9fcf7 Filippos Giannakos
//FIXME
694 6d486cc0 Georgios D. Tsoukalas
static int pointer_ok(        unsigned long ptr,
695 6d486cc0 Georgios D. Tsoukalas
                        unsigned long base,
696 6d486cc0 Georgios D. Tsoukalas
                        uint64_t size,
697 6d486cc0 Georgios D. Tsoukalas
                        char *name)
698 6d486cc0 Georgios D. Tsoukalas
{
699 6d486cc0 Georgios D. Tsoukalas
        int ret = !(ptr >= base && ptr < base + size);
700 6d486cc0 Georgios D. Tsoukalas
        if (ret)
701 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("invalid pointer '->%s' [%llx on %llx]!\n",
702 6d486cc0 Georgios D. Tsoukalas
                        (unsigned long long)ptr,
703 6d486cc0 Georgios D. Tsoukalas
                        (unsigned long long)base,
704 6d486cc0 Georgios D. Tsoukalas
                        name);
705 6d486cc0 Georgios D. Tsoukalas
        return ret;
706 6d486cc0 Georgios D. Tsoukalas
}
707 6d486cc0 Georgios D. Tsoukalas
708 6d486cc0 Georgios D. Tsoukalas
#define POINTER_OK(xseg, field, base) \
709 6d486cc0 Georgios D. Tsoukalas
         pointer_ok(        (unsigned long)((xseg)->field), \
710 6d486cc0 Georgios D. Tsoukalas
                        (unsigned long)(base), \
711 6d486cc0 Georgios D. Tsoukalas
                        (xseg)->segment_size, \
712 6d486cc0 Georgios D. Tsoukalas
                        #field)
713 6d486cc0 Georgios D. Tsoukalas
714 6d486cc0 Georgios D. Tsoukalas
static int xseg_validate_pointers(struct xseg *xseg)
715 6d486cc0 Georgios D. Tsoukalas
{
716 6d486cc0 Georgios D. Tsoukalas
        int r = 0;
717 0a5d10a9 Filippos Giannakos
        r += POINTER_OK(xseg, object_handlers, xseg->segment);
718 0a5d10a9 Filippos Giannakos
        r += POINTER_OK(xseg, request_h, xseg->segment);
719 0a5d10a9 Filippos Giannakos
        r += POINTER_OK(xseg, port_h, xseg->segment);
720 6d486cc0 Georgios D. Tsoukalas
        r += POINTER_OK(xseg, ports, xseg->segment);
721 0a5d10a9 Filippos Giannakos
        r += POINTER_OK(xseg, heap, xseg->segment);
722 6d486cc0 Georgios D. Tsoukalas
        r += POINTER_OK(xseg, shared, xseg->segment);
723 6d486cc0 Georgios D. Tsoukalas
        return r;
724 6d486cc0 Georgios D. Tsoukalas
}
725 6d486cc0 Georgios D. Tsoukalas
726 6e0a3771 Georgios D. Tsoukalas
struct xseg *xseg_join(        char *segtypename,
727 6e0a3771 Georgios D. Tsoukalas
                        char *segname,
728 6e0a3771 Georgios D. Tsoukalas
                        char *peertypename,
729 6e0a3771 Georgios D. Tsoukalas
                        void (*wakeup)
730 ed7d5d7c Giannakos Filippos
                        (        uint32_t portno                ))
731 6d486cc0 Georgios D. Tsoukalas
{
732 6d486cc0 Georgios D. Tsoukalas
        struct xseg *xseg, *__xseg;
733 6d486cc0 Georgios D. Tsoukalas
        uint64_t size;
734 6e0a3771 Georgios D. Tsoukalas
        struct xseg_peer *peertype;
735 6e0a3771 Georgios D. Tsoukalas
        struct xseg_type *segtype;
736 6e0a3771 Georgios D. Tsoukalas
        struct xseg_private *priv;
737 6d486cc0 Georgios D. Tsoukalas
        struct xseg_operations *xops;
738 6e0a3771 Georgios D. Tsoukalas
        struct xseg_peer_operations *pops;
739 6d486cc0 Georgios D. Tsoukalas
        int r;
740 6d486cc0 Georgios D. Tsoukalas
741 6e0a3771 Georgios D. Tsoukalas
        __lock_domain();
742 6e0a3771 Georgios D. Tsoukalas
743 6e0a3771 Georgios D. Tsoukalas
        peertype = __find_or_load_peer_type(peertypename);
744 6e0a3771 Georgios D. Tsoukalas
        if (!peertype) {
745 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Peer type '%s' not found\n", peertypename);
746 6e0a3771 Georgios D. Tsoukalas
                __unlock_domain();
747 6d486cc0 Georgios D. Tsoukalas
                goto err;
748 6d486cc0 Georgios D. Tsoukalas
        }
749 6d486cc0 Georgios D. Tsoukalas
750 6e0a3771 Georgios D. Tsoukalas
        segtype = __find_or_load_type(segtypename);
751 6e0a3771 Georgios D. Tsoukalas
        if (!segtype) {
752 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Segment type '%s' not found\n", segtypename);
753 6e0a3771 Georgios D. Tsoukalas
                __unlock_domain();
754 6e0a3771 Georgios D. Tsoukalas
                goto err;
755 6e0a3771 Georgios D. Tsoukalas
        }
756 6e0a3771 Georgios D. Tsoukalas
757 6e0a3771 Georgios D. Tsoukalas
        __unlock_domain();
758 6e0a3771 Georgios D. Tsoukalas
759 6e0a3771 Georgios D. Tsoukalas
        xops = &segtype->ops;
760 6e0a3771 Georgios D. Tsoukalas
        pops = &peertype->peer_ops;
761 6d486cc0 Georgios D. Tsoukalas
762 6e0a3771 Georgios D. Tsoukalas
        xseg = pops->malloc(sizeof(struct xseg));
763 6d486cc0 Georgios D. Tsoukalas
        if (!xseg) {
764 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Cannot allocate memory");
765 6d486cc0 Georgios D. Tsoukalas
                goto err;
766 6d486cc0 Georgios D. Tsoukalas
        }
767 6d486cc0 Georgios D. Tsoukalas
768 6e0a3771 Georgios D. Tsoukalas
        priv = pops->malloc(sizeof(struct xseg_private));
769 6e0a3771 Georgios D. Tsoukalas
        if (!priv) {
770 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Cannot allocate memory");
771 6d486cc0 Georgios D. Tsoukalas
                goto err_seg;
772 6e0a3771 Georgios D. Tsoukalas
        }
773 6e0a3771 Georgios D. Tsoukalas
774 7ce25cf6 Stratos Psomadakis
        __xseg = xops->map(segname, XSEG_MIN_PAGE_SIZE, NULL);
775 6e0a3771 Georgios D. Tsoukalas
        if (!__xseg) {
776 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Cannot map segment");
777 6e0a3771 Georgios D. Tsoukalas
                goto err_priv;
778 6e0a3771 Georgios D. Tsoukalas
        }
779 6d486cc0 Georgios D. Tsoukalas
780 8ed1ddbb Filippos Giannakos
        if (!(__xseg->version == XSEG_VERSION)) {
781 8ed1ddbb Filippos Giannakos
                XSEGLOG("Version mismatch. Expected %llu, segment version %llu",
782 8ed1ddbb Filippos Giannakos
                                XSEG_VERSION, __xseg->version);
783 8ed1ddbb Filippos Giannakos
                goto err_priv;
784 8ed1ddbb Filippos Giannakos
        }
785 8ed1ddbb Filippos Giannakos
786 6d486cc0 Georgios D. Tsoukalas
        size = __xseg->segment_size;
787 6e0a3771 Georgios D. Tsoukalas
        /* XSEGLOG("joined segment of size: %lu\n", (unsigned long)size); */
788 6d486cc0 Georgios D. Tsoukalas
        xops->unmap(__xseg, XSEG_MIN_PAGE_SIZE);
789 6d486cc0 Georgios D. Tsoukalas
790 7ce25cf6 Stratos Psomadakis
        __xseg = xops->map(segname, size, xseg);
791 6e0a3771 Georgios D. Tsoukalas
        if (!__xseg) {
792 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Cannot map segment");
793 6e0a3771 Georgios D. Tsoukalas
                goto err_priv;
794 6e0a3771 Georgios D. Tsoukalas
        }
795 6e0a3771 Georgios D. Tsoukalas
796 6e0a3771 Georgios D. Tsoukalas
        priv->segment_type = *segtype;
797 6e0a3771 Georgios D. Tsoukalas
        priv->peer_type = *peertype;
798 6e0a3771 Georgios D. Tsoukalas
        priv->wakeup = wakeup;
799 51eafc68 Filippos Giannakos
        priv->req_data = xhash_new(3, 0, XHASH_INTEGER); //FIXME should be relative to XSEG_DEF_REQS
800 61473749 Filippos Giannakos
        if (!priv->req_data)
801 61473749 Filippos Giannakos
                goto err_priv;
802 a5c1eefb User
        xlock_release(&priv->reqdatalock);
803 61473749 Filippos Giannakos
804 7ce25cf6 Stratos Psomadakis
        xseg->max_peer_types = __xseg->max_peer_types;
805 6e0a3771 Georgios D. Tsoukalas
806 6e0a3771 Georgios D. Tsoukalas
        priv->peer_types = pops->malloc(sizeof(void *) * xseg->max_peer_types);
807 6e0a3771 Georgios D. Tsoukalas
        if (!priv->peer_types) {
808 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Cannot allocate memory");
809 6e0a3771 Georgios D. Tsoukalas
                goto err_unmap;
810 6e0a3771 Georgios D. Tsoukalas
        }
811 6e0a3771 Georgios D. Tsoukalas
        memset(priv->peer_types, 0, sizeof(void *) * xseg->max_peer_types);
812 17590774 Giannakos Filippos
        priv->peer_type_data = pops->malloc(sizeof(void *) * xseg->max_peer_types);
813 17590774 Giannakos Filippos
        if (!priv->peer_types) {
814 17590774 Giannakos Filippos
                XSEGLOG("Cannot allocate memory");
815 17590774 Giannakos Filippos
                //FIXME wrong err handling
816 17590774 Giannakos Filippos
                goto err_unmap;
817 17590774 Giannakos Filippos
        }
818 b911a183 Giannakos Filippos
        memset(priv->peer_type_data, 0, sizeof(void *) * xseg->max_peer_types);
819 6d486cc0 Georgios D. Tsoukalas
820 7ce25cf6 Stratos Psomadakis
        xseg->priv = priv;
821 6e0a3771 Georgios D. Tsoukalas
        xseg->config = __xseg->config;
822 6d486cc0 Georgios D. Tsoukalas
        xseg->version = __xseg->version;
823 0a5d10a9 Filippos Giannakos
        xseg->request_h = XPTR_TAKE(__xseg->request_h, __xseg);
824 4494b184 Filippos Giannakos
        xseg->port_h = XPTR_TAKE(__xseg->port_h, __xseg);
825 0bf9fcf7 Filippos Giannakos
        xseg->ports = XPTR_TAKE(__xseg->ports, __xseg);
826 e3052736 Filippos Giannakos
        xseg->path_next = XPTR_TAKE(__xseg->path_next, __xseg);
827 9a418f2f Filippos Giannakos
        xseg->dst_gw = XPTR_TAKE(__xseg->dst_gw, __xseg);
828 4494b184 Filippos Giannakos
        xseg->heap = XPTR_TAKE(__xseg->heap, __xseg);
829 4494b184 Filippos Giannakos
        xseg->object_handlers = XPTR_TAKE(__xseg->object_handlers, __xseg);
830 0bf9fcf7 Filippos Giannakos
        xseg->shared = XPTR_TAKE(__xseg->shared, __xseg);
831 6d486cc0 Georgios D. Tsoukalas
        xseg->segment_size = size;
832 6d486cc0 Georgios D. Tsoukalas
        xseg->segment = __xseg;
833 89cb9d38 Giannakos Filippos
        __sync_synchronize();
834 6d486cc0 Georgios D. Tsoukalas
835 6e0a3771 Georgios D. Tsoukalas
        r = xseg_validate_pointers(xseg);
836 6d486cc0 Georgios D. Tsoukalas
        if (r) {
837 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("found %d invalid xseg pointers!\n", r);
838 6e0a3771 Georgios D. Tsoukalas
                goto err_free_types;
839 6d486cc0 Georgios D. Tsoukalas
        }
840 6e0a3771 Georgios D. Tsoukalas
841 6e0a3771 Georgios D. Tsoukalas
        /* Do we need this?
842 6e0a3771 Georgios D. Tsoukalas
        r = xops->signal_join(xseg);
843 6e0a3771 Georgios D. Tsoukalas
        if (r) {
844 6e0a3771 Georgios D. Tsoukalas
                XSEGLOG("Cannot attach signaling to segment! (error: %d)\n", r);
845 6e0a3771 Georgios D. Tsoukalas
                goto err_free_types;
846 6e0a3771 Georgios D. Tsoukalas
        }
847 6e0a3771 Georgios D. Tsoukalas
        */
848 6e0a3771 Georgios D. Tsoukalas
849 6d486cc0 Georgios D. Tsoukalas
        return xseg;
850 6d486cc0 Georgios D. Tsoukalas
851 6e0a3771 Georgios D. Tsoukalas
err_free_types:
852 6e0a3771 Georgios D. Tsoukalas
        pops->mfree(priv->peer_types);
853 6d486cc0 Georgios D. Tsoukalas
err_unmap:
854 6d486cc0 Georgios D. Tsoukalas
        xops->unmap(__xseg, size);
855 61473749 Filippos Giannakos
        xhash_free(priv->req_data);
856 6e0a3771 Georgios D. Tsoukalas
err_priv:
857 6e0a3771 Georgios D. Tsoukalas
        pops->mfree(priv);
858 6d486cc0 Georgios D. Tsoukalas
err_seg:
859 6e0a3771 Georgios D. Tsoukalas
        pops->mfree(xseg);
860 6d486cc0 Georgios D. Tsoukalas
err:
861 6d486cc0 Georgios D. Tsoukalas
        return NULL;
862 6d486cc0 Georgios D. Tsoukalas
}
863 6d486cc0 Georgios D. Tsoukalas
864 7ce25cf6 Stratos Psomadakis
void xseg_leave(struct xseg *xseg)
865 7ce25cf6 Stratos Psomadakis
{
866 7ce25cf6 Stratos Psomadakis
        struct xseg_type *type;
867 7ce25cf6 Stratos Psomadakis
868 7ce25cf6 Stratos Psomadakis
        __lock_domain();
869 7ce25cf6 Stratos Psomadakis
        type = __find_or_load_type(xseg->config.type);
870 7ce25cf6 Stratos Psomadakis
        if (!type) {
871 7ce25cf6 Stratos Psomadakis
                XSEGLOG("no segment type '%s'\n", xseg->config.type);
872 7ce25cf6 Stratos Psomadakis
                __unlock_domain();
873 7ce25cf6 Stratos Psomadakis
                return;
874 7ce25cf6 Stratos Psomadakis
        }
875 7ce25cf6 Stratos Psomadakis
        __unlock_domain();
876 7ce25cf6 Stratos Psomadakis
877 7ce25cf6 Stratos Psomadakis
        type->ops.unmap(xseg->segment, xseg->segment_size);
878 b911a183 Giannakos Filippos
        //FIXME free xseg?
879 7ce25cf6 Stratos Psomadakis
}
880 6d486cc0 Georgios D. Tsoukalas
881 be1186ce Filippos Giannakos
struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno)
882 be1186ce Filippos Giannakos
{
883 79681fdc Filippos Giannakos
        xptr p;
884 be1186ce Filippos Giannakos
        if (!__validate_port(xseg, portno))
885 be1186ce Filippos Giannakos
                return NULL;
886 79681fdc Filippos Giannakos
        p = xseg->ports[portno];
887 18f02d02 Filippos Giannakos
        if (p)
888 18f02d02 Filippos Giannakos
                return XPTR_TAKE(p, xseg->segment);
889 18f02d02 Filippos Giannakos
        else 
890 18f02d02 Filippos Giannakos
                return NULL;
891 be1186ce Filippos Giannakos
}
892 be1186ce Filippos Giannakos
893 441202a7 Filippos Giannakos
struct xq * __alloc_queue(struct xseg *xseg, uint64_t nr_reqs)
894 441202a7 Filippos Giannakos
{
895 441202a7 Filippos Giannakos
        uint64_t bytes;
896 441202a7 Filippos Giannakos
        void *mem, *buf;
897 441202a7 Filippos Giannakos
        struct xq *q;
898 441202a7 Filippos Giannakos
        struct xheap *heap = xseg->heap;
899 441202a7 Filippos Giannakos
900 441202a7 Filippos Giannakos
        //how many bytes to allocate for a queue
901 441202a7 Filippos Giannakos
        bytes = sizeof(struct xq) + nr_reqs*sizeof(xqindex);
902 441202a7 Filippos Giannakos
        mem = xheap_allocate(heap, bytes);
903 441202a7 Filippos Giannakos
        if (!mem)
904 441202a7 Filippos Giannakos
                return NULL;
905 441202a7 Filippos Giannakos
906 441202a7 Filippos Giannakos
        //how many bytes did we got, and calculate what's left of buffer
907 441202a7 Filippos Giannakos
        bytes = xheap_get_chunk_size(mem) - sizeof(struct xq);
908 441202a7 Filippos Giannakos
909 441202a7 Filippos Giannakos
        //initialize queue with max nr of elements it can hold
910 441202a7 Filippos Giannakos
        q = (struct xq *) mem;
911 441202a7 Filippos Giannakos
        buf = (void *) (((unsigned long) mem) + sizeof(struct xq));
912 441202a7 Filippos Giannakos
        xq_init_empty(q, bytes/sizeof(xqindex), buf); 
913 441202a7 Filippos Giannakos
914 441202a7 Filippos Giannakos
        return q;
915 441202a7 Filippos Giannakos
}
916 441202a7 Filippos Giannakos
917 e06fe035 Filippos Giannakos
//FIXME
918 e06fe035 Filippos Giannakos
//maybe add parameters of initial free_queue size and max_alloc_reqs
919 be1186ce Filippos Giannakos
struct xseg_port *xseg_alloc_port(struct xseg *xseg, uint32_t flags, uint64_t nr_reqs)
920 be1186ce Filippos Giannakos
{
921 441202a7 Filippos Giannakos
        struct xq *q;
922 18f02d02 Filippos Giannakos
        struct xobject_h *obj_h = xseg->port_h;
923 be1186ce Filippos Giannakos
        struct xseg_port *port = xobj_get_obj(obj_h, flags);
924 be1186ce Filippos Giannakos
        if (!port)
925 be1186ce Filippos Giannakos
                return NULL;
926 e06fe035 Filippos Giannakos
927 441202a7 Filippos Giannakos
        //alloc free queue
928 441202a7 Filippos Giannakos
        q = __alloc_queue(xseg, nr_reqs);
929 441202a7 Filippos Giannakos
        if (!q)
930 be1186ce Filippos Giannakos
                goto err_free;
931 441202a7 Filippos Giannakos
        port->free_queue = XPTR_MAKE(q, xseg->segment);
932 be1186ce Filippos Giannakos
933 be1186ce Filippos Giannakos
        //and for request queue
934 441202a7 Filippos Giannakos
        q = __alloc_queue(xseg, nr_reqs);
935 441202a7 Filippos Giannakos
        if (!q)
936 be1186ce Filippos Giannakos
                goto err_req;
937 441202a7 Filippos Giannakos
        port->request_queue = XPTR_MAKE(q, xseg->segment);
938 be1186ce Filippos Giannakos
939 441202a7 Filippos Giannakos
        //and for reply queue
940 441202a7 Filippos Giannakos
        q = __alloc_queue(xseg, nr_reqs);
941 441202a7 Filippos Giannakos
        if (!q)
942 be1186ce Filippos Giannakos
                goto err_reply;
943 441202a7 Filippos Giannakos
        port->reply_queue = XPTR_MAKE(q, xseg->segment);
944 be1186ce Filippos Giannakos
945 6e36d028 Filippos Giannakos
        xlock_release(&port->fq_lock);
946 6e36d028 Filippos Giannakos
        xlock_release(&port->rq_lock);
947 6e36d028 Filippos Giannakos
        xlock_release(&port->pq_lock);
948 94f1113a Filippos Giannakos
        xlock_release(&port->port_lock);
949 e06fe035 Filippos Giannakos
        port->owner = Noone;
950 e06fe035 Filippos Giannakos
        port->portno = NoPort;
951 e06fe035 Filippos Giannakos
        port->peer_type = 0; //FIXME what  here ??? NoType??
952 94f1113a Filippos Giannakos
        port->alloc_reqs = 0;
953 e06fe035 Filippos Giannakos
        port->max_alloc_reqs = XSEG_DEF_MAX_ALLOCATED_REQS;
954 e3052736 Filippos Giannakos
        port->flags = 0;
955 0f944d14 Filippos Giannakos
        port->signal_desc = 0;
956 8eea2b4b Filippos Giannakos
957 8eea2b4b Filippos Giannakos
958 be1186ce Filippos Giannakos
        return port;
959 be1186ce Filippos Giannakos
960 be1186ce Filippos Giannakos
err_reply:
961 0a5d10a9 Filippos Giannakos
        xheap_free(XPTR_TAKE(port->request_queue, xseg->segment));
962 be1186ce Filippos Giannakos
        port->request_queue = 0;
963 be1186ce Filippos Giannakos
err_req:
964 0a5d10a9 Filippos Giannakos
        xheap_free(XPTR_TAKE(port->free_queue, xseg->segment));
965 be1186ce Filippos Giannakos
        port->free_queue = 0;
966 be1186ce Filippos Giannakos
err_free:
967 be1186ce Filippos Giannakos
        xobj_put_obj(obj_h, port);
968 be1186ce Filippos Giannakos
969 be1186ce Filippos Giannakos
        return NULL;
970 be1186ce Filippos Giannakos
}
971 be1186ce Filippos Giannakos
972 be1186ce Filippos Giannakos
void xseg_free_port(struct xseg *xseg, struct xseg_port *port)
973 0a5d10a9 Filippos Giannakos
{
974 18f02d02 Filippos Giannakos
        struct xobject_h *obj_h = xseg->port_h;
975 be1186ce Filippos Giannakos
976 be1186ce Filippos Giannakos
        if (port->request_queue) {
977 0a5d10a9 Filippos Giannakos
                xheap_free(XPTR_TAKE(port->request_queue, xseg->segment));
978 be1186ce Filippos Giannakos
                port->request_queue = 0;
979 be1186ce Filippos Giannakos
        }
980 be1186ce Filippos Giannakos
        if (port->free_queue) {
981 0a5d10a9 Filippos Giannakos
                xheap_free(XPTR_TAKE(port->free_queue, xseg->segment));
982 be1186ce Filippos Giannakos
                port->free_queue = 0;
983 be1186ce Filippos Giannakos
        }
984 be1186ce Filippos Giannakos
        if (port->reply_queue) {
985 0a5d10a9 Filippos Giannakos
                xheap_free(XPTR_TAKE(port->reply_queue, xseg->segment));
986 be1186ce Filippos Giannakos
                port->reply_queue = 0;
987 be1186ce Filippos Giannakos
        }
988 be1186ce Filippos Giannakos
        xobj_put_obj(obj_h, port);
989 be1186ce Filippos Giannakos
}
990 be1186ce Filippos Giannakos
991 be1186ce Filippos Giannakos
void* xseg_alloc_buffer(struct xseg *xseg, uint64_t size)
992 be1186ce Filippos Giannakos
{
993 be1186ce Filippos Giannakos
        struct xheap *heap = xseg->heap;
994 6e36d028 Filippos Giannakos
        void *mem = xheap_allocate(heap, size);
995 94f1113a Filippos Giannakos
        if (mem && xheap_get_chunk_size(mem) < size) {
996 6e36d028 Filippos Giannakos
                XSEGLOG("Buffer size %llu instead of %llu\n", 
997 6e36d028 Filippos Giannakos
                                xheap_get_chunk_size(mem), size);
998 6e36d028 Filippos Giannakos
                xheap_free(mem);
999 6e36d028 Filippos Giannakos
                mem = NULL;
1000 6e36d028 Filippos Giannakos
        }
1001 6e36d028 Filippos Giannakos
        return mem;
1002 be1186ce Filippos Giannakos
}
1003 be1186ce Filippos Giannakos
1004 be1186ce Filippos Giannakos
void xseg_free_buffer(struct xseg *xseg, void *ptr)
1005 be1186ce Filippos Giannakos
{
1006 be1186ce Filippos Giannakos
        xheap_free(ptr);
1007 be1186ce Filippos Giannakos
}
1008 be1186ce Filippos Giannakos
1009 6d486cc0 Georgios D. Tsoukalas
int xseg_prepare_wait(struct xseg *xseg, uint32_t portno)
1010 6d486cc0 Georgios D. Tsoukalas
{
1011 6d486cc0 Georgios D. Tsoukalas
        if (!__validate_port(xseg, portno))
1012 6d486cc0 Georgios D. Tsoukalas
                return -1;
1013 6d486cc0 Georgios D. Tsoukalas
1014 6e0a3771 Georgios D. Tsoukalas
        return xseg->priv->peer_type.peer_ops.prepare_wait(xseg, portno);
1015 6d486cc0 Georgios D. Tsoukalas
}
1016 6d486cc0 Georgios D. Tsoukalas
1017 6d486cc0 Georgios D. Tsoukalas
int xseg_cancel_wait(struct xseg *xseg, uint32_t portno)
1018 6d486cc0 Georgios D. Tsoukalas
{
1019 6d486cc0 Georgios D. Tsoukalas
        if (!__validate_port(xseg, portno))
1020 6d486cc0 Georgios D. Tsoukalas
                return -1;
1021 6e0a3771 Georgios D. Tsoukalas
        return xseg->priv->peer_type.peer_ops.cancel_wait(xseg, portno);
1022 6d486cc0 Georgios D. Tsoukalas
}
1023 6d486cc0 Georgios D. Tsoukalas
1024 8cbf5379 Filippos Giannakos
int xseg_wait_signal(struct xseg *xseg, void *sd, uint32_t usec_timeout)
1025 6d486cc0 Georgios D. Tsoukalas
{
1026 8cbf5379 Filippos Giannakos
        return xseg->priv->peer_type.peer_ops.wait_signal(xseg, sd, usec_timeout);
1027 6d486cc0 Georgios D. Tsoukalas
}
1028 6d486cc0 Georgios D. Tsoukalas
1029 3f925312 Filippos Giannakos
int xseg_signal(struct xseg *xseg, xport portno)
1030 6d486cc0 Georgios D. Tsoukalas
{
1031 6d486cc0 Georgios D. Tsoukalas
        struct xseg_peer *type;
1032 be1186ce Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1033 be1186ce Filippos Giannakos
        if (!port)
1034 6d486cc0 Georgios D. Tsoukalas
                return -1;
1035 be1186ce Filippos Giannakos
        
1036 6d486cc0 Georgios D. Tsoukalas
        type = __get_peer_type(xseg, port->peer_type);
1037 6d486cc0 Georgios D. Tsoukalas
        if (!type)
1038 6d486cc0 Georgios D. Tsoukalas
                return -1;
1039 6d486cc0 Georgios D. Tsoukalas
1040 6e0a3771 Georgios D. Tsoukalas
        return type->peer_ops.signal(xseg, portno);
1041 6d486cc0 Georgios D. Tsoukalas
}
1042 6d486cc0 Georgios D. Tsoukalas
1043 9fb0f83b Filippos Giannakos
int xseg_init_local_signal(struct xseg *xseg, xport portno)
1044 3f925312 Filippos Giannakos
{
1045 3f925312 Filippos Giannakos
        struct xseg_peer *type;
1046 3f925312 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1047 3f925312 Filippos Giannakos
        if (!port)
1048 3f925312 Filippos Giannakos
                return -1;
1049 3f925312 Filippos Giannakos
        
1050 3f925312 Filippos Giannakos
        type = __get_peer_type(xseg, port->peer_type);
1051 3f925312 Filippos Giannakos
        if (!type)
1052 3f925312 Filippos Giannakos
                return -1;
1053 3f925312 Filippos Giannakos
1054 89cb9d38 Giannakos Filippos
        return type->peer_ops.local_signal_init(xseg, portno);
1055 9fb0f83b Filippos Giannakos
}
1056 9fb0f83b Filippos Giannakos
1057 9fb0f83b Filippos Giannakos
void xseg_quit_local_signal(struct xseg *xseg, xport portno)
1058 9fb0f83b Filippos Giannakos
{
1059 9fb0f83b Filippos Giannakos
        struct xseg_peer *type;
1060 9fb0f83b Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1061 9fb0f83b Filippos Giannakos
        if (!port)
1062 9fb0f83b Filippos Giannakos
                return;
1063 9fb0f83b Filippos Giannakos
        
1064 9fb0f83b Filippos Giannakos
        type = __get_peer_type(xseg, port->peer_type);
1065 9fb0f83b Filippos Giannakos
        if (!type)
1066 9fb0f83b Filippos Giannakos
                return;
1067 9fb0f83b Filippos Giannakos
1068 89cb9d38 Giannakos Filippos
        type->peer_ops.local_signal_quit(xseg, portno);
1069 3f925312 Filippos Giannakos
}
1070 3f925312 Filippos Giannakos
1071 750496d5 Filippos Giannakos
//FIXME doesn't increase alloced reqs
1072 9d488b8d Filippos Giannakos
//is integer i enough here?
1073 6d486cc0 Georgios D. Tsoukalas
int xseg_alloc_requests(struct xseg *xseg, uint32_t portno, uint32_t nr)
1074 6d486cc0 Georgios D. Tsoukalas
{
1075 9d488b8d Filippos Giannakos
        int i = 0;
1076 be1186ce Filippos Giannakos
        xqindex xqi;
1077 be1186ce Filippos Giannakos
        struct xq *q;
1078 be1186ce Filippos Giannakos
        struct xseg_request *req;
1079 4494b184 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1080 4494b184 Filippos Giannakos
        if (!port)
1081 6d486cc0 Georgios D. Tsoukalas
                return -1;
1082 6d486cc0 Georgios D. Tsoukalas
1083 e06fe035 Filippos Giannakos
        xlock_acquire(&port->fq_lock, portno);
1084 be1186ce Filippos Giannakos
        q = XPTR_TAKE(port->free_queue, xseg->segment);
1085 22a9914f Filippos Giannakos
        while ((req = xobj_get_obj(xseg->request_h, X_ALLOC)) != NULL && i < nr) {
1086 be1186ce Filippos Giannakos
                xqi = XPTR_MAKE(req, xseg->segment);
1087 e06fe035 Filippos Giannakos
                xqi = __xq_append_tail(q, xqi);
1088 9fb0f83b Filippos Giannakos
                if (xqi == Noneidx) {
1089 9fb0f83b Filippos Giannakos
                        xobj_put_obj(xseg->request_h, req);
1090 be1186ce Filippos Giannakos
                        break;
1091 9fb0f83b Filippos Giannakos
                }
1092 be1186ce Filippos Giannakos
                i++;
1093 be1186ce Filippos Giannakos
        }
1094 e06fe035 Filippos Giannakos
        xlock_release(&port->fq_lock);
1095 4494b184 Filippos Giannakos
1096 be1186ce Filippos Giannakos
        if (i == 0)
1097 be1186ce Filippos Giannakos
                i = -1;
1098 be1186ce Filippos Giannakos
        return i;
1099 6d486cc0 Georgios D. Tsoukalas
}
1100 6d486cc0 Georgios D. Tsoukalas
1101 6d486cc0 Georgios D. Tsoukalas
int xseg_free_requests(struct xseg *xseg, uint32_t portno, int nr)
1102 6d486cc0 Georgios D. Tsoukalas
{
1103 9d488b8d Filippos Giannakos
        int i = 0;
1104 be1186ce Filippos Giannakos
        xqindex xqi;
1105 be1186ce Filippos Giannakos
        struct xq *q;
1106 be1186ce Filippos Giannakos
        struct xseg_request *req;
1107 be1186ce Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1108 be1186ce Filippos Giannakos
        if (!port)
1109 6d486cc0 Georgios D. Tsoukalas
                return -1;
1110 6d486cc0 Georgios D. Tsoukalas
1111 e06fe035 Filippos Giannakos
        xlock_acquire(&port->fq_lock, portno);
1112 be1186ce Filippos Giannakos
        q = XPTR_TAKE(port->free_queue, xseg->segment);
1113 e06fe035 Filippos Giannakos
        while ((xqi = __xq_pop_head(q)) != Noneidx && i < nr) {
1114 be1186ce Filippos Giannakos
                req = XPTR_TAKE(xqi, xseg->segment);
1115 22a9914f Filippos Giannakos
                xobj_put_obj(xseg->request_h, (void *) req);
1116 be1186ce Filippos Giannakos
                i++;
1117 be1186ce Filippos Giannakos
        }
1118 be1186ce Filippos Giannakos
        if (i == 0)
1119 750496d5 Filippos Giannakos
                return -1;
1120 e06fe035 Filippos Giannakos
        xlock_release(&port->fq_lock);
1121 e06fe035 Filippos Giannakos
1122 750496d5 Filippos Giannakos
        xlock_acquire(&port->port_lock, portno);
1123 750496d5 Filippos Giannakos
        port->alloc_reqs -= i;
1124 750496d5 Filippos Giannakos
        xlock_release(&port->port_lock);
1125 750496d5 Filippos Giannakos
1126 be1186ce Filippos Giannakos
        return i;
1127 6d486cc0 Georgios D. Tsoukalas
}
1128 6d486cc0 Georgios D. Tsoukalas
1129 e3052736 Filippos Giannakos
int xseg_prep_ports (struct xseg *xseg, struct xseg_request *xreq,
1130 9a418f2f Filippos Giannakos
                        uint32_t src_portno, uint32_t dst_portno)
1131 9a418f2f Filippos Giannakos
{
1132 9a418f2f Filippos Giannakos
        if (!__validate_port(xseg, src_portno))
1133 9a418f2f Filippos Giannakos
                return -1;
1134 9a418f2f Filippos Giannakos
1135 9a418f2f Filippos Giannakos
        if (!__validate_port(xseg, dst_portno))
1136 9a418f2f Filippos Giannakos
                return -1;
1137 9a418f2f Filippos Giannakos
1138 9a418f2f Filippos Giannakos
        xreq->src_portno = src_portno;
1139 e3052736 Filippos Giannakos
        xreq->transit_portno = src_portno;
1140 9a418f2f Filippos Giannakos
        xreq->dst_portno = dst_portno;
1141 e3052736 Filippos Giannakos
        xreq->effective_dst_portno = dst_portno;
1142 9a418f2f Filippos Giannakos
1143 9a418f2f Filippos Giannakos
        return 0;
1144 9a418f2f Filippos Giannakos
}
1145 9a418f2f Filippos Giannakos
1146 e3052736 Filippos Giannakos
struct xseg_request *xseg_get_request(struct xseg *xseg, xport src_portno,
1147 7882a035 Filippos Giannakos
                                        xport dst_portno, uint32_t flags)
1148 6d486cc0 Georgios D. Tsoukalas
{
1149 7882a035 Filippos Giannakos
        /*
1150 7882a035 Filippos Giannakos
         * Flags:
1151 e3052736 Filippos Giannakos
         * X_ALLOC Allocate more requests if object handler
1152 7882a035 Filippos Giannakos
         *            does not have any avaiable
1153 7882a035 Filippos Giannakos
         * X_LOCAL Use only local - preallocated reqs
1154 7882a035 Filippos Giannakos
         *         (Maybe we want this as default, to give a hint to a peer
1155 7882a035 Filippos Giannakos
         *             how many requests it can have flying)
1156 7882a035 Filippos Giannakos
         */
1157 94f1113a Filippos Giannakos
        struct xseg_request *req = NULL;
1158 6d486cc0 Georgios D. Tsoukalas
        struct xseg_port *port;
1159 4494b184 Filippos Giannakos
        struct xq *q;
1160 6d486cc0 Georgios D. Tsoukalas
        xqindex xqi;
1161 4494b184 Filippos Giannakos
        xptr ptr;
1162 6d486cc0 Georgios D. Tsoukalas
1163 61473749 Filippos Giannakos
        port = xseg_get_port(xseg, src_portno);
1164 4494b184 Filippos Giannakos
        if (!port)
1165 6d486cc0 Georgios D. Tsoukalas
                return NULL;
1166 4494b184 Filippos Giannakos
        //try to allocate from free_queue
1167 e06fe035 Filippos Giannakos
        xlock_acquire(&port->fq_lock, src_portno);
1168 4494b184 Filippos Giannakos
        q = XPTR_TAKE(port->free_queue, xseg->segment);
1169 e06fe035 Filippos Giannakos
        xqi = __xq_pop_head(q);
1170 4494b184 Filippos Giannakos
        if (xqi != Noneidx){
1171 e06fe035 Filippos Giannakos
                xlock_release(&port->fq_lock);
1172 4494b184 Filippos Giannakos
                ptr = xqi;
1173 4494b184 Filippos Giannakos
                req = XPTR_TAKE(ptr, xseg->segment);
1174 4494b184 Filippos Giannakos
                goto done;
1175 4494b184 Filippos Giannakos
        }
1176 e06fe035 Filippos Giannakos
        xlock_release(&port->fq_lock);
1177 6d486cc0 Georgios D. Tsoukalas
1178 7882a035 Filippos Giannakos
        if (flags & X_LOCAL)
1179 7882a035 Filippos Giannakos
                return NULL;
1180 7882a035 Filippos Giannakos
1181 4494b184 Filippos Giannakos
        //else try to allocate from global heap
1182 7882a035 Filippos Giannakos
        //FIXME
1183 61473749 Filippos Giannakos
        xlock_acquire(&port->port_lock, src_portno);
1184 94f1113a Filippos Giannakos
        if (port->alloc_reqs < port->max_alloc_reqs) {
1185 7882a035 Filippos Giannakos
                req = xobj_get_obj(xseg->request_h, flags & X_ALLOC);
1186 94f1113a Filippos Giannakos
                if (req)
1187 94f1113a Filippos Giannakos
                        port->alloc_reqs++;
1188 94f1113a Filippos Giannakos
        }
1189 94f1113a Filippos Giannakos
        xlock_release(&port->port_lock);
1190 4494b184 Filippos Giannakos
        if (!req)
1191 4494b184 Filippos Giannakos
                return NULL;
1192 94f1113a Filippos Giannakos
1193 4494b184 Filippos Giannakos
done:
1194 1b52f571 Stratos Psomadakis
1195 fe34fb45 User
        req->buffer = 0;
1196 fe34fb45 User
        req->bufferlen = 0;
1197 79681fdc Filippos Giannakos
        req->target = 0;
1198 79681fdc Filippos Giannakos
        req->data = 0;
1199 79681fdc Filippos Giannakos
        req->datalen = 0;
1200 79681fdc Filippos Giannakos
        req->targetlen = 0;
1201 9a418f2f Filippos Giannakos
        if (xseg_prep_ports(xseg, req, src_portno, dst_portno) < 0) {
1202 7882a035 Filippos Giannakos
                xseg_put_request(xseg, req, src_portno);
1203 9a418f2f Filippos Giannakos
                return NULL;
1204 9a418f2f Filippos Giannakos
        }
1205 9a418f2f Filippos Giannakos
        req->state = 0;
1206 1b52f571 Stratos Psomadakis
        req->elapsed = 0;
1207 1b52f571 Stratos Psomadakis
        req->timestamp.tv_sec = 0;
1208 3b07b042 Stratos Psomadakis
        req->timestamp.tv_usec = 0;
1209 87935597 Giannakos Filippos
        req->flags = 0;
1210 d3f3b03b Filippos Giannakos
        req->serviced = 0;
1211 1b52f571 Stratos Psomadakis
1212 61473749 Filippos Giannakos
        xq_init_empty(&req->path, MAX_PATH_LEN, req->path_bufs); 
1213 61473749 Filippos Giannakos
1214 6d486cc0 Georgios D. Tsoukalas
        return req;
1215 6d486cc0 Georgios D. Tsoukalas
}
1216 6d486cc0 Georgios D. Tsoukalas
1217 037769e7 Filippos Giannakos
//add flags
1218 037769e7 Filippos Giannakos
//do not put request if path not empty or X_FORCE set
1219 7882a035 Filippos Giannakos
int xseg_put_request (struct xseg *xseg, struct xseg_request *xreq,
1220 7882a035 Filippos Giannakos
                        xport portno)
1221 6d486cc0 Georgios D. Tsoukalas
{
1222 4494b184 Filippos Giannakos
        xqindex xqi = XPTR_MAKE(xreq, xseg->segment);
1223 4494b184 Filippos Giannakos
        struct xq *q;
1224 7882a035 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, xreq->src_portno);
1225 4494b184 Filippos Giannakos
        if (!port) 
1226 4494b184 Filippos Giannakos
                return -1;
1227 1b52f571 Stratos Psomadakis
1228 4494b184 Filippos Giannakos
        if (xreq->buffer){
1229 4494b184 Filippos Giannakos
                void *ptr = XPTR_TAKE(xreq->buffer, xseg->segment);
1230 4494b184 Filippos Giannakos
                xseg_free_buffer(xseg, ptr);
1231 4494b184 Filippos Giannakos
        }
1232 9a418f2f Filippos Giannakos
        /* empty path */
1233 61473749 Filippos Giannakos
        xq_init_empty(&xreq->path, MAX_PATH_LEN, xreq->path_bufs); 
1234 61473749 Filippos Giannakos
        
1235 fe34fb45 User
        xreq->buffer = 0;
1236 fe34fb45 User
        xreq->bufferlen = 0;
1237 4494b184 Filippos Giannakos
        xreq->target = 0;
1238 4494b184 Filippos Giannakos
        xreq->data = 0;
1239 4494b184 Filippos Giannakos
        xreq->datalen = 0;
1240 4494b184 Filippos Giannakos
        xreq->targetlen = 0;
1241 9a418f2f Filippos Giannakos
        xreq->state = 0;
1242 9a418f2f Filippos Giannakos
        xreq->src_portno = NoPort;
1243 9a418f2f Filippos Giannakos
        xreq->dst_portno = NoPort;
1244 e3052736 Filippos Giannakos
        xreq->transit_portno = NoPort;
1245 e3052736 Filippos Giannakos
        xreq->effective_dst_portno = NoPort;        
1246 d3f3b03b Filippos Giannakos
        xreq->serviced = 0;
1247 d3f3b03b Filippos Giannakos
1248 1b52f571 Stratos Psomadakis
        if (xreq->elapsed != 0) {
1249 1b52f571 Stratos Psomadakis
                __lock_segment(xseg);
1250 1b52f571 Stratos Psomadakis
                ++(xseg->counters.req_cnt);
1251 1b52f571 Stratos Psomadakis
                xseg->counters.avg_req_lat += xreq->elapsed;
1252 1b52f571 Stratos Psomadakis
                __unlock_segment(xseg);
1253 1b52f571 Stratos Psomadakis
        }
1254 1b52f571 Stratos Psomadakis
1255 94f1113a Filippos Giannakos
1256 4494b184 Filippos Giannakos
        //try to put it in free_queue of the port
1257 e06fe035 Filippos Giannakos
        xlock_acquire(&port->fq_lock, portno);
1258 94f1113a Filippos Giannakos
        q = XPTR_TAKE(port->free_queue, xseg->segment);
1259 e06fe035 Filippos Giannakos
        xqi = __xq_append_head(q, xqi);
1260 e06fe035 Filippos Giannakos
        xlock_release(&port->fq_lock);
1261 4494b184 Filippos Giannakos
        if (xqi != Noneidx)
1262 4494b184 Filippos Giannakos
                return 0;
1263 4494b184 Filippos Giannakos
        //else return it to segment
1264 22a9914f Filippos Giannakos
        xobj_put_obj(xseg->request_h, (void *) xreq);
1265 06773369 Filippos Giannakos
        xlock_acquire(&port->port_lock, portno);
1266 06773369 Filippos Giannakos
        port->alloc_reqs--;
1267 06773369 Filippos Giannakos
        xlock_release(&port->port_lock);
1268 4494b184 Filippos Giannakos
        return 0;
1269 6d486cc0 Georgios D. Tsoukalas
}
1270 6d486cc0 Georgios D. Tsoukalas
1271 0a5d10a9 Filippos Giannakos
int xseg_prep_request ( struct xseg* xseg, struct xseg_request *req,
1272 abaea134 Stratos Psomadakis
                        uint32_t targetlen, uint64_t datalen )
1273 6d486cc0 Georgios D. Tsoukalas
{
1274 4494b184 Filippos Giannakos
        uint64_t bufferlen = targetlen + datalen;
1275 fe34fb45 User
        void *buf;
1276 fe34fb45 User
        req->buffer = 0;
1277 fe34fb45 User
        req->bufferlen = 0;
1278 fe34fb45 User
        buf = xseg_alloc_buffer(xseg, bufferlen);
1279 4494b184 Filippos Giannakos
        if (!buf)
1280 6d486cc0 Georgios D. Tsoukalas
                return -1;
1281 4494b184 Filippos Giannakos
        req->bufferlen = xheap_get_chunk_size(buf);
1282 4494b184 Filippos Giannakos
        req->buffer = XPTR_MAKE(buf, xseg->segment);
1283 4494b184 Filippos Giannakos
        
1284 6d486cc0 Georgios D. Tsoukalas
        req->data = req->buffer;
1285 abaea134 Stratos Psomadakis
        req->target = req->buffer + req->bufferlen - targetlen;
1286 abaea134 Stratos Psomadakis
        req->datalen = datalen;
1287 abaea134 Stratos Psomadakis
        req->targetlen = targetlen;
1288 6d486cc0 Georgios D. Tsoukalas
        return 0;
1289 6d486cc0 Georgios D. Tsoukalas
}
1290 6d486cc0 Georgios D. Tsoukalas
1291 e7c27378 Filippos Giannakos
int xseg_resize_request (struct xseg *xseg, struct xseg_request *req,
1292 e7c27378 Filippos Giannakos
                        uint32_t new_targetlen, uint64_t new_datalen)
1293 e7c27378 Filippos Giannakos
{
1294 40e56a42 Filippos Giannakos
        if (req->bufferlen >= new_datalen + new_targetlen) {
1295 40e56a42 Filippos Giannakos
                req->data = req->buffer;
1296 40e56a42 Filippos Giannakos
                req->target = req->buffer + req->bufferlen - new_targetlen;
1297 40e56a42 Filippos Giannakos
                req->datalen = new_datalen;
1298 40e56a42 Filippos Giannakos
                req->targetlen = new_targetlen;
1299 8dc198c8 Filippos Giannakos
                return 0;
1300 40e56a42 Filippos Giannakos
        }
1301 8dc198c8 Filippos Giannakos
1302 e7c27378 Filippos Giannakos
        if (req->buffer){
1303 e7c27378 Filippos Giannakos
                void *ptr = XPTR_TAKE(req->buffer, xseg->segment);
1304 e7c27378 Filippos Giannakos
                xseg_free_buffer(xseg, ptr);
1305 e7c27378 Filippos Giannakos
        }
1306 e7c27378 Filippos Giannakos
        req->buffer = 0;
1307 e7c27378 Filippos Giannakos
        req->bufferlen = 0;
1308 e7c27378 Filippos Giannakos
        return xseg_prep_request(xseg, req, new_targetlen, new_datalen);
1309 e7c27378 Filippos Giannakos
}
1310 e7c27378 Filippos Giannakos
1311 1b52f571 Stratos Psomadakis
static void __update_timestamp(struct xseg_request *xreq)
1312 1b52f571 Stratos Psomadakis
{
1313 1b52f571 Stratos Psomadakis
        struct timeval tv;
1314 1b52f571 Stratos Psomadakis
1315 1b52f571 Stratos Psomadakis
        __get_current_time(&tv);
1316 1b52f571 Stratos Psomadakis
        if (xreq->timestamp.tv_sec != 0)
1317 1b52f571 Stratos Psomadakis
                /*
1318 1b52f571 Stratos Psomadakis
                 * FIXME: Make xreq->elapsed timeval/timespec again to avoid the
1319 1b52f571 Stratos Psomadakis
                 *                   multiplication?
1320 1b52f571 Stratos Psomadakis
                 */
1321 1b52f571 Stratos Psomadakis
                xreq->elapsed += (tv.tv_sec - xreq->timestamp.tv_sec) * 1000000 
1322 1b52f571 Stratos Psomadakis
                                                + (tv.tv_usec - xreq->timestamp.tv_usec);
1323 1b52f571 Stratos Psomadakis
1324 1b52f571 Stratos Psomadakis
        xreq->timestamp.tv_sec = tv.tv_sec;
1325 1b52f571 Stratos Psomadakis
        xreq->timestamp.tv_usec = tv.tv_usec;
1326 1b52f571 Stratos Psomadakis
}
1327 1b52f571 Stratos Psomadakis
1328 e06fe035 Filippos Giannakos
//FIXME should we add NON_BLOCK flag?
1329 e3052736 Filippos Giannakos
xport xseg_submit (struct xseg *xseg, struct xseg_request *xreq,
1330 7882a035 Filippos Giannakos
                        xport portno, uint32_t flags)
1331 6d486cc0 Georgios D. Tsoukalas
{
1332 6d486cc0 Georgios D. Tsoukalas
        xserial serial = NoSerial;
1333 6e36d028 Filippos Giannakos
        xqindex xqi, r;
1334 6e36d028 Filippos Giannakos
        struct xq *q, *newq;
1335 9a418f2f Filippos Giannakos
        xport next, cur;
1336 9a418f2f Filippos Giannakos
        struct xseg_port *port;
1337 9a418f2f Filippos Giannakos
1338 e3052736 Filippos Giannakos
        /* discover where to submit */
1339 e3052736 Filippos Giannakos
1340 e3052736 Filippos Giannakos
        if (!__validate_port(xseg, xreq->transit_portno)){
1341 e3052736 Filippos Giannakos
                XSEGLOG("Couldn't validate transit_portno (portno: %lu)",
1342 e3052736 Filippos Giannakos
                                xreq->transit_portno);
1343 7882a035 Filippos Giannakos
                return NoPort;
1344 b04e0466 User
        }
1345 e3052736 Filippos Giannakos
        if (!__validate_port(xseg, xreq->effective_dst_portno)){
1346 e3052736 Filippos Giannakos
                XSEGLOG("Couldn't validate effective_dst_portno (portno: %lu)",
1347 e3052736 Filippos Giannakos
                                xreq->effective_dst_portno);
1348 7882a035 Filippos Giannakos
                return NoPort;
1349 b04e0466 User
        }
1350 9a418f2f Filippos Giannakos
1351 e3052736 Filippos Giannakos
        cur = xreq->transit_portno;
1352 e3052736 Filippos Giannakos
        next = cur;
1353 e3052736 Filippos Giannakos
        //FIXME assert(cur == portno);
1354 e3052736 Filippos Giannakos
        do {
1355 e3052736 Filippos Giannakos
                if (next == xreq->effective_dst_portno){
1356 e3052736 Filippos Giannakos
                        XSEGLOG("Path ended with no one willing to accept");
1357 e3052736 Filippos Giannakos
                        return NoPort;
1358 e3052736 Filippos Giannakos
                }
1359 9a418f2f Filippos Giannakos
1360 e3052736 Filippos Giannakos
                if (xseg->path_next[next] != NoPort){
1361 e3052736 Filippos Giannakos
                        next = xseg->path_next[next];
1362 e3052736 Filippos Giannakos
                } else {
1363 e3052736 Filippos Giannakos
                        next = xreq->effective_dst_portno;
1364 e3052736 Filippos Giannakos
                }
1365 e3052736 Filippos Giannakos
1366 e3052736 Filippos Giannakos
                port = xseg_get_port(xseg, next);
1367 e3052736 Filippos Giannakos
                if (!port){
1368 e3052736 Filippos Giannakos
                        XSEGLOG("Couldnt get port (next :%u)", next);
1369 e3052736 Filippos Giannakos
                        return NoPort;
1370 e3052736 Filippos Giannakos
                }
1371 e3052736 Filippos Giannakos
        } while ((!port->flags & CAN_ACCEPT));
1372 e3052736 Filippos Giannakos
1373 e3052736 Filippos Giannakos
        /* submit */
1374 6d486cc0 Georgios D. Tsoukalas
1375 166c1bff Filippos Giannakos
        //__update_timestamp(xreq);
1376 e3052736 Filippos Giannakos
1377 4494b184 Filippos Giannakos
        xqi = XPTR_MAKE(xreq, xseg->segment);
1378 6e36d028 Filippos Giannakos
1379 9a418f2f Filippos Giannakos
        /* add current port to path */
1380 9a418f2f Filippos Giannakos
        serial = __xq_append_head(&xreq->path, cur);
1381 9a418f2f Filippos Giannakos
        if (serial == Noneidx){
1382 e3052736 Filippos Giannakos
                XSEGLOG("Couldn't append path head");
1383 7882a035 Filippos Giannakos
                return NoPort;
1384 9a418f2f Filippos Giannakos
        }
1385 9a418f2f Filippos Giannakos
1386 6e36d028 Filippos Giannakos
        xlock_acquire(&port->rq_lock, portno);
1387 6e36d028 Filippos Giannakos
        q = XPTR_TAKE(port->request_queue, xseg->segment);
1388 6e36d028 Filippos Giannakos
        serial = __xq_append_tail(q, xqi);
1389 7882a035 Filippos Giannakos
        if (flags & X_ALLOC && serial == Noneidx) {
1390 6e36d028 Filippos Giannakos
                /* double up queue size */
1391 e3052736 Filippos Giannakos
                XSEGLOG("Trying to double up queue");
1392 06773369 Filippos Giannakos
                newq = __alloc_queue(xseg, xq_size(q)*2);
1393 6e36d028 Filippos Giannakos
                if (!newq)
1394 6e36d028 Filippos Giannakos
                        goto out_rel;
1395 6e36d028 Filippos Giannakos
                r = __xq_resize(q, newq);
1396 7882a035 Filippos Giannakos
                if (r == Noneidx){
1397 7882a035 Filippos Giannakos
                        xheap_free(newq);
1398 6e36d028 Filippos Giannakos
                        goto out_rel;
1399 7882a035 Filippos Giannakos
                }
1400 6e36d028 Filippos Giannakos
                port->request_queue = XPTR_MAKE(newq, xseg->segment);
1401 6e36d028 Filippos Giannakos
                xheap_free(q);
1402 6e36d028 Filippos Giannakos
                serial = __xq_append_tail(newq, xqi);
1403 6e36d028 Filippos Giannakos
        }
1404 6e36d028 Filippos Giannakos
1405 6e36d028 Filippos Giannakos
out_rel:
1406 6e36d028 Filippos Giannakos
        xlock_release(&port->rq_lock);
1407 b04e0466 User
        if (serial == Noneidx){
1408 e3052736 Filippos Giannakos
                XSEGLOG("Couldn't append request to queue");
1409 9a418f2f Filippos Giannakos
                __xq_pop_head(&xreq->path);
1410 b04e0466 User
                next = NoPort;
1411 b04e0466 User
        }
1412 7882a035 Filippos Giannakos
        return next;
1413 e3052736 Filippos Giannakos
1414 6d486cc0 Georgios D. Tsoukalas
}
1415 6d486cc0 Georgios D. Tsoukalas
1416 cc21de66 Giannakos Filippos
struct xseg_request *xseg_receive(struct xseg *xseg, xport portno, uint32_t flags)
1417 6d486cc0 Georgios D. Tsoukalas
{
1418 6d486cc0 Georgios D. Tsoukalas
        xqindex xqi;
1419 9a418f2f Filippos Giannakos
        xserial serial = NoSerial;
1420 4494b184 Filippos Giannakos
        struct xq *q;
1421 4494b184 Filippos Giannakos
        struct xseg_request *req;
1422 4494b184 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1423 4494b184 Filippos Giannakos
        if (!port)
1424 6d486cc0 Georgios D. Tsoukalas
                return NULL;
1425 9a418f2f Filippos Giannakos
retry:
1426 cc21de66 Giannakos Filippos
        if (flags & X_NONBLOCK) {
1427 cc21de66 Giannakos Filippos
                if (!xlock_try_lock(&port->pq_lock, portno))
1428 cc21de66 Giannakos Filippos
                        return NULL;
1429 cc21de66 Giannakos Filippos
        } else {
1430 cc21de66 Giannakos Filippos
                xlock_acquire(&port->pq_lock, portno);
1431 cc21de66 Giannakos Filippos
        }
1432 4494b184 Filippos Giannakos
        q = XPTR_TAKE(port->reply_queue, xseg->segment);
1433 6e36d028 Filippos Giannakos
        xqi = __xq_pop_head(q);
1434 6e36d028 Filippos Giannakos
        xlock_release(&port->pq_lock);
1435 6e36d028 Filippos Giannakos
1436 78596ef2 Stratos Psomadakis
        if (xqi == Noneidx)
1437 6d486cc0 Georgios D. Tsoukalas
                return NULL;
1438 6d486cc0 Georgios D. Tsoukalas
1439 4494b184 Filippos Giannakos
        req = XPTR_TAKE(xqi, xseg->segment);
1440 166c1bff Filippos Giannakos
//        __update_timestamp(req);
1441 61473749 Filippos Giannakos
        serial = __xq_pop_head(&req->path);
1442 9a418f2f Filippos Giannakos
        if (serial == Noneidx){
1443 9a418f2f Filippos Giannakos
                /* this should never happen */
1444 9a418f2f Filippos Giannakos
                XSEGLOG("pop head of path queue returned Noneidx\n");
1445 9a418f2f Filippos Giannakos
                goto retry;
1446 9a418f2f Filippos Giannakos
        }
1447 9a418f2f Filippos Giannakos
1448 1b52f571 Stratos Psomadakis
1449 4494b184 Filippos Giannakos
        return req;
1450 6d486cc0 Georgios D. Tsoukalas
}
1451 6d486cc0 Georgios D. Tsoukalas
1452 cc21de66 Giannakos Filippos
struct xseg_request *xseg_accept(struct xseg *xseg, xport portno, uint32_t flags)
1453 6d486cc0 Georgios D. Tsoukalas
{
1454 6d486cc0 Georgios D. Tsoukalas
        xqindex xqi;
1455 4494b184 Filippos Giannakos
        struct xq *q;
1456 4494b184 Filippos Giannakos
        struct xseg_request *req;
1457 4494b184 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1458 4494b184 Filippos Giannakos
        if (!port)
1459 6d486cc0 Georgios D. Tsoukalas
                return NULL;
1460 cc21de66 Giannakos Filippos
        if (flags & X_NONBLOCK) {
1461 cc21de66 Giannakos Filippos
                if (!xlock_try_lock(&port->rq_lock, portno))
1462 cc21de66 Giannakos Filippos
                        return NULL;
1463 cc21de66 Giannakos Filippos
        } else {
1464 cc21de66 Giannakos Filippos
                xlock_acquire(&port->rq_lock, portno);
1465 cc21de66 Giannakos Filippos
        }
1466 cc21de66 Giannakos Filippos
1467 4494b184 Filippos Giannakos
        q = XPTR_TAKE(port->request_queue, xseg->segment);
1468 6e36d028 Filippos Giannakos
        xqi = __xq_pop_head(q);
1469 6e36d028 Filippos Giannakos
        xlock_release(&port->rq_lock);
1470 78596ef2 Stratos Psomadakis
        if (xqi == Noneidx)
1471 6d486cc0 Georgios D. Tsoukalas
                return NULL;
1472 6d486cc0 Georgios D. Tsoukalas
1473 4494b184 Filippos Giannakos
        req = XPTR_TAKE(xqi, xseg->segment);
1474 e3052736 Filippos Giannakos
        req->transit_portno = portno;
1475 9a418f2f Filippos Giannakos
1476 9a418f2f Filippos Giannakos
        return req;
1477 6d486cc0 Georgios D. Tsoukalas
}
1478 6d486cc0 Georgios D. Tsoukalas
1479 e06fe035 Filippos Giannakos
//FIXME should we add NON_BLOCK flag?
1480 7882a035 Filippos Giannakos
xport xseg_respond (struct xseg *xseg, struct xseg_request *xreq,
1481 7882a035 Filippos Giannakos
                        xport portno, uint32_t flags)
1482 6d486cc0 Georgios D. Tsoukalas
{
1483 6d486cc0 Georgios D. Tsoukalas
        xserial serial = NoSerial;
1484 6e36d028 Filippos Giannakos
        xqindex xqi, r;
1485 6e36d028 Filippos Giannakos
        struct xq *q, *newq;
1486 9a418f2f Filippos Giannakos
        struct xseg_port *port;
1487 61473749 Filippos Giannakos
        xport dst;
1488 9a418f2f Filippos Giannakos
1489 e3052736 Filippos Giannakos
retry:
1490 9a418f2f Filippos Giannakos
        serial = __xq_peek_head(&xreq->path);
1491 9a418f2f Filippos Giannakos
        if (serial == Noneidx)
1492 7882a035 Filippos Giannakos
                return NoPort;
1493 61473749 Filippos Giannakos
        dst = (xport) serial;
1494 e06fe035 Filippos Giannakos
1495 61473749 Filippos Giannakos
        port = xseg_get_port(xseg, dst);
1496 4494b184 Filippos Giannakos
        if (!port)
1497 7882a035 Filippos Giannakos
                return NoPort;
1498 e3052736 Filippos Giannakos
        if (!(port->flags & CAN_RECEIVE)){
1499 e3052736 Filippos Giannakos
                //XSEGLOG("Port %u cannot receive", dst);
1500 e3052736 Filippos Giannakos
                /* Port cannot receive. Try next one in path */
1501 e3052736 Filippos Giannakos
                __xq_pop_head(&xreq->path);
1502 e3052736 Filippos Giannakos
                goto retry;
1503 e3052736 Filippos Giannakos
        }
1504 e06fe035 Filippos Giannakos
1505 4494b184 Filippos Giannakos
        xqi = XPTR_MAKE(xreq, xseg->segment);
1506 e06fe035 Filippos Giannakos
1507 6e36d028 Filippos Giannakos
        xlock_acquire(&port->pq_lock, portno);
1508 6e36d028 Filippos Giannakos
        q = XPTR_TAKE(port->reply_queue, xseg->segment);
1509 6e36d028 Filippos Giannakos
        serial = __xq_append_tail(q, xqi);
1510 7882a035 Filippos Giannakos
        if (flags & X_ALLOC && serial == Noneidx) {
1511 06773369 Filippos Giannakos
                newq = __alloc_queue(xseg, xq_size(q)*2);
1512 e06fe035 Filippos Giannakos
                if (!newq)
1513 6e36d028 Filippos Giannakos
                        goto out_rel;
1514 6e36d028 Filippos Giannakos
                r = __xq_resize(q, newq);
1515 7882a035 Filippos Giannakos
                if (r == Noneidx) {
1516 7882a035 Filippos Giannakos
                        xheap_free(newq);
1517 6e36d028 Filippos Giannakos
                        goto out_rel;
1518 7882a035 Filippos Giannakos
                }
1519 6e36d028 Filippos Giannakos
                port->reply_queue = XPTR_MAKE(newq, xseg->segment);
1520 6e36d028 Filippos Giannakos
                xheap_free(q);
1521 6e36d028 Filippos Giannakos
                serial = __xq_append_tail(newq, xqi);
1522 6e36d028 Filippos Giannakos
        }
1523 6e36d028 Filippos Giannakos
1524 6e36d028 Filippos Giannakos
out_rel:
1525 6e36d028 Filippos Giannakos
        xlock_release(&port->pq_lock);
1526 e06fe035 Filippos Giannakos
1527 7882a035 Filippos Giannakos
        if (serial == Noneidx)
1528 7882a035 Filippos Giannakos
                dst = NoPort;
1529 7882a035 Filippos Giannakos
        return dst;
1530 4494b184 Filippos Giannakos
        
1531 6d486cc0 Georgios D. Tsoukalas
}
1532 6d486cc0 Georgios D. Tsoukalas
1533 e3052736 Filippos Giannakos
xport xseg_forward(struct xseg *xseg, struct xseg_request *req, xport new_dst,
1534 e3052736 Filippos Giannakos
                xport portno, uint32_t flags)
1535 9a418f2f Filippos Giannakos
{
1536 e3052736 Filippos Giannakos
        if (!__validate_port(xseg, new_dst)){
1537 e3052736 Filippos Giannakos
                XSEGLOG("Couldn't validate new destination (new_dst %lu)",
1538 e3052736 Filippos Giannakos
                                new_dst);
1539 9a418f2f Filippos Giannakos
                return NoPort;
1540 e3052736 Filippos Giannakos
        }
1541 e3052736 Filippos Giannakos
        req->effective_dst_portno = new_dst;
1542 e3052736 Filippos Giannakos
        return xseg_submit(xseg, req, portno, flags);
1543 9a418f2f Filippos Giannakos
1544 9a418f2f Filippos Giannakos
}
1545 9a418f2f Filippos Giannakos
1546 e3052736 Filippos Giannakos
int xseg_set_path_next(struct xseg *xseg, xport portno, xport next)
1547 9a418f2f Filippos Giannakos
{
1548 9a418f2f Filippos Giannakos
        if (!__validate_port(xseg, portno))
1549 e3052736 Filippos Giannakos
                return -1;
1550 e3052736 Filippos Giannakos
        if (!__validate_port(xseg, next))
1551 e3052736 Filippos Giannakos
                return -1;
1552 e3052736 Filippos Giannakos
        xseg->path_next[portno] = next;
1553 e3052736 Filippos Giannakos
        return 0;
1554 9a418f2f Filippos Giannakos
}
1555 9a418f2f Filippos Giannakos
1556 61473749 Filippos Giannakos
int xseg_set_req_data(struct xseg *xseg, struct xseg_request *xreq, void *data)
1557 61473749 Filippos Giannakos
{
1558 61473749 Filippos Giannakos
        int r;
1559 a5c1eefb User
        xhash_t *req_data;
1560 a5c1eefb User
        
1561 a5c1eefb User
        xlock_acquire(&xseg->priv->reqdatalock, 1);
1562 a5c1eefb User
1563 a5c1eefb User
        req_data = xseg->priv->req_data;
1564 8a1b5a0d Filippos Giannakos
        r = xhash_insert(req_data, (xhashidx) xreq, (xhashidx) data);
1565 61473749 Filippos Giannakos
        if (r == -XHASH_ERESIZE) {
1566 30cd71a2 Filippos Giannakos
                req_data = xhash_resize(req_data, xhash_grow_size_shift(req_data), 0, NULL);
1567 61473749 Filippos Giannakos
                if (req_data) {
1568 61473749 Filippos Giannakos
                        xseg->priv->req_data = req_data;
1569 8a1b5a0d Filippos Giannakos
                        r = xhash_insert(req_data, (xhashidx) xreq, (xhashidx) data);
1570 61473749 Filippos Giannakos
                }
1571 61473749 Filippos Giannakos
        }
1572 a5c1eefb User
1573 a5c1eefb User
        xlock_release(&xseg->priv->reqdatalock);
1574 61473749 Filippos Giannakos
        return r;
1575 61473749 Filippos Giannakos
}
1576 61473749 Filippos Giannakos
1577 61473749 Filippos Giannakos
int xseg_get_req_data(struct xseg *xseg, struct xseg_request *xreq, void **data)
1578 61473749 Filippos Giannakos
{
1579 a5c1eefb User
        int r;
1580 8a1b5a0d Filippos Giannakos
        xhashidx val;
1581 a5c1eefb User
        xhash_t *req_data;
1582 a5c1eefb User
        
1583 a5c1eefb User
        xlock_acquire(&xseg->priv->reqdatalock, 1);
1584 a5c1eefb User
1585 a5c1eefb User
        req_data = xseg->priv->req_data;
1586 a5c1eefb User
        //maybe we need a xhash_delete with lookup...
1587 a5c1eefb User
        //maybe we also need a delete that doesn't shrink xhash
1588 8a1b5a0d Filippos Giannakos
        r = xhash_lookup(req_data, (xhashidx) xreq, &val);
1589 61473749 Filippos Giannakos
        *data = (void *) val;
1590 a5c1eefb User
        if (r >= 0) {
1591 8a1b5a0d Filippos Giannakos
                r = xhash_delete(req_data, (xhashidx) xreq);
1592 61473749 Filippos Giannakos
                if (r == -XHASH_ERESIZE) {
1593 30cd71a2 Filippos Giannakos
                        req_data = xhash_resize(req_data, xhash_shrink_size_shift(req_data), 0, NULL);
1594 61473749 Filippos Giannakos
                        if (req_data){
1595 61473749 Filippos Giannakos
                                xseg->priv->req_data = req_data;
1596 8a1b5a0d Filippos Giannakos
                                r = xhash_delete(req_data, (xhashidx) xreq);
1597 61473749 Filippos Giannakos
                        }
1598 61473749 Filippos Giannakos
                }
1599 61473749 Filippos Giannakos
        }
1600 a5c1eefb User
1601 a5c1eefb User
        xlock_release(&xseg->priv->reqdatalock);
1602 a5c1eefb User
        return r;
1603 61473749 Filippos Giannakos
}
1604 6d486cc0 Georgios D. Tsoukalas
1605 44c41348 Giannakos Filippos
struct xobject_h * xseg_get_objh(struct xseg *xseg, uint32_t magic, uint64_t size)
1606 44c41348 Giannakos Filippos
{
1607 44c41348 Giannakos Filippos
        int r;
1608 44c41348 Giannakos Filippos
        struct xobject_h *obj_h = xobj_get_obj(xseg->object_handlers, X_ALLOC);
1609 44c41348 Giannakos Filippos
        if (!obj_h)
1610 44c41348 Giannakos Filippos
                return NULL;
1611 44c41348 Giannakos Filippos
        r = xobj_handler_init(obj_h, xseg->segment, magic, size, xseg->heap);
1612 44c41348 Giannakos Filippos
        if (r < 0) {
1613 44c41348 Giannakos Filippos
                xobj_put_obj(xseg->object_handlers, obj_h);
1614 44c41348 Giannakos Filippos
                return NULL;
1615 44c41348 Giannakos Filippos
        }
1616 44c41348 Giannakos Filippos
        return obj_h;
1617 44c41348 Giannakos Filippos
}
1618 44c41348 Giannakos Filippos
1619 44c41348 Giannakos Filippos
void xseg_put_objh(struct xseg *xseg, struct xobject_h *objh)
1620 44c41348 Giannakos Filippos
{
1621 44c41348 Giannakos Filippos
        xobj_put_obj(xseg->object_handlers, objh);
1622 44c41348 Giannakos Filippos
}
1623 44c41348 Giannakos Filippos
1624 44c41348 Giannakos Filippos
1625 7882a035 Filippos Giannakos
/*
1626 7882a035 Filippos Giannakos
int xseg_complete_req(struct xseg_request *req)
1627 7882a035 Filippos Giannakos
{
1628 7882a035 Filippos Giannakos
        req->state |= XS_SERVED;
1629 7882a035 Filippos Giannakos
        req->state &= ~XS_FAILED;
1630 7882a035 Filippos Giannakos
}
1631 7882a035 Filippos Giannakos

1632 7882a035 Filippos Giannakos
int xseg_fail_req(struct xseg_request *req)
1633 7882a035 Filippos Giannakos
{
1634 7882a035 Filippos Giannakos
        req->state &= ~XS_SERVED;
1635 7882a035 Filippos Giannakos
        req->state |= XS_FAILED;
1636 7882a035 Filippos Giannakos
}
1637 7882a035 Filippos Giannakos
*/
1638 7882a035 Filippos Giannakos
1639 17590774 Giannakos Filippos
struct xseg_port *xseg_bind_port(struct xseg *xseg, uint32_t req, void * sd)
1640 6d486cc0 Georgios D. Tsoukalas
{
1641 6d486cc0 Georgios D. Tsoukalas
        uint32_t portno, maxno, id = __get_id(), force;
1642 61473749 Filippos Giannakos
        struct xseg_port *port = NULL;
1643 a6600315 Filippos Giannakos
        void *peer_data, *sigdesc;
1644 a6600315 Filippos Giannakos
        int64_t driver;
1645 a6600315 Filippos Giannakos
        int r;
1646 6d486cc0 Georgios D. Tsoukalas
1647 0f944d14 Filippos Giannakos
        if (xseg->config.dynports >= xseg->config.nr_ports) {
1648 0f944d14 Filippos Giannakos
                return NULL;
1649 0f944d14 Filippos Giannakos
        }
1650 0f944d14 Filippos Giannakos
1651 0f944d14 Filippos Giannakos
        if (req >= xseg->config.dynports) {
1652 6d486cc0 Georgios D. Tsoukalas
                portno = 0;
1653 0f944d14 Filippos Giannakos
                maxno = xseg->config.dynports;
1654 6d486cc0 Georgios D. Tsoukalas
                force = 0;
1655 6d486cc0 Georgios D. Tsoukalas
        } else {
1656 6d486cc0 Georgios D. Tsoukalas
                portno = req;
1657 3b07b042 Stratos Psomadakis
                maxno = req + 1;
1658 6d486cc0 Georgios D. Tsoukalas
                force = 1;
1659 6d486cc0 Georgios D. Tsoukalas
        }
1660 6d486cc0 Georgios D. Tsoukalas
1661 6d486cc0 Georgios D. Tsoukalas
        __lock_segment(xseg);
1662 3b07b042 Stratos Psomadakis
        for (; portno < maxno; portno++) {
1663 bf045861 Filippos Giannakos
                if (!xseg->ports[portno]) {
1664 71e81af5 Filippos Giannakos
                        port = xseg_alloc_port(xseg, X_ALLOC, XSEG_DEF_REQS);
1665 bf045861 Filippos Giannakos
                        if (!port)
1666 bf045861 Filippos Giannakos
                                goto out;
1667 bf045861 Filippos Giannakos
                } else if (force) {
1668 bf045861 Filippos Giannakos
                        port = xseg_get_port(xseg, portno);
1669 bf045861 Filippos Giannakos
                        if (!port)
1670 bf045861 Filippos Giannakos
                                goto out;        
1671 bf045861 Filippos Giannakos
                } else {
1672 6d486cc0 Georgios D. Tsoukalas
                        continue;
1673 bf045861 Filippos Giannakos
                }
1674 6e0a3771 Georgios D. Tsoukalas
                driver = __enable_driver(xseg, &xseg->priv->peer_type);
1675 6d486cc0 Georgios D. Tsoukalas
                if (driver < 0)
1676 6d486cc0 Georgios D. Tsoukalas
                        break;
1677 17590774 Giannakos Filippos
                if (!sd){
1678 a6600315 Filippos Giannakos
                        peer_data = __get_peer_type_data(xseg, (uint64_t) driver);
1679 44c41348 Giannakos Filippos
                        if (!peer_data)
1680 17590774 Giannakos Filippos
                                break;
1681 a6600315 Filippos Giannakos
                        sigdesc = xseg->priv->peer_type.peer_ops.alloc_signal_desc(xseg, peer_data);
1682 44c41348 Giannakos Filippos
                        if (!sigdesc)
1683 17590774 Giannakos Filippos
                                break;
1684 a6600315 Filippos Giannakos
                        r = xseg->priv->peer_type.peer_ops.init_signal_desc(xseg, sigdesc);
1685 44c41348 Giannakos Filippos
                        if (r < 0){
1686 44c41348 Giannakos Filippos
                                xseg->priv->peer_type.peer_ops.free_signal_desc(xseg, peer_data, sigdesc);
1687 44c41348 Giannakos Filippos
                                break;
1688 44c41348 Giannakos Filippos
                        }
1689 17590774 Giannakos Filippos
                        port->signal_desc = XPTR_MAKE(sigdesc, xseg->segment);
1690 17590774 Giannakos Filippos
                } else {
1691 17590774 Giannakos Filippos
                        port->signal_desc = XPTR_MAKE(sd, xseg->segment);
1692 17590774 Giannakos Filippos
                }
1693 6e0a3771 Georgios D. Tsoukalas
                port->peer_type = (uint64_t)driver;
1694 6d486cc0 Georgios D. Tsoukalas
                port->owner = id;
1695 6f2e0b3a Filippos Giannakos
                port->portno = portno;
1696 e3052736 Filippos Giannakos
                port->flags = CAN_ACCEPT | CAN_RECEIVE;
1697 be1186ce Filippos Giannakos
                xseg->ports[portno] = XPTR_MAKE(port, xseg->segment);
1698 6d486cc0 Georgios D. Tsoukalas
                goto out;
1699 6d486cc0 Georgios D. Tsoukalas
        }
1700 61473749 Filippos Giannakos
        if (port) {
1701 61473749 Filippos Giannakos
                xseg_free_port(xseg, port);
1702 5722660a Giannakos Filippos
                xseg->ports[portno] = 0;
1703 61473749 Filippos Giannakos
                port = NULL;
1704 61473749 Filippos Giannakos
        }
1705 6d486cc0 Georgios D. Tsoukalas
out:
1706 6d486cc0 Georgios D. Tsoukalas
        __unlock_segment(xseg);
1707 6d486cc0 Georgios D. Tsoukalas
        return port;
1708 6d486cc0 Georgios D. Tsoukalas
}
1709 6d486cc0 Georgios D. Tsoukalas
1710 0f944d14 Filippos Giannakos
struct xseg_port *xseg_bind_dynport(struct xseg *xseg)
1711 0f944d14 Filippos Giannakos
{
1712 0f944d14 Filippos Giannakos
        uint32_t portno, maxno, id = __get_id();
1713 0f944d14 Filippos Giannakos
        struct xseg_port *port = NULL;
1714 0f944d14 Filippos Giannakos
        void *peer_data, *sigdesc;
1715 0f944d14 Filippos Giannakos
        int64_t driver;
1716 0f944d14 Filippos Giannakos
        int r, has_sd=0, port_allocated=0;
1717 0f944d14 Filippos Giannakos
1718 0f944d14 Filippos Giannakos
        maxno = xseg->config.nr_ports;
1719 0f944d14 Filippos Giannakos
1720 0f944d14 Filippos Giannakos
        __lock_segment(xseg);
1721 d929dc12 Filippos Giannakos
        driver = __enable_driver(xseg, &xseg->priv->peer_type);
1722 d929dc12 Filippos Giannakos
        if (driver < 0)
1723 d929dc12 Filippos Giannakos
                return NULL;
1724 d929dc12 Filippos Giannakos
1725 0f944d14 Filippos Giannakos
        for (portno = xseg->config.dynports; portno < maxno; portno++) {
1726 0f944d14 Filippos Giannakos
                if (!xseg->ports[portno]) {
1727 0f944d14 Filippos Giannakos
                        port = xseg_alloc_port(xseg, X_ALLOC, XSEG_DEF_REQS);
1728 0f944d14 Filippos Giannakos
                        if (!port)
1729 0f944d14 Filippos Giannakos
                                goto out;
1730 0f944d14 Filippos Giannakos
                        xseg->ports[portno] = XPTR_MAKE(port, xseg->segment);
1731 0f944d14 Filippos Giannakos
                        port_allocated = 1;
1732 0f944d14 Filippos Giannakos
                } else {
1733 0f944d14 Filippos Giannakos
                        port = xseg_get_port(xseg, portno);
1734 0f944d14 Filippos Giannakos
                        if (!port)
1735 0f944d14 Filippos Giannakos
                                goto out;
1736 0f944d14 Filippos Giannakos
                        if (port->owner != Noone)
1737 0f944d14 Filippos Giannakos
                                continue;
1738 0f944d14 Filippos Giannakos
1739 d929dc12 Filippos Giannakos
                        if (port->signal_desc) {
1740 d929dc12 Filippos Giannakos
                                if (port->peer_type == driver) {
1741 d929dc12 Filippos Giannakos
                                        has_sd = 1;
1742 d929dc12 Filippos Giannakos
                                } else {
1743 d929dc12 Filippos Giannakos
                                        /* Just abandon the old signal desc.
1744 d929dc12 Filippos Giannakos
                                         * We can't be really sure when to free
1745 d929dc12 Filippos Giannakos
                                         * it.
1746 d929dc12 Filippos Giannakos
                                         * Minor memory leak.
1747 d929dc12 Filippos Giannakos
                                         */
1748 d929dc12 Filippos Giannakos
                                        port->signal_desc = 0;
1749 d929dc12 Filippos Giannakos
                                }
1750 d929dc12 Filippos Giannakos
                        }
1751 0f944d14 Filippos Giannakos
                }
1752 0f944d14 Filippos Giannakos
                if (!has_sd){
1753 0f944d14 Filippos Giannakos
                        peer_data = __get_peer_type_data(xseg, (uint64_t) driver);
1754 0f944d14 Filippos Giannakos
                        if (!peer_data)
1755 0f944d14 Filippos Giannakos
                                break;
1756 0f944d14 Filippos Giannakos
                        sigdesc = xseg->priv->peer_type.peer_ops.alloc_signal_desc(xseg, peer_data);
1757 0f944d14 Filippos Giannakos
                        if (!sigdesc)
1758 0f944d14 Filippos Giannakos
                                break;
1759 0f944d14 Filippos Giannakos
                        r = xseg->priv->peer_type.peer_ops.init_signal_desc(xseg, sigdesc);
1760 0f944d14 Filippos Giannakos
                        if (r < 0){
1761 0f944d14 Filippos Giannakos
                                xseg->priv->peer_type.peer_ops.free_signal_desc(xseg, peer_data, sigdesc);
1762 0f944d14 Filippos Giannakos
                                break;
1763 0f944d14 Filippos Giannakos
                        }
1764 0f944d14 Filippos Giannakos
                        port->signal_desc = XPTR_MAKE(sigdesc, xseg->segment);
1765 0f944d14 Filippos Giannakos
                }
1766 0f944d14 Filippos Giannakos
                port->peer_type = (uint64_t)driver;
1767 0f944d14 Filippos Giannakos
                port->owner = id;
1768 0f944d14 Filippos Giannakos
                port->portno = portno;
1769 0f944d14 Filippos Giannakos
                port->flags = CAN_ACCEPT | CAN_RECEIVE;
1770 0f944d14 Filippos Giannakos
                goto out;
1771 0f944d14 Filippos Giannakos
        }
1772 0f944d14 Filippos Giannakos
        if (port_allocated) {
1773 0f944d14 Filippos Giannakos
                xseg_free_port(xseg, port);
1774 0f944d14 Filippos Giannakos
                xseg->ports[portno] = 0;
1775 0f944d14 Filippos Giannakos
        }
1776 0f944d14 Filippos Giannakos
        port = NULL;
1777 0f944d14 Filippos Giannakos
out:
1778 0f944d14 Filippos Giannakos
        __unlock_segment(xseg);
1779 0f944d14 Filippos Giannakos
        return port;
1780 0f944d14 Filippos Giannakos
}
1781 0f944d14 Filippos Giannakos
1782 0f944d14 Filippos Giannakos
int xseg_leave_dynport(struct xseg *xseg, struct xseg_port *port)
1783 0f944d14 Filippos Giannakos
{
1784 0f944d14 Filippos Giannakos
        if (!port)
1785 0f944d14 Filippos Giannakos
                return -1;
1786 0f944d14 Filippos Giannakos
1787 0f944d14 Filippos Giannakos
        __lock_segment(xseg);
1788 0f944d14 Filippos Giannakos
        port->owner = Noone;
1789 0f944d14 Filippos Giannakos
        __unlock_segment(xseg);
1790 0f944d14 Filippos Giannakos
        return 0;
1791 0f944d14 Filippos Giannakos
}
1792 0f944d14 Filippos Giannakos
1793 e06fe035 Filippos Giannakos
/*
1794 e06fe035 Filippos Giannakos
 * set the limit of requests, a port can allocate.
1795 e06fe035 Filippos Giannakos
 *
1796 e06fe035 Filippos Giannakos
 * this limit should be greater than the number of requests a port can cache
1797 e06fe035 Filippos Giannakos
 * locally on its free_queue, and less than the hard limit imposed by the
1798 e06fe035 Filippos Giannakos
 * segment.
1799 a344287f Filippos Giannakos
 *
1800 a344287f Filippos Giannakos
 * maybe make it drop excess requests
1801 e06fe035 Filippos Giannakos
 */
1802 e06fe035 Filippos Giannakos
int xseg_set_max_requests(struct xseg *xseg, xport portno, uint64_t nr_reqs)
1803 e06fe035 Filippos Giannakos
{
1804 e06fe035 Filippos Giannakos
        int r = -1;
1805 a6600315 Filippos Giannakos
        struct xseg_port *port;
1806 a6600315 Filippos Giannakos
        struct xq *q;
1807 e06fe035 Filippos Giannakos
        if (nr_reqs > XSEG_MAX_ALLOCATED_REQS)
1808 e06fe035 Filippos Giannakos
                return -1;
1809 e06fe035 Filippos Giannakos
1810 a6600315 Filippos Giannakos
        port = xseg_get_port(xseg, portno);
1811 e06fe035 Filippos Giannakos
        if (!port)
1812 e06fe035 Filippos Giannakos
                return -1;
1813 e06fe035 Filippos Giannakos
1814 e06fe035 Filippos Giannakos
        xlock_acquire(&port->fq_lock, portno);
1815 a6600315 Filippos Giannakos
        q = XPTR_TAKE(port->free_queue, xseg->segment);
1816 e06fe035 Filippos Giannakos
        if (xq_size(q) <= nr_reqs){
1817 e06fe035 Filippos Giannakos
                port->max_alloc_reqs = nr_reqs;
1818 e06fe035 Filippos Giannakos
                r = 0;
1819 e06fe035 Filippos Giannakos
        }
1820 e06fe035 Filippos Giannakos
        xlock_release(&port->fq_lock);
1821 e06fe035 Filippos Giannakos
1822 0f944d14 Filippos Giannakos
        /* no lock here
1823 e06fe035 Filippos Giannakos
         * if theres is a get_request in progress, it is not critical to enforce
1824 e06fe035 Filippos Giannakos
         * the new limit.
1825 e06fe035 Filippos Giannakos
         */
1826 e06fe035 Filippos Giannakos
        port->max_alloc_reqs = nr_reqs;
1827 e06fe035 Filippos Giannakos
        return r;
1828 e06fe035 Filippos Giannakos
}
1829 e06fe035 Filippos Giannakos
1830 e06fe035 Filippos Giannakos
uint64_t xseg_get_max_requests(struct xseg *xseg, xport portno)
1831 e06fe035 Filippos Giannakos
{
1832 e06fe035 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1833 e06fe035 Filippos Giannakos
        if (!port)
1834 e06fe035 Filippos Giannakos
                return -1;
1835 e06fe035 Filippos Giannakos
        return port->max_alloc_reqs;
1836 e06fe035 Filippos Giannakos
}
1837 e06fe035 Filippos Giannakos
1838 e06fe035 Filippos Giannakos
uint64_t xseg_get_allocated_requests(struct xseg *xseg, xport portno)
1839 e06fe035 Filippos Giannakos
{
1840 e06fe035 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1841 e06fe035 Filippos Giannakos
        if (!port)
1842 e06fe035 Filippos Giannakos
                return -1;
1843 e06fe035 Filippos Giannakos
        return port->alloc_reqs;
1844 e06fe035 Filippos Giannakos
}
1845 e06fe035 Filippos Giannakos
1846 e06fe035 Filippos Giannakos
/*
1847 e06fe035 Filippos Giannakos
 * set free_queue size, aka the local "cached" requests a port can have
1848 e06fe035 Filippos Giannakos
 * it should be smaller than port->max_alloc_reqs?
1849 e06fe035 Filippos Giannakos
 *
1850 e06fe035 Filippos Giannakos
 */
1851 e06fe035 Filippos Giannakos
int xseg_set_freequeue_size(struct xseg *xseg, xport portno, xqindex size,
1852 e06fe035 Filippos Giannakos
                                uint32_t flags)
1853 e06fe035 Filippos Giannakos
{
1854 e06fe035 Filippos Giannakos
        int ret = 0;
1855 e06fe035 Filippos Giannakos
        xqindex xqi,r;
1856 e06fe035 Filippos Giannakos
        struct xq *q, *newq;
1857 e06fe035 Filippos Giannakos
        struct xseg_request *xreq;
1858 e06fe035 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
1859 e06fe035 Filippos Giannakos
        if (!port)
1860 e06fe035 Filippos Giannakos
                return -1;
1861 e06fe035 Filippos Giannakos
1862 e06fe035 Filippos Giannakos
        newq = __alloc_queue(xseg, size);
1863 e06fe035 Filippos Giannakos
        if (!newq)
1864 e06fe035 Filippos Giannakos
                return -1;
1865 e06fe035 Filippos Giannakos
1866 e06fe035 Filippos Giannakos
        if (flags & X_NONBLOCK) {
1867 e06fe035 Filippos Giannakos
                if (!xlock_try_lock(&port->fq_lock, portno))
1868 e06fe035 Filippos Giannakos
                        return -1;
1869 e06fe035 Filippos Giannakos
        } else {
1870 e06fe035 Filippos Giannakos
                xlock_acquire(&port->fq_lock, portno);
1871 e06fe035 Filippos Giannakos
        }
1872 e06fe035 Filippos Giannakos
1873 e06fe035 Filippos Giannakos
        q = XPTR_TAKE(port->free_queue, xseg->segment);
1874 e06fe035 Filippos Giannakos
1875 e06fe035 Filippos Giannakos
        /* put requests that don't fit in the new queue */
1876 e06fe035 Filippos Giannakos
        while (xq_count(q) > xq_size(newq)){
1877 e06fe035 Filippos Giannakos
                xqi = __xq_pop_head(q);
1878 e06fe035 Filippos Giannakos
                if (xqi != Noneidx){
1879 e06fe035 Filippos Giannakos
                        xreq = XPTR_TAKE(xqi, xseg->segment);
1880 e06fe035 Filippos Giannakos
                        xobj_put_obj(xseg->request_h, (void *) xreq);
1881 e06fe035 Filippos Giannakos
                }
1882 e06fe035 Filippos Giannakos
        }
1883 e06fe035 Filippos Giannakos
1884 e06fe035 Filippos Giannakos
        r = __xq_resize(q, newq);
1885 e06fe035 Filippos Giannakos
        if (r == Noneidx){
1886 e06fe035 Filippos Giannakos
                xheap_free(newq);
1887 e06fe035 Filippos Giannakos
                ret = -1;
1888 e06fe035 Filippos Giannakos
                goto out_rel;
1889 e06fe035 Filippos Giannakos
        }
1890 e06fe035 Filippos Giannakos
        port->free_queue = XPTR_MAKE(newq, xseg->segment);
1891 e06fe035 Filippos Giannakos
        xheap_free(q);
1892 e06fe035 Filippos Giannakos
        ret = 0;
1893 e06fe035 Filippos Giannakos
1894 e06fe035 Filippos Giannakos
out_rel:
1895 e06fe035 Filippos Giannakos
        xlock_release(&port->fq_lock);
1896 e06fe035 Filippos Giannakos
        return ret;
1897 e06fe035 Filippos Giannakos
}
1898 e06fe035 Filippos Giannakos
1899 7882a035 Filippos Giannakos
int xseg_leave_port(struct xseg *xseg, struct xseg_port *port)
1900 7882a035 Filippos Giannakos
{
1901 7882a035 Filippos Giannakos
        /* To be implemented */
1902 7882a035 Filippos Giannakos
        return -1;
1903 7882a035 Filippos Giannakos
}
1904 7882a035 Filippos Giannakos
1905 6e0a3771 Georgios D. Tsoukalas
int xseg_initialize(void)
1906 6d486cc0 Georgios D. Tsoukalas
{
1907 6e0a3771 Georgios D. Tsoukalas
        return __xseg_preinit();        /* with or without lock ? */
1908 6e0a3771 Georgios D. Tsoukalas
}
1909 6d486cc0 Georgios D. Tsoukalas
1910 6e0a3771 Georgios D. Tsoukalas
int xseg_finalize(void)
1911 6e0a3771 Georgios D. Tsoukalas
{
1912 6e0a3771 Georgios D. Tsoukalas
        /* finalize not supported yet */
1913 6e0a3771 Georgios D. Tsoukalas
        return -1;
1914 6d486cc0 Georgios D. Tsoukalas
}
1915 6d486cc0 Georgios D. Tsoukalas
1916 4494b184 Filippos Giannakos
1917 bc1e3fc8 Filippos Giannakos
char* xseg_get_data_nonstatic(struct xseg* xseg, struct xseg_request *req)
1918 bc1e3fc8 Filippos Giannakos
{
1919 bc1e3fc8 Filippos Giannakos
        return xseg_get_data(xseg, req);
1920 bc1e3fc8 Filippos Giannakos
}
1921 bc1e3fc8 Filippos Giannakos
1922 bc1e3fc8 Filippos Giannakos
char* xseg_get_target_nonstatic(struct xseg* xseg, struct xseg_request *req)
1923 bc1e3fc8 Filippos Giannakos
{
1924 bc1e3fc8 Filippos Giannakos
        return xseg_get_target(xseg, req);
1925 bc1e3fc8 Filippos Giannakos
}
1926 bc1e3fc8 Filippos Giannakos
1927 8cbf5379 Filippos Giannakos
void* xseg_get_signal_desc_nonstatic(struct xseg *xseg, struct xseg_port *port)
1928 8cbf5379 Filippos Giannakos
{
1929 8cbf5379 Filippos Giannakos
        return xseg_get_signal_desc(xseg, port);
1930 8cbf5379 Filippos Giannakos
}
1931 bc1e3fc8 Filippos Giannakos
1932 0f944d14 Filippos Giannakos
uint32_t xseg_portno_nonstatic(struct xseg *xseg, struct xseg_port *port)
1933 0f944d14 Filippos Giannakos
{
1934 0f944d14 Filippos Giannakos
        return xseg_portno(xseg, port);
1935 0f944d14 Filippos Giannakos
}
1936 0f944d14 Filippos Giannakos
1937 0f944d14 Filippos Giannakos
1938 6d486cc0 Georgios D. Tsoukalas
#ifdef __KERNEL__
1939 6d486cc0 Georgios D. Tsoukalas
#include <linux/module.h>
1940 6d486cc0 Georgios D. Tsoukalas
#include <xseg/xseg_exports.h>
1941 6d486cc0 Georgios D. Tsoukalas
#endif