source: libcfa/src/concurrency/io/types.hfa @ 4f762d3

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 4f762d3 was 78da4ab, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

New implementation of io based on instance burrowing.
Trying to avoid the unbounded growth of the previous flat combining approach.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// io/types.hfa -- PRIVATE
8// Types used by the I/O subsystem
9//
10// Author           : Thierry Delisle
11// Created On       : Fri Jul 31 16:22:47 2020
12// Last Modified By :
13// Last Modified On :
14// Update Count     :
15//
16
17#pragma once
18
19extern "C" {
20        #include <linux/types.h>
21}
22
23#include "bits/locks.hfa"
24#include "kernel/fwd.hfa"
25
26#if defined(CFA_HAVE_LINUX_IO_URING_H)
27        #include "bits/sequence.hfa"
28        #include "monitor.hfa"
29
30        struct processor;
31        monitor $io_arbiter;
32
33        //-----------------------------------------------------------------------
34        // Ring Data structure
35      struct __sub_ring_t {
36                struct {
37                        // Head and tail of the ring (associated with array)
38                        volatile __u32 * head;   // one passed last index consumed by the kernel
39                        volatile __u32 * tail;   // one passed last index visible to the kernel
40                        volatile __u32 ready;    // one passed last index added to array ()
41                        volatile __u32 released; // one passed last index released back to the free list
42
43                        // The actual kernel ring which uses head/tail
44                        // indexes into the sqes arrays
45                        __u32 * array;
46                } kring;
47
48                struct {
49                        volatile __u32 head;
50                        volatile __u32 tail;
51                        // The ring which contains free allocations
52                        // indexes into the sqes arrays
53                        __u32 * array;
54                } free_ring;
55
56                // number of sqes to submit on next system call.
57                __u32 to_submit;
58
59                // number of entries and mask to go with it
60                const __u32 * num;
61                const __u32 * mask;
62
63                // Submission flags, currently only IORING_SETUP_SQPOLL
64                __u32 * flags;
65
66                // number of sqes not submitted
67                // From documentation : [dropped] is incremented for each invalid submission queue entry encountered in the ring buffer.
68                __u32 * dropped;
69
70                // A buffer of sqes (not the actual ring)
71                struct io_uring_sqe * sqes;
72
73                // The location and size of the mmaped area
74                void * ring_ptr;
75                size_t ring_sz;
76        };
77
78        struct __cmp_ring_t {
79                // Head and tail of the ring
80                volatile __u32 * head;
81                volatile __u32 * tail;
82
83                // number of entries and mask to go with it
84                const __u32 * mask;
85                const __u32 * num;
86
87                // I don't know what this value is for
88                __u32 * overflow;
89
90                // the kernel ring
91                volatile struct io_uring_cqe * cqes;
92
93                // The location and size of the mmaped area
94                void * ring_ptr;
95                size_t ring_sz;
96        };
97
98        struct __attribute__((aligned(128))) $io_context {
99                inline Seqable;
100
101                volatile bool revoked;
102                processor * proc;
103
104                $io_arbiter * arbiter;
105
106                struct {
107                        volatile bool empty;
108                        condition blocked;
109                } ext_sq;
110
111                struct __sub_ring_t sq;
112                struct __cmp_ring_t cq;
113                __u32 ring_flags;
114                int fd;
115                int efd;
116
117                single_sem sem;
118                $thread self;
119        };
120
121        void main( $io_context & this );
122        static inline $thread  * get_thread ( $io_context & this ) __attribute__((const)) { return &this.self; }
123        static inline $monitor * get_monitor( $io_context & this ) __attribute__((const)) { return &this.self.self_mon; }
124        static inline $io_context *& Back( $io_context * n ) { return ($io_context *)Back( (Seqable *)n ); }
125        static inline $io_context *& Next( $io_context * n ) { return ($io_context *)Next( (Colable *)n ); }
126        void ^?{}( $io_context & mutex this );
127
128        monitor __attribute__((aligned(128))) $io_arbiter {
129                struct {
130                        condition blocked;
131                        $io_context * ctx;
132                        volatile bool flag;
133                } pending;
134
135                Sequence($io_context) assigned;
136
137                Sequence($io_context) available;
138        };
139
140        //-----------------------------------------------------------------------
141        // Misc
142        // Weirdly, some systems that do support io_uring don't actually define these
143        #ifdef __alpha__
144                /*
145                * alpha is the only exception, all other architectures
146                * have common numbers for new system calls.
147                */
148                #ifndef __NR_io_uring_setup
149                        #define __NR_io_uring_setup           535
150                #endif
151                #ifndef __NR_io_uring_enter
152                        #define __NR_io_uring_enter           536
153                #endif
154                #ifndef __NR_io_uring_register
155                        #define __NR_io_uring_register        537
156                #endif
157        #else /* !__alpha__ */
158                #ifndef __NR_io_uring_setup
159                        #define __NR_io_uring_setup           425
160                #endif
161                #ifndef __NR_io_uring_enter
162                        #define __NR_io_uring_enter           426
163                #endif
164                #ifndef __NR_io_uring_register
165                        #define __NR_io_uring_register        427
166                #endif
167        #endif
168
169        void __ioctx_prepare_block($io_context & ctx);
170#endif
171
172//-----------------------------------------------------------------------
173// IO user data
174struct io_future_t {
175        future_t self;
176        __s32 result;
177};
178
179static inline {
180        bool fulfil( io_future_t & this, __s32 result ) {
181                this.result = result;
182                return fulfil(this.self);
183        }
184
185        // Wait for the future to be fulfilled
186        bool wait( io_future_t & this ) {
187                return wait(this.self);
188        }
189}
Note: See TracBrowser for help on using the repository browser.