Diff for /libelwix/src/ring.c between versions 1.4.4.2 and 1.8

version 1.4.4.2, 2026/02/10 17:24:39 version 1.8, 2026/02/18 11:41:47
Line 61  rbuf_init(ringbuf_t *rbuf, int num) Line 61  rbuf_init(ringbuf_t *rbuf, int num)
   
         atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed);
         atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed);
           atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_relaxed);
   
         rbuf->rb_buffer = e_calloc(num, sizeof(struct iovec));          rbuf->rb_buffer = e_calloc(num, sizeof(struct iovec));
         if (!rbuf->rb_buffer)          if (!rbuf->rb_buffer)
Line 92  rbuf_free(ringbuf_t *rbuf) Line 93  rbuf_free(ringbuf_t *rbuf)
   
         atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed);
         atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed);
           atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_relaxed);
 }  }
   
 /*  /*
Line 111  rbuf_purge(ringbuf_t *rbuf) Line 113  rbuf_purge(ringbuf_t *rbuf)
   
         atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed);
         atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed);
           atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_relaxed);
 }  }
   
 /*  /*
Line 122  rbuf_purge(ringbuf_t *rbuf) Line 125  rbuf_purge(ringbuf_t *rbuf)
 int  int
 rbuf_isempty(ringbuf_t *rbuf)  rbuf_isempty(ringbuf_t *rbuf)
 {  {
        if (!rbuf)        if (!rbuf || !rbuf->rb_bufnum)
                 return -1;                  return -1;
   
           if (atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire))
                   return 0;
   
         return (atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire) ==          return (atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire) ==
                atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire));                        atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire));
 }  }
   
 /*  /*
Line 140  rbuf_isfull(ringbuf_t *rbuf) Line 146  rbuf_isfull(ringbuf_t *rbuf)
 {  {
         int h, t;          int h, t;
   
        if (!rbuf)        if (!rbuf || !rbuf->rb_bufnum)
                 return -1;                  return -1;
         if (!rbuf->rb_bufnum)  
                 return 1;  
   
        t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire);        if (!atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire))
        h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_relaxed) + 1;                return 0;
        if (h >= rbuf->rb_bufnum) 
                h ^= h; 
   
           t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire);
           h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire);
         return (h == t);          return (h == t);
 }  }
   
Line 159  rbuf_isfull(ringbuf_t *rbuf) Line 163  rbuf_isfull(ringbuf_t *rbuf)
  * @rbuf = Ring buffer   * @rbuf = Ring buffer
  * @data = Data   * @data = Data
  * @len = Length   * @len = Length
    * @lost = Permit to lost data
  * return: -1 error, 1 buffer is full or 0 ok   * return: -1 error, 1 buffer is full or 0 ok
  */   */
 int  int
rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len)rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len, int lost)
 {  {
        int h, t, n;        int h, t, f, n, t2, drop = 0;
         struct iovec *iov;          struct iovec *iov;
   
        if (!rbuf || !rbuf->rb_buffer)        if (!rbuf || !rbuf->rb_buffer || !rbuf->rb_bufnum)
                 return -1;                  return -1;
         if (!rbuf->rb_bufnum)  
                 return 1;  
   
        h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_relaxed);        f = atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire);
         t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire);          t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire);
        n = (h + 1) % rbuf->rb_bufnum;        h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire);
   
        if (n == t)        if (f && h == t) {
                return 1;                if (!lost)
                         return 1;
                 else
                         drop = 1;
         }
   
           n = (h + 1) % rbuf->rb_bufnum;
   
         iov = rbuf->rb_buffer + h;          iov = rbuf->rb_buffer + h;
         iov->iov_len = len;          iov->iov_len = len;
         iov->iov_base = data;          iov->iov_base = data;
   
         atomic_store_explicit((atomic_int*) &rbuf->rb_head, n, memory_order_release);          atomic_store_explicit((atomic_int*) &rbuf->rb_head, n, memory_order_release);
           if (drop) {
                   t2 = (t + 1) % rbuf->rb_bufnum;
                   while (42) {
                           drop = t;
                           if (atomic_compare_exchange_weak_explicit((atomic_int*) &rbuf->rb_tail,
                                                   &drop, t2, memory_order_release, memory_order_relaxed))
                                   break;
                           t = drop;
                           t2 = (t + 1) % rbuf->rb_bufnum;
                   }
           } else
                   t2 = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire);
           atomic_store_explicit((atomic_int*) &rbuf->rb_full, (n == t2), memory_order_release);
         return 0;          return 0;
 }  }
   
Line 197  rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len) Line 219  rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len)
 int  int
 rbuf_dequeue(ringbuf_t *rbuf, struct iovec **out)  rbuf_dequeue(ringbuf_t *rbuf, struct iovec **out)
 {  {
        int h, t, n;        int h, t, n, f;
   
        if (!rbuf || !rbuf->rb_buffer)        if (!rbuf || !rbuf->rb_buffer || !rbuf->rb_bufnum)
                 return -1;                  return -1;
         if (!rbuf->rb_bufnum)  
                 return 1;  
   
        h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire);        while (42) {
        t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_relaxed);                h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire);
        n = (t + 1) % rbuf->rb_bufnum;                f = atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire);
                 t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire);
   
        if (h == t)                if (!f && h == t)
                return 1;                        return 1;
   
        if (out)                n = (t + 1) % rbuf->rb_bufnum;
                *out = rbuf->rb_buffer + t; 
   
        atomic_store_explicit((atomic_int*) &rbuf->rb_tail, n, memory_order_release);                f = t;
                 if (atomic_compare_exchange_weak_explicit((atomic_int*) &rbuf->rb_tail,
                                         &f, n, memory_order_release, memory_order_relaxed)) {
                         if (out)
                                 *out = rbuf->rb_buffer + t;
 
                         atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_release);
                         break;
                 }
         }
 
         return 0;          return 0;
 }  }
   
Line 234  lrb_init(lrbuf_t *lrb, u_int size) Line 264  lrb_init(lrbuf_t *lrb, u_int size)
   
         atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed);
         atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed);
           atomic_store_explicit((atomic_int*) &lrb->lrb_full, 0, memory_order_relaxed);
   
         lrb->lrb_data = e_malloc(size);          lrb->lrb_data = e_malloc(size);
         if (!lrb->lrb_data)          if (!lrb->lrb_data)
Line 265  lrb_free(lrbuf_t *lrb) Line 296  lrb_free(lrbuf_t *lrb)
   
         atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed);
         atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed);
           atomic_store_explicit((atomic_int*) &lrb->lrb_full, 0, memory_order_relaxed);
 }  }
   
 /*  /*
Line 284  lrb_purge(lrbuf_t *lrb) Line 316  lrb_purge(lrbuf_t *lrb)
   
         atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed);
         atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed);          atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed);
           atomic_store_explicit((atomic_int*) &lrb->lrb_full, 0, memory_order_relaxed);
 }  }
   
 /*  /*
Line 295  lrb_purge(lrbuf_t *lrb) Line 328  lrb_purge(lrbuf_t *lrb)
 int  int
 lrb_isempty(lrbuf_t *lrb)  lrb_isempty(lrbuf_t *lrb)
 {  {
        if (!lrb)        if (!lrb || !lrb->lrb_size)
                 return -1;                  return -1;
   
        return (!atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire) &&        if (atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire))
                        (atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire) ==                return 0;
                        atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire)));
         return (atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire) ==
                         atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire));
 }  }
   
 /*  /*
Line 314  lrb_isfull(lrbuf_t *lrb) Line 349  lrb_isfull(lrbuf_t *lrb)
 {  {
         int h, t;          int h, t;
   
        if (!lrb)        if (!lrb || !lrb->lrb_size)
                 return -1;                  return -1;
         if (!lrb->lrb_size)  
                 return 1;  
   
         if (!atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire))          if (!atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire))
                 return 0;                  return 0;
   
         t = atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire);          t = atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire);
        h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed) + 1;        h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire);
        if (h >= lrb->lrb_size) 
                h ^= h; 
 
         return (h == t);          return (h == t);
 }  }
   
 /*  /*
    * lrb_getw() - Get address for write
    *
    * @lrb = Linear ring buffer
    * @len = Return available buffer length for write
    * return: NULL error or !=NULL pointer for write
    * remark: After use of lrb_getw() and write to pointer.
    *              You should update ring buffer with lrb_enqueue(,NULL,wrote_len,)
    */
   void *
   lrb_getw(lrbuf_t *lrb, size_t *len)
   {
           int h;
   
           if (!lrb || !lrb->lrb_data || !lrb->lrb_size)
                   return NULL;
   
           h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed);
           if (len)
                   *len = lrb->lrb_size - h;
   
           return (lrb->lrb_data + h);
   }
   
   /*
  * lrb_enqueue() - Enqueue data to buffer   * lrb_enqueue() - Enqueue data to buffer
  *   *
  * @lrb = Linear ring buffer   * @lrb = Linear ring buffer
Line 342  lrb_isfull(lrbuf_t *lrb) Line 396  lrb_isfull(lrbuf_t *lrb)
 int  int
 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int lost)  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int lost)
 {  {
        int h, t, n, t2, unused, drop = 0;        int h, t = 0, n, t2 = 0, unused, drop = 0;
   
        if (!lrb || !lrb->lrb_data)        if (!lrb || !lrb->lrb_data || !lrb->lrb_size)
                 return -1;                  return -1;
        if (!lrb->lrb_size || lrb->lrb_size <= len)        if (lrb->lrb_size <= len)
                 return 1;                  return 1;
   
         lrb_unused(lrb, unused);          lrb_unused(lrb, unused);
Line 366  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int  Line 420  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int 
         h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed);          h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed);
         n = lrb->lrb_size - h;          n = lrb->lrb_size - h;
         if (len < n) {          if (len < n) {
                memcpy(lrb->lrb_data + h, data, len);                if (data)
                         memcpy(lrb->lrb_data + h, data, len);
                 n = h + len;                  n = h + len;
         } else {          } else {
                memcpy(lrb->lrb_data + h, data, n);                if (data) {
                memcpy(lrb->lrb_data, data + n, len - n);                        memcpy(lrb->lrb_data + h, data, n);
                         memcpy(lrb->lrb_data, data + n, len - n);
                 }
                 n = len - n;                  n = len - n;
         }          }
   
Line 392  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int  Line 449  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int 
 }  }
   
 /*  /*
    * lrb_getr() - Get address for read
    *
    * @lrb = Linear ring buffer
    * @len = Return available data length for read
    * return: NULL error or !=NULL pointer for read
    * remark: After use of lrb_getr() and read from pointer.
    *              You could update ring buffer with lrb_dequeue(,NULL,read_len)
    */
   void *
   lrb_getr(lrbuf_t *lrb, size_t *len)
   {
           int t;
   
           if (!lrb || !lrb->lrb_data || !lrb->lrb_size)
                   return NULL;
   
           t = atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire);
           if (len)
                   lrb_queued(lrb, *len);
   
           return (lrb->lrb_data + t);
   }
   
   /*
  * lrb_dequeue() - Dequeue data from buffer   * lrb_dequeue() - Dequeue data from buffer
  *   *
  * @lrb = Linear ring buffer   * @lrb = Linear ring buffer
Line 402  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int  Line 483  lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int 
 int  int
 lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)  lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
 {  {
        int h, t, t2, n, l;        int h, t, t2, n, l, f;
   
        if (!lrb)        if (!lrb || !lrb->lrb_size)
                 return -1;                  return -1;
        if (!lrb->lrb_size || !len || lrb_isempty(lrb))        if (!len || lrb_isempty(lrb))
                 return 0;                  return 0;
         if (lrb->lrb_size <= len)          if (lrb->lrb_size <= len)
                 len = lrb->lrb_size - 1;                  len = lrb->lrb_size - 1;
Line 414  lrb_dequeue(lrbuf_t *lrb, void *data, size_t len) Line 495  lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
         while (42) {          while (42) {
                 t = atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire);                  t = atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire);
                 h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire);                  h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire);
                   f = atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire);
   
                 l = h - t;                  l = h - t;
                 if (l < 0)                  if (l < 0)
                         l += lrb->lrb_size;                          l += lrb->lrb_size;
                if (!l)                if (!l) {
                        return 0;                        if (!f)
                                 return 0;
                         l = lrb->lrb_size;
                 }
                 if (l > len)                  if (l > len)
                         l = len;                          l = len;
   
Line 431  lrb_dequeue(lrbuf_t *lrb, void *data, size_t len) Line 516  lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
                 } else {                  } else {
                         if (data) {                          if (data) {
                                 memcpy(data, lrb->lrb_data + t, n);                                  memcpy(data, lrb->lrb_data + t, n);
                                memcpy(data + n, lrb->lrb_data, l - n);                                memcpy(((u_char*) data) + n, lrb->lrb_data, l - n);
                         }                          }
                         t2 = l - n;                          t2 = l - n;
                 }                  }

Removed from v.1.4.4.2  
changed lines
  Added in v.1.8


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>