1. 01 Mar, 2021 1 commit
    • Philippe Gerum's avatar
      include/tube: fix queue remove/add race · edb5af7f
      Philippe Gerum authored
      
      
      A receiver could get a spurious empty tube status, due to
      receive_tube() racing with send_tube(). See the added comments into
      the code for details about the resolution.
      
      At this chance, guard against load/store tearing on shared pointers.
      
      Pending issue: we still have a potential connectivity issue between
      the prep and finish ops when pushing to a tube.
      Signed-off-by: default avatarPhilippe Gerum <rpm@xenomai.org>
      edb5af7f
  2. 12 Dec, 2020 1 commit
    • Philippe Gerum's avatar
      include/tube: remove likely branch annotations · 4be045bb
      Philippe Gerum authored
      
      
      In user-space at least, we'd be better off trusting the CPU's branch
      predictor, instead of relying on our limited perception when it comes
      to determining the likeliness of a condition, or every compiler to do
      the right thing with respect to efficient branching.
      
      We only have a couple of likely predictions in-tree on straightforward
      conditions from the tube implementation code, which we can remove
      safely.
      Signed-off-by: default avatarPhilippe Gerum <rpm@xenomai.org>
      4be045bb
  3. 26 Mar, 2020 1 commit
  4. 03 Dec, 2019 2 commits
  5. 28 Nov, 2019 1 commit
  6. 27 Nov, 2019 1 commit
  7. 19 Nov, 2019 1 commit
    • Philippe Gerum's avatar
      include: add 'tube' data path · 08592109
      Philippe Gerum authored
      A lighweight, lockless multi-reader/multi-writer FIFO with a
      base-offset variant which can work over a memory segment shared
      between processes. Scalar data or simple (small!) aggregates are
      conveyed though a tube inside canisters which exactly fit their type.
      By design, a tube is meant to be a basic, spartan mechanism: it
      imposes no usage policy whatsoever on users.
      
      As a result, a tube is strictly non-blocking, it solely detects and
      notifies the caller on return about empty input (no message in) and
      output contention (no buffer space for output). If required, the
      caller can implement blocking states, typically with a pair of EVL
      semaphores, e.g. setting up a tube conveying integers which supports
      blocking mode:
      
          DECLARE_EVL_TUBE_CANISTER(canister_type, int); /* defines struct canister_type */
          DECLARE_EVL_TUBE(tube_type, cannister_type) tube;
          struct cannister_type items[1024];
      
          evl_init_tube(&tube, items, 1024);
          evl_new_sem(&in, ...);
          evl_new_sem_any(&out, CLOCK_MONOTONIC, tube.max_items, ...);
      
          evl_get_sem(&in, ...);           @      evl_get_sem(&out);
          evl_tube_receive(&tube, ...);    @      evl_tube_send(&tube, ...);
          evl_put_sem(&out);               @      evl_put_sem(&in, ...);
      08592109