Ignore:
Timestamp:
Feb 19, 2021, 1:47:09 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4f762d3
Parents:
b44959f
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/io/types.hfa

    rb44959f r78da4ab  
    2525
    2626#if defined(CFA_HAVE_LINUX_IO_URING_H)
    27         #define LEADER_LOCK
    28         struct __leaderlock_t {
    29                 struct $thread * volatile value;        // ($thread) next_leader | (bool:1) is_locked
    30         };
     27        #include "bits/sequence.hfa"
     28        #include "monitor.hfa"
    3129
    32         static inline void ?{}( __leaderlock_t & this ) { this.value = 0p; }
     30        struct processor;
     31        monitor $io_arbiter;
    3332
    3433        //-----------------------------------------------------------------------
    3534        // Ring Data structure
    36       struct __submition_data {
    37                 // Head and tail of the ring (associated with array)
    38                 volatile __u32 * head;
    39                 volatile __u32 * tail;
    40                 volatile __u32 prev_head;
     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
    4142
    42                 // The actual kernel ring which uses head/tail
    43                 // indexes into the sqes arrays
    44                 __u32 * array;
     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;
    4558
    4659                // number of entries and mask to go with it
     
    4861                const __u32 * mask;
    4962
    50                 // Submission flags (Not sure what for)
     63                // Submission flags, currently only IORING_SETUP_SQPOLL
    5164                __u32 * flags;
    5265
    53                 // number of sqes not submitted (whatever that means)
     66                // number of sqes not submitted
     67                // From documentation : [dropped] is incremented for each invalid submission queue entry encountered in the ring buffer.
    5468                __u32 * dropped;
    5569
    56                 // Like head/tail but not seen by the kernel
    57                 volatile __u32 * ready;
    58                 __u32 ready_cnt;
    59                 __u32 prev_ready;
    60 
    61                 #if defined(LEADER_LOCK)
    62                         __leaderlock_t submit_lock;
    63                 #else
    64                         __spinlock_t submit_lock;
    65                 #endif
    66                 __spinlock_t  release_lock;
    67 
    6870                // A buffer of sqes (not the actual ring)
    69                 volatile struct io_uring_sqe * sqes;
     71                struct io_uring_sqe * sqes;
    7072
    7173                // The location and size of the mmaped area
     
    7476        };
    7577
    76         struct __completion_data {
     78        struct __cmp_ring_t {
    7779                // Head and tail of the ring
    7880                volatile __u32 * head;
     
    8385                const __u32 * num;
    8486
    85                 // number of cqes not submitted (whatever that means)
     87                // I don't know what this value is for
    8688                __u32 * overflow;
    8789
     
    9496        };
    9597
    96         struct __io_data {
    97                 struct __submition_data submit_q;
    98                 struct __completion_data completion_q;
     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;
    99113                __u32 ring_flags;
    100114                int fd;
    101115                int efd;
    102                 bool eager_submits:1;
    103                 bool poller_submits:1;
     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;
    104138        };
    105139
     
    133167        #endif
    134168
    135         struct $io_ctx_thread;
    136         void __ioctx_register($io_ctx_thread & ctx);
    137         void __ioctx_unregister($io_ctx_thread & ctx);
    138         void __ioctx_prepare_block($io_ctx_thread & ctx);
    139         void __sqe_clean( volatile struct io_uring_sqe * sqe );
     169        void __ioctx_prepare_block($io_context & ctx);
    140170#endif
    141171
Note: See TracChangeset for help on using the changeset viewer.