root / src / include / xseg / xseg.h @ 41b5e6c5
History | View | Annotate | Download (17.8 kB)
1 |
/*
|
---|---|
2 |
* Copyright 2012 GRNET S.A. All rights reserved.
|
3 |
*
|
4 |
* Redistribution and use in source and binary forms, with or
|
5 |
* without modification, are permitted provided that the following
|
6 |
* conditions are met:
|
7 |
*
|
8 |
* 1. Redistributions of source code must retain the above
|
9 |
* copyright notice, this list of conditions and the following
|
10 |
* disclaimer.
|
11 |
* 2. Redistributions in binary form must reproduce the above
|
12 |
* copyright notice, this list of conditions and the following
|
13 |
* disclaimer in the documentation and/or other materials
|
14 |
* provided with the distribution.
|
15 |
*
|
16 |
* THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 |
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 |
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 |
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 |
* POSSIBILITY OF SUCH DAMAGE.
|
28 |
*
|
29 |
* The views and conclusions contained in the software and
|
30 |
* documentation are those of the authors and should not be
|
31 |
* interpreted as representing official policies, either expressed
|
32 |
* or implied, of GRNET S.A.
|
33 |
*/
|
34 |
|
35 |
#ifndef _XSEG_H
|
36 |
#define _XSEG_H
|
37 |
|
38 |
#ifndef XSEG_PAGE_SHIFT
|
39 |
#define XSEG_PAGE_SHIFT 12 |
40 |
#endif
|
41 |
|
42 |
#define XSEG_BASE (0x37fd0UL << XSEG_PAGE_SHIFT) |
43 |
#define XSEG_BASE_AS_PTR ((void *)XSEG_BASE) |
44 |
#define XSEG_BASE_AS_BUF ((char *)XSEG_BASE) |
45 |
#define XSEG_OFFSET(base, ptr) ((unsigned long)(ptr) - (unsigned long)(base)) |
46 |
#define XSEG_PTR_CONVERT(ptr, src, dst) ((void *)((unsigned long)(dst) + XSEG_OFFSET(src, ptr))) |
47 |
#define XSEG_TAKE_PTR(ptr, base) XSEG_PTR_CONVERT(ptr, XSEG_BASE, base)
|
48 |
#define XSEG_MAKE_PTR(ptr, base) XSEG_PTR_CONVERT(ptr, base, XSEG_BASE)
|
49 |
|
50 |
#include <stdint.h> |
51 |
#include <sys/time.h> |
52 |
#include <xseg/version.h> |
53 |
#include <xseg/util.h> |
54 |
#include <xseg/xq.h> |
55 |
#include <xseg/xobj.h> |
56 |
#include <xseg/xhash.h> |
57 |
#include <xseg/xpool.h> |
58 |
|
59 |
typedef uint64_t xserial;
|
60 |
typedef uint32_t xport;
|
61 |
|
62 |
#define NoSerial ((xserial)-1) |
63 |
#define NoPort ((xport) -1) |
64 |
|
65 |
#ifndef XSEG_DEF_REQS
|
66 |
#define XSEG_DEF_REQS 256 |
67 |
#endif
|
68 |
|
69 |
#ifndef XSEG_DEF_MAX_ALLOCATED_REQS
|
70 |
#define XSEG_DEF_MAX_ALLOCATED_REQS 1024 |
71 |
#endif
|
72 |
|
73 |
/* hard limit on max allocated requests per port */
|
74 |
//FIXME make this a dynamicly calculated value based
|
75 |
//on heap_size and request_h->size
|
76 |
#ifndef XSEG_MAX_ALLOCATED_REQS
|
77 |
#define XSEG_MAX_ALLOCATED_REQS 10000 |
78 |
#endif
|
79 |
|
80 |
#if XSEG_DEF_MAX_ALLOCATED_REQS > XSEG_MAX_ALLOCATED_REQS
|
81 |
#error "XSEG_DEF_MAX_ALLOCATED_REQS should be less than XSEG_MAX_ALLOCATED_REQS" |
82 |
#endif
|
83 |
|
84 |
#if XSEG_DEF_REQS > XSEG_MAX_ALLOCATED_REQS
|
85 |
#error "XSEG_DEF_REQS should me less than XSEG_MAX_ALLOCATED_REQS" |
86 |
#endif
|
87 |
|
88 |
#ifndef MAX_PATH_LEN
|
89 |
#define MAX_PATH_LEN 32 |
90 |
#endif
|
91 |
|
92 |
#define XSEG_NAMESIZE 256 |
93 |
#define XSEG_TNAMESIZE 32 |
94 |
|
95 |
/* Peers and Segments
|
96 |
*
|
97 |
* Segments are memory segments shared among peers.
|
98 |
* Peers are local execution contexes that share a segment.
|
99 |
*
|
100 |
* xseg_type and xseg_peer
|
101 |
*
|
102 |
* A peer needs an xseg_type in order to
|
103 |
* create or access a certain segment type,
|
104 |
* and it needs an xseg_peer in order to
|
105 |
* communicate with a certain type of peer.
|
106 |
* Both segment and peer types are identified by name strings.
|
107 |
*
|
108 |
* Note that each peer (that is, context) type will need
|
109 |
* different code to access the same type of segment or peer.
|
110 |
* Therefore each peer must have its own "customized" version
|
111 |
* of the xseg library.
|
112 |
*
|
113 |
* This is accomplished by mechanisms for registering both
|
114 |
* xseg_type's and xseg_peer's. This can be done at both at build time
|
115 |
* and at runtime, through a plugin-loading mechanism (where applicable).
|
116 |
* The plugin namespace serves both segment and peer type namespace,
|
117 |
* so if a segment type has the same name with a peer type,
|
118 |
* they must be provided by the same plugin.
|
119 |
*
|
120 |
* Note also that peers of different types may share the same segment.
|
121 |
* Therefore each peer must know the type of each peer it needs to
|
122 |
* communicate with, and have a driver for it.
|
123 |
*
|
124 |
*/
|
125 |
|
126 |
struct xseg;
|
127 |
struct xseg_port;
|
128 |
|
129 |
#define XSEG_MAGIC (0xcafe0000) |
130 |
#define MAGIC_OBJH (XSEG_MAGIC | 1) |
131 |
#define MAGIC_REQ (XSEG_MAGIC | 2) |
132 |
#define MAGIC_PORT (XSEG_MAGIC | 3) |
133 |
|
134 |
struct xseg_operations {
|
135 |
void (*mfree)(void *mem); |
136 |
long (*allocate)(const char *name, uint64_t size); |
137 |
long (*deallocate)(const char *name); |
138 |
void *(*map)(const char *name, uint64_t size, struct xseg *seg); |
139 |
void (*unmap)(void *xseg, uint64_t size); |
140 |
}; |
141 |
|
142 |
struct xseg_type {
|
143 |
struct xseg_operations ops;
|
144 |
char name[XSEG_TNAMESIZE];
|
145 |
}; |
146 |
|
147 |
|
148 |
struct xseg_peer_operations {
|
149 |
int (*init_signal_desc)(struct xseg *xseg, void *sd); |
150 |
void (*quit_signal_desc)(struct xseg *xseg, void *sd); |
151 |
void *(*alloc_data)(struct xseg *xseg); |
152 |
void (*free_data)(struct xseg *xseg, void *data); |
153 |
void *(*alloc_signal_desc)(struct xseg *xseg, void *data); |
154 |
void (*free_signal_desc)(struct xseg *xseg, void *data, void *sd); |
155 |
int (*local_signal_init)(struct xseg *xseg, xport portno); |
156 |
void (*local_signal_quit)(struct xseg *xseg, xport portno); |
157 |
int (*remote_signal_init)(void); |
158 |
void (*remote_signal_quit)(void); |
159 |
int (*signal_join)(struct xseg *xseg); |
160 |
int (*signal_leave)(struct xseg *xseg); |
161 |
int (*prepare_wait)(struct xseg *xseg, uint32_t portno); |
162 |
int (*cancel_wait)(struct xseg *xseg, uint32_t portno); |
163 |
int (*wait_signal)(struct xseg *xseg, void *sd, uint32_t usec_timeout); |
164 |
int (*signal)(struct xseg *xseg, uint32_t portno); |
165 |
void *(*malloc)(uint64_t size);
|
166 |
void *(*realloc)(void *mem, uint64_t size); |
167 |
void (*mfree)(void *mem); |
168 |
}; |
169 |
|
170 |
struct xseg_peer {
|
171 |
struct xseg_peer_operations peer_ops;
|
172 |
char name[XSEG_TNAMESIZE];
|
173 |
}; |
174 |
|
175 |
struct xseg_config {
|
176 |
uint64_t heap_size; /* heap size in MB */
|
177 |
uint32_t nr_ports; |
178 |
uint32_t dynports; |
179 |
uint32_t page_shift; /* the alignment unit */
|
180 |
char type[XSEG_TNAMESIZE]; /* zero-terminated identifier */ |
181 |
char name[XSEG_NAMESIZE]; /* zero-terminated identifier */ |
182 |
}; |
183 |
|
184 |
struct xseg_port {
|
185 |
struct xlock fq_lock;
|
186 |
struct xlock rq_lock;
|
187 |
struct xlock pq_lock;
|
188 |
xptr free_queue; |
189 |
xptr request_queue; |
190 |
xptr reply_queue; |
191 |
uint64_t owner; |
192 |
uint64_t peer_type; |
193 |
uint32_t portno; |
194 |
uint64_t max_alloc_reqs; |
195 |
uint64_t alloc_reqs; |
196 |
struct xlock port_lock;
|
197 |
xptr signal_desc; |
198 |
uint32_t flags; |
199 |
}; |
200 |
|
201 |
struct xseg_request;
|
202 |
|
203 |
struct xseg_task {
|
204 |
uint64_t epoch; |
205 |
struct xseg_request *req;
|
206 |
xqindex *deps; |
207 |
xqindex nr_deps; |
208 |
xqindex __alloced_deps; |
209 |
}; |
210 |
|
211 |
/* OPS */
|
212 |
#define X_PING 0 |
213 |
#define X_READ 1 |
214 |
#define X_WRITE 2 |
215 |
#define X_SYNC 3 |
216 |
#define X_TRUNCATE 4 |
217 |
#define X_DELETE 5 |
218 |
#define X_ACQUIRE 6 |
219 |
#define X_RELEASE 7 |
220 |
#define X_COPY 8 |
221 |
#define X_CLONE 9 |
222 |
#define X_COMMIT 10 |
223 |
#define X_INFO 11 |
224 |
#define X_MAPR 12 |
225 |
#define X_MAPW 13 |
226 |
#define X_OPEN 14 |
227 |
#define X_CLOSE 15 |
228 |
#define X_SNAPSHOT 16 |
229 |
#define X_HASH 17 |
230 |
#define X_CREATE 18 |
231 |
|
232 |
/* REQ FLAGS */
|
233 |
#define XF_NOSYNC (1 << 0) |
234 |
#define XF_FLUSH (1 << 1) |
235 |
#define XF_FUA (1 << 2) |
236 |
#define XF_FORCE (1 << 3) |
237 |
#define XF_CONTADDR (1 << 4) |
238 |
|
239 |
/* PORT FLAGS */
|
240 |
|
241 |
#define CAN_ACCEPT (1 << 0) |
242 |
#define CAN_RECEIVE (1 << 1) |
243 |
|
244 |
/* STATES */
|
245 |
#define XS_SERVED (1 << 0) |
246 |
#define XS_FAILED (1 << 1) |
247 |
|
248 |
#define XS_ACCEPTED (1 << 2) |
249 |
#define XS_PENDING (2 << 2) |
250 |
#define XS_SERVING (3 << 2) |
251 |
#define XS_CONCLUDED (3 << 2) |
252 |
|
253 |
struct xseg_request {
|
254 |
xserial serial; |
255 |
uint64_t offset; |
256 |
uint64_t size; |
257 |
uint64_t serviced; |
258 |
uint64_t contaddr_size; |
259 |
xptr data; |
260 |
uint64_t datalen; |
261 |
xptr target; |
262 |
uint32_t targetlen; |
263 |
uint32_t op; |
264 |
volatile uint32_t state;
|
265 |
uint32_t flags; |
266 |
xport src_portno; |
267 |
xport transit_portno; |
268 |
xport dst_portno; |
269 |
xport effective_dst_portno; |
270 |
struct xq path;
|
271 |
xqindex path_bufs[MAX_PATH_LEN]; |
272 |
/* pad */
|
273 |
xptr buffer; |
274 |
uint64_t bufferlen; |
275 |
xqindex task; |
276 |
uint64_t priv; |
277 |
struct timeval timestamp;
|
278 |
uint64_t elapsed; |
279 |
}; |
280 |
|
281 |
struct xseg_shared {
|
282 |
uint64_t flags; |
283 |
char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */ |
284 |
xptr *peer_type_data; |
285 |
uint32_t nr_peer_types; |
286 |
}; |
287 |
|
288 |
struct xseg_private {
|
289 |
struct xseg_type segment_type;
|
290 |
struct xseg_peer peer_type;
|
291 |
struct xseg_peer **peer_types;
|
292 |
void **peer_type_data;
|
293 |
uint32_t max_peer_types; |
294 |
void (*wakeup)(uint32_t portno);
|
295 |
xhash_t *req_data; |
296 |
struct xlock reqdatalock;
|
297 |
}; |
298 |
|
299 |
struct xseg_counters {
|
300 |
uint64_t avg_req_lat; |
301 |
uint64_t req_cnt; |
302 |
}; |
303 |
|
304 |
struct xseg {
|
305 |
uint64_t version; |
306 |
uint64_t segment_size; |
307 |
struct xseg *segment;
|
308 |
struct xheap *heap;
|
309 |
struct xobject_h *object_handlers;
|
310 |
|
311 |
struct xobject_h *request_h;
|
312 |
struct xobject_h *port_h;
|
313 |
xptr *ports; |
314 |
xport *path_next, *dst_gw; |
315 |
|
316 |
struct xseg_shared *shared;
|
317 |
struct xseg_private *priv;
|
318 |
uint32_t max_peer_types; |
319 |
struct xseg_config config;
|
320 |
struct xseg_counters counters;
|
321 |
}; |
322 |
|
323 |
#define XSEG_F_LOCK 0x1 |
324 |
|
325 |
/* ================= XSEG REQUEST INTERFACE ================================= */
|
326 |
/* ___________________ _________ */
|
327 |
/* / \ / \ */
|
328 |
int xseg_initialize ( void ); |
329 |
|
330 |
int xseg_finalize ( void ); |
331 |
|
332 |
int xseg_parse_spec ( char * spec, |
333 |
struct xseg_config * config );
|
334 |
|
335 |
struct xseg_port * xseg_bind_port ( struct xseg * xseg, |
336 |
uint32_t portno, |
337 |
void * sd );
|
338 |
|
339 |
static uint32_t xseg_portno ( struct xseg * xseg, |
340 |
struct xseg_port * port );
|
341 |
/* \___________________/ \_________/ */
|
342 |
/* ___________________ _________ */
|
343 |
/* / \ / \ */
|
344 |
int xseg_register_type ( struct xseg_type * type ); |
345 |
int xseg_unregister_type ( const char * name ); |
346 |
|
347 |
int xseg_register_peer ( struct xseg_peer * peer ); |
348 |
int xseg_unregister_peer ( const char * name ); |
349 |
|
350 |
void xseg_report_peer_types( void ); |
351 |
|
352 |
int64_t xseg_enable_driver ( struct xseg * xseg,
|
353 |
const char * name ); |
354 |
int xseg_disable_driver ( struct xseg * xseg, |
355 |
const char * name ); |
356 |
/* \___________________/ \_________/ */
|
357 |
/* ___________________ _________ */
|
358 |
/* / \ / \ */
|
359 |
int xseg_create ( struct xseg_config * cfg ); |
360 |
|
361 |
void xseg_destroy ( struct xseg * xseg ); |
362 |
/* \___________________/ \_________/ */
|
363 |
/* ___________________ _________ */
|
364 |
/* / \ / \ */
|
365 |
struct xseg * xseg_join ( char * segtype, |
366 |
char * segname,
|
367 |
char * peertype,
|
368 |
void (* wakeup )
|
369 |
(uint32_t portno )); |
370 |
|
371 |
void xseg_leave ( struct xseg * xseg ); |
372 |
/* \___________________/ \_________/ */
|
373 |
/* ___________________ _________ */
|
374 |
/* / \ / \ */
|
375 |
int xseg_alloc_requests ( struct xseg * xseg, |
376 |
uint32_t portno, |
377 |
uint32_t nr ); |
378 |
|
379 |
int xseg_free_requests ( struct xseg * xseg, |
380 |
uint32_t portno, |
381 |
int nr );
|
382 |
|
383 |
struct xseg_request * xseg_get_request ( struct xseg * xseg, |
384 |
xport src_portno, |
385 |
xport dst_portno, |
386 |
uint32_t flags ); |
387 |
|
388 |
int xseg_put_request ( struct xseg * xseg, |
389 |
struct xseg_request * xreq,
|
390 |
xport portno ); |
391 |
|
392 |
int xseg_prep_request ( struct xseg * xseg, |
393 |
struct xseg_request * xreq,
|
394 |
uint32_t targetlen, |
395 |
uint64_t datalen ); |
396 |
/* \___________________/ \_________/ */
|
397 |
/* ___________________ _________ */
|
398 |
/* / \ / \ */
|
399 |
xport xseg_submit ( struct xseg * xseg,
|
400 |
struct xseg_request * xreq,
|
401 |
xport portno, |
402 |
uint32_t flags ); |
403 |
|
404 |
struct xseg_request * xseg_receive ( struct xseg * xseg, |
405 |
xport portno, |
406 |
uint32_t flags ); |
407 |
/* \___________________/ \_________/ */
|
408 |
/* ___________________ _________ */
|
409 |
/* / \ / \ */
|
410 |
|
411 |
struct xseg_request * xseg_accept ( struct xseg * xseg, |
412 |
xport portno, |
413 |
uint32_t flags ); |
414 |
|
415 |
xport xseg_respond ( struct xseg * xseg,
|
416 |
struct xseg_request * xreq,
|
417 |
xport portno, |
418 |
uint32_t flags ); |
419 |
/* \___________________/ \_________/ */
|
420 |
/* ___________________ _________ */
|
421 |
/* / \ / \ */
|
422 |
int xseg_prepare_wait ( struct xseg * xseg, |
423 |
uint32_t portno ); |
424 |
|
425 |
int xseg_cancel_wait ( struct xseg * xseg, |
426 |
uint32_t portno ); |
427 |
|
428 |
int xseg_wait_signal ( struct xseg * xseg, |
429 |
void * sd,
|
430 |
uint32_t utimeout ); |
431 |
|
432 |
int xseg_signal ( struct xseg * xseg, |
433 |
uint32_t portno ); |
434 |
/* \___________________/ \_________/ */
|
435 |
|
436 |
|
437 |
|
438 |
/* */
|
439 |
/* ================= XSEG REQUEST INTERFACE ================================= */
|
440 |
|
441 |
struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno); |
442 |
|
443 |
|
444 |
extern char* xseg_get_data_nonstatic(struct xseg* xseg, struct xseg_request *req); |
445 |
extern char* xseg_get_target_nonstatic(struct xseg* xseg, struct xseg_request *req); |
446 |
extern void* xseg_get_signal_desc_nonstatic(struct xseg *xseg, struct xseg_port *port); |
447 |
|
448 |
static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port) |
449 |
{ |
450 |
return port->portno;
|
451 |
} |
452 |
static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req) |
453 |
{ |
454 |
return (char *) XPTR_TAKE(req->target, xseg->segment); |
455 |
} |
456 |
|
457 |
static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req) |
458 |
{ |
459 |
return (char *) XPTR_TAKE(req->data, xseg->segment); |
460 |
} |
461 |
|
462 |
static inline void * xseg_get_signal_desc(struct xseg *xseg, struct xseg_port *port) |
463 |
{ |
464 |
return (void *) XPTR_TAKE(port->signal_desc, xseg->segment); |
465 |
} |
466 |
|
467 |
struct xobject_h * xseg_get_objh(struct xseg *xseg, uint32_t magic, uint64_t size); |
468 |
void xseg_put_objh(struct xseg *xseg, struct xobject_h *objh); |
469 |
|
470 |
#define xseg_get_queue(__xseg, __port, __queue) \
|
471 |
((struct xq *) XPTR_TAKE(__port->__queue, __xseg->segment))
|
472 |
|
473 |
|
474 |
int xseg_set_path_next(struct xseg *xseg, xport portno, xport next); |
475 |
|
476 |
int xseg_set_req_data(struct xseg *xseg, struct xseg_request *xreq, void *data); |
477 |
int xseg_get_req_data(struct xseg *xseg, struct xseg_request *xreq, void **data); |
478 |
|
479 |
int xseg_init_local_signal(struct xseg *xseg, xport portno); |
480 |
void xseg_quit_local_signal(struct xseg *xseg, xport portno); |
481 |
|
482 |
int xseg_resize_request (struct xseg *xseg, struct xseg_request *req, |
483 |
uint32_t new_targetlen, uint64_t new_datalen); |
484 |
|
485 |
int xseg_set_max_requests(struct xseg *xseg, xport portno, uint64_t nr_reqs); |
486 |
uint64_t xseg_get_max_requests(struct xseg *xseg, xport portno);
|
487 |
uint64_t xseg_get_allocated_requests(struct xseg *xseg, xport portno);
|
488 |
int xseg_set_freequeue_size(struct xseg *xseg, xport portno, xqindex size, |
489 |
uint32_t flags); |
490 |
|
491 |
xport xseg_forward(struct xseg *xseg, struct xseg_request *req, xport new_dst, |
492 |
xport portno, uint32_t flags); |
493 |
|
494 |
struct xseg_port *xseg_bind_dynport(struct xseg *xseg); |
495 |
int xseg_leave_dynport(struct xseg *xseg, struct xseg_port *port); |
496 |
extern uint32_t xseg_portno_nonstatic(struct xseg *xseg, struct xseg_port *port); |
497 |
#endif
|