Statistics
| Branch: | Revision:

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