5 #define XSEG_VERSION 2012022601
8 #ifndef XSEG_PAGE_SHIFT
9 #define XSEG_PAGE_SHIFT 12
12 #define XSEG_BASE (0x37fd0UL << XSEG_PAGE_SHIFT)
13 #define XSEG_BASE_AS_PTR ((void *)XSEG_BASE)
14 #define XSEG_BASE_AS_BUF ((char *)XSEG_BASE)
15 #define XSEG_OFFSET(base, ptr) ((unsigned long)(ptr) - (unsigned long)(base))
16 #define XSEG_PTR_CONVERT(ptr, src, dst) ((void *)((unsigned long)(dst) + XSEG_OFFSET(src, ptr)))
17 #define XSEG_TAKE_PTR(ptr, base) XSEG_PTR_CONVERT(ptr, XSEG_BASE, base)
18 #define XSEG_MAKE_PTR(ptr, base) XSEG_PTR_CONVERT(ptr, base, XSEG_BASE)
21 #include <xtypes/xq.h>
22 #include <xtypes/xobj.h>
23 #include <xtypes/xhash.h>
25 typedef uint64_t xserial;
27 #define NoSerial ((xserial)-1)
30 #define XSEG_DEF_REQS 512
35 * Segments are memory segments shared among peers.
36 * Peers are local execution contexes that share a segment.
38 * xseg_type and xseg_peer
40 * A peer needs an xseg_type in order to
41 * create or access a certain segment type,
42 * and it needs an xseg_peer in order to
43 * communicate with a certain type of peer.
44 * Both segment and peer types are identified by name strings.
46 * Note that each peer (that is, context) type will need
47 * different code to access the same type of segment or peer.
48 * Therefore each peer must have its own "customized" version
49 * of the xseg library.
51 * This is accomplished by mechanisms for registering both
52 * xseg_type's and xseg_peer's. This can be done at both at build time
53 * and at runtime, through a plugin-loading mechanism (where applicable).
54 * The plugin namespace serves both segment and peer type namespace,
55 * so if a segment type has the same name with a peer type,
56 * they must be provided by the same plugin.
58 * Note also that peers of different types may share the same segment.
59 * Therefore each peer must know the type of each peer it needs to
60 * communicate with, and have a driver for it.
71 struct xseg_operations {
72 void (*mfree)(void *mem);
73 long (*allocate)(const char *name, uint64_t size);
74 long (*deallocate)(const char *name);
75 void *(*map)(const char *name, uint64_t size, struct xseg *seg);
76 void (*unmap)(void *xseg, uint64_t size);
79 #define XSEG_NAMESIZE 256
80 #define XSEG_TNAMESIZE 32
83 struct xseg_operations ops;
84 char name[XSEG_TNAMESIZE];
87 struct xseg_peer_operations {
88 int (*signal_init)(void);
89 void (*signal_quit)(void);
90 int (*signal_join)(struct xseg *xseg);
91 int (*signal_leave)(struct xseg *xseg);
92 int (*prepare_wait)(struct xseg *xseg, uint32_t portno);
93 int (*cancel_wait)(struct xseg *xseg, uint32_t portno);
94 int (*wait_signal)(struct xseg *xseg, uint32_t usec_timeout);
95 int (*signal)(struct xseg *xseg, uint32_t portno);
96 void *(*malloc)(uint64_t size);
97 void *(*realloc)(void *mem, uint64_t size);
98 void (*mfree)(void *mem);
102 struct xseg_peer_operations peer_ops;
103 char name[XSEG_TNAMESIZE];
107 uint64_t heap_size; /* heap size in MB */
109 uint32_t page_shift; /* the alignment unit */
110 char type[XSEG_TNAMESIZE]; /* zero-terminated identifier */
111 char name[XSEG_NAMESIZE]; /* zero-terminated identifier */
119 volatile uint64_t waitcue;
128 struct xseg_request *req;
131 xqindex __alloced_deps;
151 #define XF_NOSYNC (1 << 0)
152 #define XF_FLUSH (1 << 1)
153 #define XF_FUA (1 << 2)
156 #define XS_SERVED (1 << 0)
157 #define XS_FAILED (1 << 1)
159 #define XS_ACCEPTED (1 << 2)
160 #define XS_PENDING (2 << 2)
161 #define XS_SERVING (3 << 2)
162 #define XS_CONCLUDED (3 << 2)
164 struct xseg_request {
167 uint64_t size; /* FIXME: why are there both size and datalen fields? */
168 /* FIXME: why does filed use ->datalen instead of ->size? */
183 struct timeval timestamp;
189 char (*peer_types)[XSEG_TNAMESIZE]; /* alignment? */
190 uint32_t nr_peer_types;
193 struct xseg_private {
194 struct xseg_type segment_type;
195 struct xseg_peer peer_type;
196 struct xseg_peer **peer_types;
197 uint32_t max_peer_types;
198 void (*wakeup)(struct xseg *xseg, uint32_t portno);
201 struct xseg_counters {
202 uint64_t avg_req_lat;
208 uint64_t segment_size;
209 struct xseg *segment;
211 struct xobject_h *object_handlers;
213 struct xobject_h *request_h;
214 struct xobject_h *port_h;
217 struct xseg_shared *shared;
218 struct xseg_private *priv;
219 uint32_t max_peer_types;
220 struct xseg_config config;
221 struct xseg_counters counters;
224 #define XSEG_F_LOCK 0x1
226 /* ================= XSEG REQUEST INTERFACE ================================= */
227 /* ___________________ _________ */
229 int xseg_initialize ( void );
231 int xseg_finalize ( void );
233 int xseg_parse_spec ( char * spec,
234 struct xseg_config * config );
236 struct xseg_port * xseg_bind_port ( struct xseg * xseg,
239 static uint32_t xseg_portno ( struct xseg * xseg,
240 struct xseg_port * port );
241 /* \___________________/ \_________/ */
242 /* ___________________ _________ */
244 int xseg_register_type ( struct xseg_type * type );
245 int xseg_unregister_type ( const char * name );
247 int xseg_register_peer ( struct xseg_peer * peer );
248 int xseg_unregister_peer ( const char * name );
250 void xseg_report_peer_types( void );
252 int64_t xseg_enable_driver ( struct xseg * xseg,
254 int xseg_disable_driver ( struct xseg * xseg,
256 /* \___________________/ \_________/ */
257 /* ___________________ _________ */
259 int xseg_create ( struct xseg_config * cfg );
261 void xseg_destroy ( struct xseg * xseg );
262 /* \___________________/ \_________/ */
263 /* ___________________ _________ */
265 struct xseg * xseg_join ( char * segtype,
272 void xseg_leave ( struct xseg * xseg );
273 /* \___________________/ \_________/ */
274 /* ___________________ _________ */
276 int xseg_alloc_requests ( struct xseg * xseg,
280 int xseg_free_requests ( struct xseg * xseg,
284 struct xseg_request * xseg_get_request ( struct xseg * xseg,
287 int xseg_put_request ( struct xseg * xseg,
289 struct xseg_request * xreq );
291 int xseg_prep_request ( struct xseg * xseg,
292 struct xseg_request * xreq,
295 /* \___________________/ \_________/ */
296 /* ___________________ _________ */
298 xserial xseg_submit ( struct xseg * xseg,
300 struct xseg_request * xreq );
302 struct xseg_request * xseg_receive ( struct xseg * xseg,
304 /* \___________________/ \_________/ */
305 /* ___________________ _________ */
308 struct xseg_request * xseg_accept ( struct xseg * xseg,
311 xserial xseg_respond ( struct xseg * xseg,
313 struct xseg_request * xreq );
314 /* \___________________/ \_________/ */
315 /* ___________________ _________ */
317 int xseg_prepare_wait ( struct xseg * xseg,
320 int xseg_cancel_wait ( struct xseg * xseg,
323 int xseg_wait_signal ( struct xseg * xseg,
326 int xseg_signal ( struct xseg * xseg,
328 /* \___________________/ \_________/ */
333 /* ================= XSEG REQUEST INTERFACE ================================= */
335 struct xseg_port* xseg_get_port(struct xseg *xseg, uint32_t portno);
337 static inline uint32_t xseg_portno(struct xseg *xseg, struct xseg_port *port)
342 static inline char* xseg_get_target(struct xseg* xseg, struct xseg_request *req)
344 return (char *) XPTR_TAKE(req->target, xseg->segment);
347 static inline char* xseg_get_data(struct xseg* xseg, struct xseg_request *req)
349 return (char *) XPTR_TAKE(req->data, xseg->segment);
352 #define xseg_get_queue(__xseg, __port, queue) \
353 ((struct xq *) XPTR_TAKE(__port->queue, __xseg->segment))