Statistics
| Branch: | Revision:

root / src / include / xseg / xseg.h @ 9f38e25a

History | View | Annotate | Download (17.7 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

    
231
/* REQ FLAGS */
232
#define XF_NOSYNC    (1 << 0)
233
#define XF_FLUSH     (1 << 1)
234
#define XF_FUA       (1 << 2)
235
#define XF_FORCE     (1 << 3)
236
#define XF_CONTADDR  (1 << 4)
237

    
238
/* PORT FLAGS */
239

    
240
#define CAN_ACCEPT   (1 << 0)
241
#define CAN_RECEIVE  (1 << 1)
242

    
243
/* STATES */
244
#define XS_SERVED        (1 << 0)
245
#define XS_FAILED        (1 << 1)
246

    
247
#define XS_ACCEPTED        (1 << 2)
248
#define XS_PENDING        (2 << 2)
249
#define XS_SERVING        (3 << 2)
250
#define XS_CONCLUDED        (3 << 2)
251

    
252
struct xseg_request {
253
        xserial serial;
254
        uint64_t offset;
255
        uint64_t size; 
256
        uint64_t serviced;
257
        xptr data;
258
        uint64_t datalen;
259
        xptr target;
260
        uint32_t targetlen;
261
        uint32_t op;
262
        volatile uint32_t state;
263
        uint32_t flags;
264
        xport src_portno;
265
        xport transit_portno;
266
        xport dst_portno;
267
        xport effective_dst_portno;
268
        struct xq path;
269
        xqindex path_bufs[MAX_PATH_LEN];
270
        /* pad */
271
        xptr buffer;
272
        uint64_t bufferlen;
273
        xqindex task;
274
        uint64_t priv;
275
        struct timeval timestamp;
276
        uint64_t elapsed;
277
};
278

    
279
struct xseg_shared {
280
        uint64_t flags;
281
        char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */
282
        xptr *peer_type_data;
283
        uint32_t nr_peer_types;
284
};
285

    
286
struct xseg_private {
287
        struct xseg_type segment_type;
288
        struct xseg_peer peer_type;
289
        struct xseg_peer **peer_types;
290
        void **peer_type_data;
291
        uint32_t max_peer_types;
292
        void (*wakeup)(uint32_t portno);
293
        xhash_t *req_data;
294
        struct xlock reqdatalock;
295
};
296

    
297
struct xseg_counters {
298
        uint64_t avg_req_lat;
299
        uint64_t req_cnt;
300
};
301

    
302
struct xseg {
303
        uint64_t version;
304
        uint64_t segment_size;
305
        struct xseg *segment;
306
        struct xheap *heap;
307
        struct xobject_h *object_handlers;
308

    
309
        struct xobject_h *request_h;
310
        struct xobject_h *port_h;
311
        xptr *ports;
312
        xport *path_next, *dst_gw;
313

    
314
        struct xseg_shared *shared;
315
        struct xseg_private *priv;
316
        uint32_t max_peer_types;
317
        struct xseg_config config;
318
        struct xseg_counters counters;
319
};
320

    
321
#define XSEG_F_LOCK 0x1
322

    
323
/* ================= XSEG REQUEST INTERFACE ================================= */
324
/*                     ___________________                         _________  */
325
/*                    /                   \                       /         \ */
326
                int    xseg_initialize      ( void                            );
327

    
328
                int    xseg_finalize        ( void                            );
329

    
330
                int    xseg_parse_spec      ( char                * spec,
331
                                              struct xseg_config  * config    );
332

    
333
   struct xseg_port *  xseg_bind_port       ( struct xseg         * xseg,
334
                                              uint32_t              portno,
335
                                              void                  * sd        );
336

    
337
    static uint32_t    xseg_portno          ( struct xseg         * xseg,
338
                                              struct xseg_port    * port      );
339
/*                    \___________________/                       \_________/ */
340
/*                     ___________________                         _________  */
341
/*                    /                   \                       /         \ */
342
                int    xseg_register_type   ( struct xseg_type    * type      );
343
                int    xseg_unregister_type ( const char          * name      );
344

    
345
                int    xseg_register_peer   ( struct xseg_peer    * peer      );
346
                int    xseg_unregister_peer ( const char          * name      );
347

    
348
               void    xseg_report_peer_types( void );
349

    
350
            int64_t    xseg_enable_driver   ( struct xseg         * xseg,
351
                                              const char          * name      );
352
                int    xseg_disable_driver  ( struct xseg         * xseg,
353
                                              const char          * name      );
354
/*                    \___________________/                       \_________/ */
355
/*                     ___________________                         _________  */
356
/*                    /                   \                       /         \ */
357
                int    xseg_create          ( struct xseg_config  * cfg       );
358

    
359
               void    xseg_destroy         ( struct xseg         * xseg      );
360
/*                    \___________________/                       \_________/ */
361
/*                     ___________________                         _________  */
362
/*                    /                   \                       /         \ */
363
        struct xseg *  xseg_join            ( char                * segtype,
364
                                              char                * segname,
365
                                              char                * peertype,
366
                                              void               (* wakeup    )
367
                                             (uint32_t              portno   ));
368

    
369
               void    xseg_leave           ( struct xseg         * xseg      );
370
/*                    \___________________/                       \_________/ */
371
/*                     ___________________                         _________  */
372
/*                    /                   \                       /         \ */
373
                int    xseg_alloc_requests  ( struct xseg         * xseg,
374
                                              uint32_t              portno,
375
                                              uint32_t              nr        );
376

    
377
                int    xseg_free_requests   ( struct xseg         * xseg,
378
                                              uint32_t              portno,
379
                                              int                   nr        );
380

    
381
struct xseg_request *  xseg_get_request     ( struct xseg         * xseg,
382
                                              xport                 src_portno,
383
                                              xport                 dst_portno,
384
                                              uint32_t              flags     );
385

    
386
                int    xseg_put_request     ( struct xseg         * xseg,
387
                                              struct xseg_request * xreq,
388
                                              xport                 portno    );
389

    
390
                int    xseg_prep_request    ( struct xseg          * xseg,
391
                                              struct xseg_request * xreq,
392
                                              uint32_t              targetlen,
393
                                              uint64_t              datalen  );
394
/*                    \___________________/                       \_________/ */
395
/*                     ___________________                         _________  */
396
/*                    /                   \                       /         \ */
397
              xport    xseg_submit          ( struct xseg         * xseg,
398
                                              struct xseg_request * xreq,      
399
                                              xport                 portno,
400
                                              uint32_t              flags     );
401

    
402
struct xseg_request *  xseg_receive         ( struct xseg         * xseg,
403
                                              xport                 portno,    
404
                                              uint32_t                    flags     );
405
/*                    \___________________/                       \_________/ */
406
/*                     ___________________                         _________  */
407
/*                    /                   \                       /         \ */
408

    
409
struct xseg_request *  xseg_accept          ( struct xseg         * xseg,
410
                                              xport                 portno,    
411
                                              uint32_t                    flags     );
412

    
413
              xport    xseg_respond         ( struct xseg         * xseg,
414
                                              struct xseg_request * xreq,
415
                                              xport                 portno,
416
                                              uint32_t              flags     );
417
/*                    \___________________/                       \_________/ */
418
/*                     ___________________                         _________  */
419
/*                    /                   \                       /         \ */
420
                int    xseg_prepare_wait    ( struct xseg         * xseg,
421
                                              uint32_t              portno    );
422

    
423
                int    xseg_cancel_wait     ( struct xseg         * xseg,
424
                                              uint32_t              portno    );
425

    
426
                int    xseg_wait_signal     ( struct xseg         * xseg,
427
                                              void                   * sd,
428
                                              uint32_t              utimeout  );
429

    
430
                int    xseg_signal          ( struct xseg         * xseg,
431
                                              uint32_t              portno    );
432
/*                    \___________________/                       \_________/ */
433

    
434

    
435

    
436
/*                                                                            */
437
/* ================= XSEG REQUEST INTERFACE ================================= */
438

    
439
struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno);
440

    
441

    
442
extern char* xseg_get_data_nonstatic(struct xseg* xseg, struct xseg_request *req);
443
extern char* xseg_get_target_nonstatic(struct xseg* xseg, struct xseg_request *req);
444
extern void* xseg_get_signal_desc_nonstatic(struct xseg *xseg, struct xseg_port *port);
445

    
446
static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port)
447
{
448
        return port->portno;
449
}
450
static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req)
451
{
452
        return (char *) XPTR_TAKE(req->target, xseg->segment);
453
}
454

    
455
static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req)
456
{
457
        return (char *) XPTR_TAKE(req->data, xseg->segment);
458
}
459

    
460
static inline void * xseg_get_signal_desc(struct xseg *xseg, struct xseg_port *port)
461
{
462
        return (void *) XPTR_TAKE(port->signal_desc, xseg->segment);
463
}
464

    
465
struct xobject_h * xseg_get_objh(struct xseg *xseg, uint32_t magic, uint64_t size);
466
void xseg_put_objh(struct xseg *xseg, struct xobject_h *objh);
467

    
468
#define xseg_get_queue(__xseg, __port, __queue) \
469
        ((struct xq *) XPTR_TAKE(__port->__queue, __xseg->segment))
470

    
471

    
472
int xseg_set_path_next(struct xseg *xseg, xport portno, xport next);
473

    
474
int xseg_set_req_data(struct xseg *xseg, struct xseg_request *xreq, void *data);
475
int xseg_get_req_data(struct xseg *xseg, struct xseg_request *xreq, void **data);
476

    
477
int xseg_init_local_signal(struct xseg *xseg, xport portno);
478
void xseg_quit_local_signal(struct xseg *xseg, xport portno);
479

    
480
int xseg_resize_request (struct xseg *xseg, struct xseg_request *req,
481
                        uint32_t new_targetlen, uint64_t new_datalen);
482

    
483
int xseg_set_max_requests(struct xseg *xseg, xport portno, uint64_t nr_reqs);
484
uint64_t xseg_get_max_requests(struct xseg *xseg, xport portno);
485
uint64_t xseg_get_allocated_requests(struct xseg *xseg, xport portno);
486
int xseg_set_freequeue_size(struct xseg *xseg, xport portno, xqindex size,
487
                                uint32_t flags);
488

    
489
xport xseg_forward(struct xseg *xseg, struct xseg_request *req, xport new_dst,
490
                xport portno, uint32_t flags);
491

    
492
struct xseg_port *xseg_bind_dynport(struct xseg *xseg);
493
int xseg_leave_dynport(struct xseg *xseg, struct xseg_port *port);
494
extern uint32_t xseg_portno_nonstatic(struct xseg *xseg, struct xseg_port *port);
495
#endif