source: libcfa/src/concurrency/io/call.cfa.in@ 8e4bc30

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 8e4bc30 was eccb14d, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Missed fix in madvise

  • Property mode set to 100644
File size: 15.0 KB
Line 
1#!python3
2#
3# Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
4#
5# The contents of this file are covered under the licence agreement in the
6# file "LICENCE" distributed with Cforall.
7#
8# call.cfa.in -- Python script to generate io/call.cfa
9#
10# Author : Thierry Delisle
11# Created On : Fri Sep 11 12:41:16 2020
12# Last Modified By :
13# Last Modified On :
14# Update Count :
15#
16
17Header = """//
18// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
19//
20// The contents of this file are covered under the licence agreement in the
21// file "LICENCE" distributed with Cforall.
22//
23// call.cfa -- Api for cforall
24//
25// Author : Generated from call.cfa.in
26// Created On : {}
27//
28
29"""
30
31Prelude = """#define __cforall_thread__
32
33#include "bits/defs.hfa"
34#include "kernel.hfa"
35#include "io/types.hfa"
36
37//=============================================================================================
38// I/O uring backend
39//=============================================================================================
40
41#if defined(CFA_HAVE_LINUX_IO_URING_H)
42 #include <assert.h>
43 #include <stdint.h>
44 #include <errno.h>
45 #include <linux/io_uring.h>
46
47 #include "kernel/fwd.hfa"
48
49 #if defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_IO_DRAIN) && defined(CFA_HAVE_IOSQE_ASYNC)
50 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_IO_DRAIN | IOSQE_ASYNC)
51 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_ASYNC)
52 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_ASYNC)
53 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_IO_DRAIN)
54 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_IO_DRAIN)
55 #elif defined(CFA_HAVE_IOSQE_IO_DRAIN) && defined(CFA_HAVE_IOSQE_ASYNC)
56 #define REGULAR_FLAGS (IOSQE_IO_DRAIN | IOSQE_ASYNC)
57 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE)
58 #define REGULAR_FLAGS (IOSQE_FIXED_FILE)
59 #elif defined(CFA_HAVE_IOSQE_IO_DRAIN)
60 #define REGULAR_FLAGS (IOSQE_IO_DRAIN)
61 #elif defined(CFA_HAVE_IOSQE_ASYNC)
62 #define REGULAR_FLAGS (IOSQE_ASYNC)
63 #else
64 #define REGULAR_FLAGS (0)
65 #endif
66
67 #if defined(CFA_HAVE_IOSQE_IO_LINK) && defined(CFA_HAVE_IOSQE_IO_HARDLINK)
68 #define LINK_FLAGS (IOSQE_IO_LINK | IOSQE_IO_HARDLINK)
69 #elif defined(CFA_HAVE_IOSQE_IO_LINK)
70 #define LINK_FLAGS (IOSQE_IO_LINK)
71 #elif defined(CFA_HAVE_IOSQE_IO_HARDLINK)
72 #define LINK_FLAGS (IOSQE_IO_HARDLINK)
73 #else
74 #define LINK_FLAGS (0)
75 #endif
76
77 #if defined(CFA_HAVE_SPLICE_F_FD_IN_FIXED)
78 #define SPLICE_FLAGS (SPLICE_F_FD_IN_FIXED)
79 #else
80 #define SPLICE_FLAGS (0)
81 #endif
82
83 extern [* struct io_uring_sqe, __u32] __submit_alloc( struct __io_data & ring, __u64 data );
84 extern void __submit( struct io_context * ctx, __u32 idx ) __attribute__((nonnull (1)));
85
86 static inline io_context * __get_io_context( void ) {
87 cluster * cltr = active_cluster();
88
89 /* paranoid */ verifyf( cltr, "No active cluster for io operation\\n");
90 assertf( cltr->io.cnt > 0, "Cluster %p has no default io contexts and no context was specified\\n", cltr );
91
92 /* paranoid */ verifyf( cltr->io.ctxs, "default io contexts for cluster %p are missing\\n", cltr);
93 return &cltr->io.ctxs[ __tls_rand() % cltr->io.cnt ];
94 }
95#endif
96
97//=============================================================================================
98// I/O Forwards
99//=============================================================================================
100#include <time.hfa>
101
102// Some forward declarations
103#include <errno.h>
104#include <unistd.h>
105
106extern "C" {
107 #include <sys/types.h>
108 #include <sys/socket.h>
109 #include <sys/syscall.h>
110
111#if defined(CFA_HAVE_PREADV2)
112 struct iovec;
113 extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
114#endif
115#if defined(CFA_HAVE_PWRITEV2)
116 struct iovec;
117 extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
118#endif
119
120 extern int fsync(int fd);
121
122 #if __OFF_T_MATCHES_OFF64_T
123 typedef __off64_t off_t;
124 #else
125 typedef __off_t off_t;
126 #endif
127 typedef __off64_t off64_t;
128 extern int sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags);
129
130 struct msghdr;
131 struct sockaddr;
132 extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
133 extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
134 extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
135 extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
136 extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
137 extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
138
139 extern int fallocate(int fd, int mode, off_t offset, off_t len);
140 extern int posix_fadvise(int fd, off_t offset, off_t len, int advice);
141 extern int madvise(void *addr, size_t length, int advice);
142
143 extern int openat(int dirfd, const char *pathname, int flags, mode_t mode);
144 extern int close(int fd);
145
146 extern ssize_t read (int fd, void *buf, size_t count);
147
148 struct epoll_event;
149 extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
150
151 extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
152 extern ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
153}
154
155//=============================================================================================
156// I/O Interface
157//=============================================================================================
158"""
159
160print(Header.format("A Date"))
161print(Prelude)
162
163import re
164import sys
165class Call:
166 def __init__(self, op, signature, body, define=None):
167 sig = re.search("(.*) (.*)\((.*)\)", signature)
168 if not sig:
169 print("OP '{}' has invalid signature {}".format(op, signature), file=sys.stderr)
170 sys.exit(1)
171
172 self.op = op
173 self.ret = sig.group(1)
174 self.name = sig.group(2)
175 self.params = sig.group(3)
176 self.define = define
177 self.body = ""
178
179 accepted_keys = [ 'ioprio', 'fd', 'off', 'addr2','addr', 'splice_off_in','len',
180 'rw_flags', 'fsync_flags', 'poll_events', 'poll32_events',
181 'sync_range_flags', 'msg_flags', 'timeout_flags', 'accept_flags',
182 'cancel_flags', 'open_flags', 'statx_flags', 'fadvise_advice',
183 'splice_flags', 'buf_index' ,'buf_group' 'personality',
184 'splice_fd_in' ]
185
186 for k, v in body.items():
187 if not k in accepted_keys:
188 print("OP '{}' has invalid body kew {}".format(op, k), file=sys.stderr)
189 sys.exit(1)
190
191 self.body += "\n sqe->{key} = {value};".format(key=k, value=v)
192
193
194 def args(self):
195 param_a = self.params.split(',')
196 args_a = [p.replace('*', ' ').split()[-1] for p in param_a]
197 for a in args_a:
198 if '*' in a:
199 print("OP '{}' has invalid * in argument {}".format(self.op, a), file=sys.stderr)
200 sys.exit(1)
201
202 return ', '.join(args_a)
203
204AsyncTemplate = """inline void async_{name}(io_future_t & future, {params}, int submit_flags, io_cancellation * cancellation, io_context * context) {{
205 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_{op})
206 ssize_t res = {name}({args});
207 if (res >= 0) {{
208 fulfil(future, res);
209 }}
210 else {{
211 fulfil(future, -errno);
212 }}
213 #else
214 // we don't support LINK yet
215 if( 0 != (submit_flags & LINK_FLAGS) ) {{
216 errno = ENOTSUP; return -1;
217 }}
218
219 if( !context ) {{
220 context = __get_io_context();
221 }}
222 if(cancellation) {{
223 cancellation->target = (__u64)(uintptr_t)&future;
224 }}
225
226 __u8 sflags = REGULAR_FLAGS & submit_flags;
227 struct __io_data & ring = *context->thrd.ring;
228
229 __u32 idx;
230 struct io_uring_sqe * sqe;
231 [sqe, idx] = __submit_alloc( ring, (__u64)(uintptr_t)&future );
232
233 sqe->__pad2[0] = sqe->__pad2[1] = sqe->__pad2[2] = 0;
234 sqe->opcode = IORING_OP_{op};
235 sqe->flags = sflags;{body}
236
237 verify( sqe->user_data == (__u64)(uintptr_t)&future );
238 __submit( context, idx );
239 #endif
240}}"""
241
242SyncTemplate = """{ret} cfa_{name}({params}, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {{
243 if( timeout >= 0 ) {{
244 errno = ENOTSUP;
245 return -1;
246 }}
247 io_future_t future;
248
249 async_{name}( future, {args}, submit_flags, cancellation, context );
250
251 wait( future );
252 if( future.result < 0 ) {{
253 errno = -future.result;
254 return -1;
255 }}
256 return future.result;
257}}"""
258
259calls = [
260 # CFA_HAVE_IORING_OP_READV
261 Call('READV', 'ssize_t preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)', {
262 'fd' : 'fd',
263 'off' : 'offset',
264 'addr': '(__u64)iov',
265 'len' : 'iovcnt',
266 }, define = 'CFA_HAVE_PREADV2'),
267 # CFA_HAVE_IORING_OP_WRITEV
268 Call('WRITEV', 'ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)', {
269 'fd' : 'fd',
270 'off' : 'offset',
271 'addr': '(__u64)iov',
272 'len' : 'iovcnt'
273 }, define = 'CFA_HAVE_PWRITEV2'),
274 # CFA_HAVE_IORING_OP_FSYNC
275 Call('FSYNC', 'int fsync(int fd)', {
276 'fd': 'fd'
277 }),
278 # CFA_HAVE_IORING_OP_EPOLL_CTL
279 Call('EPOLL_CTL', 'int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)', {
280 'fd': 'epfd',
281 'addr': 'fd',
282 'len': 'op',
283 'off': '(__u64)event'
284 }),
285 # CFA_HAVE_IORING_OP_SYNC_FILE_RANGE
286 Call('SYNC_FILE_RANGE', 'int sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags)', {
287 'fd': 'fd',
288 'off': 'offset',
289 'len': 'nbytes',
290 'sync_range_flags': 'flags'
291 }),
292 # CFA_HAVE_IORING_OP_SENDMSG
293 Call('SENDMSG', 'ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)', {
294 'fd': 'sockfd',
295 'addr': '(__u64)(struct msghdr *)msg',
296 'len': '1',
297 'msg_flags': 'flags'
298 }),
299 # CFA_HAVE_IORING_OP_RECVMSG
300 Call('RECVMSG', 'ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)', {
301 'fd': 'sockfd',
302 'addr': '(__u64)(struct msghdr *)msg',
303 'len': '1',
304 'msg_flags': 'flags'
305 }),
306 # CFA_HAVE_IORING_OP_SEND
307 Call('SEND', 'ssize_t send(int sockfd, const void *buf, size_t len, int flags)', {
308 'fd': 'sockfd',
309 'addr': '(__u64)buf',
310 'len': 'len',
311 'msg_flags': 'flags'
312 }),
313 # CFA_HAVE_IORING_OP_RECV
314 Call('RECV', 'ssize_t recv(int sockfd, void *buf, size_t len, int flags)', {
315 'fd': 'sockfd',
316 'addr': '(__u64)buf',
317 'len': 'len',
318 'msg_flags': 'flags'
319 }),
320 # CFA_HAVE_IORING_OP_ACCEPT
321 Call('ACCEPT4', 'int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)', {
322 'fd': 'sockfd',
323 'addr': 'addr',
324 'addr2': 'addrlen',
325 'accept_flags': 'flags'
326 }),
327 # CFA_HAVE_IORING_OP_CONNECT
328 Call('CONNECT', 'int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)', {
329 'fd': 'sockfd',
330 'addr': '(__u64)addr',
331 'off': 'addrlen'
332 }),
333 # CFA_HAVE_IORING_OP_FALLOCATE
334 Call('FALLOCATE', 'int fallocate(int fd, int mode, off_t offset, off_t len)', {
335 'fd': 'fd',
336 'addr': '(__u64)len',
337 'len': 'mode',
338 'off': 'offset'
339 }),
340 # CFA_HAVE_IORING_OP_FADVISE
341 Call('FADVISE', 'int posix_fadvise(int fd, off_t offset, off_t len, int advice)', {
342 'fd': 'fd',
343 'off': 'offset',
344 'len': 'len',
345 'fadvise_advice': 'advice'
346 }),
347 # CFA_HAVE_IORING_OP_MADVISE
348 Call('MADVISE', 'int madvise(void *addr, size_t length, int advice)', {
349 'addr': '(__u64)addr',
350 'len': 'length',
351 'fadvise_advice': 'advice'
352 }),
353 # CFA_HAVE_IORING_OP_OPENAT
354 Call('OPENAT', 'int openat(int dirfd, const char *pathname, int flags, mode_t mode)', {
355 'fd': 'dirfd',
356 'addr': '(__u64)pathname',
357 'len': 'mode',
358 'open_flags': 'flags;'
359 }),
360 # CFA_HAVE_IORING_OP_OPENAT2
361 Call('OPENAT2', 'int openat2(int dirfd, const char *pathname, struct open_how * how, size_t size)', {
362 'fd': 'dirfd',
363 'addr': 'pathname',
364 'len': 'sizeof(*how)',
365 'off': '(__u64)how',
366 }, define = 'CFA_HAVE_OPENAT2'),
367 # CFA_HAVE_IORING_OP_CLOSE
368 Call('CLOSE', 'int close(int fd)', {
369 'fd': 'fd'
370 }),
371 # CFA_HAVE_IORING_OP_STATX
372 Call('STATX', 'int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf)', {
373 'fd': 'dirfd',
374 'off': '(__u64)statxbuf',
375 'addr': 'pathname',
376 'len': 'mask',
377 'statx_flags': 'flags'
378 }, define = 'CFA_HAVE_STATX'),
379 # CFA_HAVE_IORING_OP_READ
380 Call('READ', 'ssize_t read(int fd, void * buf, size_t count)', {
381 'fd': 'fd',
382 'addr': '(__u64)buf',
383 'len': 'count'
384 }),
385 # CFA_HAVE_IORING_OP_WRITE
386 Call('WRITE', 'ssize_t write(int fd, void * buf, size_t count)', {
387 'fd': 'fd',
388 'addr': '(__u64)buf',
389 'len': 'count'
390 }),
391 # CFA_HAVE_IORING_OP_SPLICE
392 Call('SPLICE', 'ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags)', {
393 'splice_fd_in': 'fd_in',
394 'splice_off_in': 'off_in ? (__u64)*off_in : (__u64)-1',
395 'fd': 'fd_out',
396 'off': 'off_out ? (__u64)*off_out : (__u64)-1',
397 'len': 'len',
398 'splice_flags': 'flags'
399 }),
400 # CFA_HAVE_IORING_OP_TEE
401 Call('TEE', 'ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags)', {
402 'splice_fd_in': 'fd_in',
403 'fd': 'fd_out',
404 'len': 'len',
405 'splice_flags': 'flags'
406 })
407]
408
409print("//----------")
410print("// synchronous calls")
411for c in calls:
412 if c.define:
413 print("""#if defined({define})
414 {ret} cfa_{name}({params}, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
415#endif""".format(define=c.define,ret=c.ret, name=c.name, params=c.params))
416 else:
417 print("{ret} cfa_{name}({params}, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);"
418 .format(ret=c.ret, name=c.name, params=c.params))
419
420print("\n//----------")
421print("// asynchronous calls")
422for c in calls:
423 if c.define:
424 print("""#if defined({define})
425 void async_{name}(io_future_t & future, {params}, int submit_flags, io_cancellation * cancellation, io_context * context);
426#endif""".format(define=c.define,name=c.name, params=c.params))
427 else:
428 print("void async_{name}(io_future_t & future, {params}, int submit_flags, io_cancellation * cancellation, io_context * context);"
429 .format(name=c.name, params=c.params))
430print("\n")
431
432for c in calls:
433 print("//-----------------------------------------------------------------------------")
434 print("// {}".format(c.name))
435 Async = AsyncTemplate.format(
436 name = c.name,
437 ret = c.ret,
438 params = c.params,
439 args = c.args(),
440 op = c.op,
441 body = c.body
442
443 )
444 Sync = SyncTemplate.format(
445 name = c.name,
446 ret = c.ret,
447 params = c.params,
448 args = c.args()
449 )
450
451 if c.define:
452 print("""#if defined({})
453 //----------
454 // asynchronous call
455 {}
456
457 //----------
458 // synchronous call
459 {}
460#endif
461""".format(c.define, "\n\t".join( Async.splitlines() ), "\n\t".join( Sync.splitlines() )))
462 else :
463 print("""//----------
464// asynchronous call
465{}
466
467//----------
468// synchronous call
469{}
470""".format(Async, Sync))
471
472print("""
473//-----------------------------------------------------------------------------
474// Check if a function is has asynchronous
475bool has_user_level_blocking( fptr_t func ) {
476 #if defined(CFA_HAVE_LINUX_IO_URING_H)""")
477
478for c in calls:
479 if c.define:
480 print(""" #if defined({define})
481 if( /*func == (fptr_t)preadv2 || */
482 func == (fptr_t)cfa_{name} ||
483 func == (fptr_t)async_{name} ) {{
484 #if defined(CFA_HAVE_IORING_OP_{op})
485 return true;
486 #else
487 return false;
488 #endif
489 }}
490 #endif""".format(define=c.define, name=c.name, op=c.op))
491 else:
492 print(""" if( /*func == (fptr_t)preadv2 || */
493 func == (fptr_t)cfa_{name} ||
494 func == (fptr_t)async_{name} ) {{
495 #if defined(CFA_HAVE_IORING_OP_{op})
496 return true;
497 #else
498 return false;
499 #endif
500 }}""".format(name=c.name, op=c.op))
501
502print(""" #endif
503
504 return false;
505}""")
Note: See TracBrowser for help on using the repository browser.