Ignore:
Timestamp:
Jul 8, 2020, 6:05:11 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
732b406
Parents:
1d5e4711
Message:

Submission release is now based on previous seen head rather than the return value of io_uring_enter
This will make it easier to support SQ POLLING
It is not currently thread safe.
It is unclear if it can be made thread safe

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/io.cfa

    r1d5e4711 r34b61882  
    109109                volatile uint32_t * head;
    110110                volatile uint32_t * tail;
     111                volatile uint32_t prev_head;
    111112
    112113                // The actual kernel ring which uses head/tail
     
    259260                sq.dropped = (         uint32_t *)(((intptr_t)sq.ring_ptr) + params.sq_off.dropped);
    260261                sq.array   = (         uint32_t *)(((intptr_t)sq.ring_ptr) + params.sq_off.array);
     262                sq.prev_head = *sq.head;
    261263
    262264                {
     
    430432//=============================================================================================
    431433        static unsigned __collect_submitions( struct __io_data & ring );
     434        static uint32_t __release_consumed_submission( struct __io_data & ring );
    432435
    433436        // Process a single completion message from the io_uring
     
    444447
    445448                if (to_submit > 0 || waitcnt > 0) {
    446                         uint32_t shead = *ring.submit_q.head;
    447449                        int ret = syscall( __NR_io_uring_enter, ring.fd, to_submit, waitcnt, IORING_ENTER_GETEVENTS, mask, _NSIG / 8);
    448450                        if( ret < 0 ) {
     
    457459
    458460                        // Release the consumed SQEs
    459                         for( i; ret ) {
    460                                 uint32_t idx = ring.submit_q.array[ (i + shead) & smask ];
    461                                 ring.submit_q.sqes[ idx ].user_data = 0;
    462                         }
     461                        __release_consumed_submission( ring );
    463462
    464463                        // update statistics
     
    738737
    739738                        block++;
    740                         yield();
     739                        if( try_lock(ring.submit_q.lock __cfaabi_dbg_ctx2) ) {
     740                                __release_consumed_submission( ring );
     741                                unlock( ring.submit_q.lock );
     742                        }
     743                        else {
     744                                yield();
     745                        }
    741746                }
    742747
     
    794799                        // We got the lock
    795800                        unsigned to_submit = __collect_submitions( ring );
    796                         uint32_t shead = *ring.submit_q.head;
    797801                        int ret = syscall( __NR_io_uring_enter, ring.fd, to_submit, 0, 0, 0p, _NSIG / 8);
    798802                        if( ret < 0 ) {
     
    810814
    811815                        // Release the consumed SQEs
    812                         const uint32_t smask = *ring.submit_q.mask;
    813                         for( i; ret ) {
    814                                 uint32_t idx = ring.submit_q.array[ (i + shead) & smask ];
    815                                 ring.submit_q.sqes[ idx ].user_data = 0;
    816                         }
     816                        __release_consumed_submission( ring );
    817817
    818818                        // update statistics
     
    851851                        )
    852852
    853                         ring.submit_q.sqes[ idx & mask ].user_data = 0;
     853                        // Release the consumed SQEs
     854                        __release_consumed_submission( ring );
    854855
    855856                        unlock(ring.submit_q.lock);
     
    885886                return to_submit;
    886887        }
     888
     889        static uint32_t __release_consumed_submission( struct __io_data & ring ) {
     890                const uint32_t smask = *ring.submit_q.mask;
     891                uint32_t chead = *ring.submit_q.head;
     892                uint32_t phead = ring.submit_q.prev_head;
     893                ring.submit_q.prev_head = chead;
     894                uint32_t count = chead - phead;
     895                for( i; count ) {
     896                        uint32_t idx = ring.submit_q.array[ (phead + i) & smask ];
     897                        ring.submit_q.sqes[ idx ].user_data = 0;
     898                }
     899                return count;
     900        }
    887901#endif
Note: See TracChangeset for help on using the changeset viewer.