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