Line data Source code
1 : #ifndef HEADER_fd_src_disco_waker_fd_waker_h 2 : #define HEADER_fd_src_disco_waker_fd_waker_h 3 : 4 : /* The waker tile sleeps in epoll_wait(2) on behalf of every tile 5 : that owns kernel fds, so those tiles do not poll speculatively. 6 : 7 : At boot the launcher creates one "outer" epoll fd for the waker 8 : plus one "inner" epoll fd per client, at fixed inherited numbers. 9 : Inner fds sit in the outer set with EPOLLIN|EPOLLONESHOT. Clients 10 : register sockets in their inner set (level-triggered) and touch 11 : the outer set only to rearm their own entry. A ready inner fd 12 : wakes the outer epoll_wait. 13 : 14 : Wake protocol, per client: one fseq word, 0 idle / 1 ready. 15 : 16 : waker: for each outer event: fd_fseq_update( word, 1UL ); 17 : (EPOLLONESHOT: a slow client cannot wake-storm) 18 : 19 : client: if fd_fseq_query( word )==1: 20 : fd_fseq_update( word, 0UL ); clear FIRST 21 : while( service_fds() ); drain to empty 22 : fd_waker_client_rearm( idx ); rearm LAST 23 : the rearm MOD re-polls, so readiness that raced the 24 : drain re-fires: no lost-wake window. 25 : 26 : Inner entries must be level-triggered and drained to empty, or 27 : data can strand with no outer readiness. */ 28 : 29 : #include "../../util/fd_util_base.h" 30 : 31 0 : #define FD_WAKER_OUTER_FD (123500) 32 0 : #define FD_WAKER_INNER_FD( idx ) (123501+(int)(idx)) 33 : 34 0 : #define FD_WAKER_CLIENT_MAX (16UL) 35 : 36 : FD_PROTOTYPES_BEGIN 37 : 38 : /* fd_waker_install creates the outer and client_cnt inner epoll fds 39 : at their fixed numbers and registers the inners in the outer set. 40 : Self-tests the kernel's nested-epoll wakeups first (broken on 41 : unpatched v5.5-v5.12; rejected at boot rather than losing wakes). 42 : Logs error and aborts on failure. */ 43 : 44 : void 45 : fd_waker_install( ulong client_cnt ); 46 : 47 : /* fd_waker_client_rearm rearms the caller's entry in the outer 48 : epoll set after a drain (see wake protocol). Logs err on 49 : failure. */ 50 : 51 : void 52 : fd_waker_client_rearm( ulong idx ); 53 : 54 : FD_PROTOTYPES_END 55 : 56 : #endif /* HEADER_fd_src_disco_waker_fd_waker_h */