FreeBSD的buf_ring,该如何解决
FreeBSD的buf_ring
公司需要用到一个不加锁的队列实现线程同步,说是BSD上有,辛辛苦苦找来的.h .c源码,看不太懂,希望高手指教,小弟不胜感激。
buf_ring.h
32 #ifndef _SYS_BUF_RING_H_
33 #define _SYS_BUF_RING_H_
34
35 #include <machine/cpu.h>
36
37 #if defined(INVARIANTS) && !defined(DEBUG_BUFRING)
38 #define DEBUG_BUFRING 1
39 #endif
40
41 #ifdef DEBUG_BUFRING
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #endif
45
46 struct buf_ring {
47 volatile uint32_t br_prod_head;
48 volatile uint32_t br_prod_tail;
49 int br_prod_size;
50 int br_prod_mask;
51 uint64_t br_drops;
52 uint64_t br_prod_bufs;
53 uint64_t br_prod_bytes;
54 /*
55 * Pad out to next L2 cache line
56 */
57 uint64_t _pad0[11];
58
59 volatile uint32_t br_cons_head;
60 volatile uint32_t br_cons_tail;
61 int br_cons_size;
62 int br_cons_mask;
63
64 /*
65 * Pad out to next L2 cache line
66 */
67 uint64_t _pad1[14];
68 #ifdef DEBUG_BUFRING
69 struct mtx *br_lock;
70 #endif
71 void *br_ring[0];
72 };
7374 /*
75 * multi-producer safe lock-free ring buffer enqueue
76 *
77 */
78 static __inline int
79 buf_ring_enqueue_bytes(struct buf_ring *br, void *buf, int nbytes)
80 {
81 uint32_t prod_head, prod_next;
82 uint32_t cons_tail;
83 int success;
84 #ifdef DEBUG_BUFRING
85 int i;
86 for (i = br->br_cons_head; i != br->br_prod_head;
87 i = ((i + 1) & br->br_cons_mask))
88 if(br->br_ring[i] == buf)
89 panic("buf=%p already enqueue at %d prod=%d cons=%d",
90 buf, i, br->br_prod_tail, br->br_cons_tail);
91 #endif
92 critical_enter();
93 do {
94 prod_head = br->br_prod_head;
95 cons_tail = br->br_cons_tail;
96
97 prod_next = (prod_head + 1) & br->br_prod_mask;
98
公司需要用到一个不加锁的队列实现线程同步,说是BSD上有,辛辛苦苦找来的.h .c源码,看不太懂,希望高手指教,小弟不胜感激。
buf_ring.h
32 #ifndef _SYS_BUF_RING_H_
33 #define _SYS_BUF_RING_H_
34
35 #include <machine/cpu.h>
36
37 #if defined(INVARIANTS) && !defined(DEBUG_BUFRING)
38 #define DEBUG_BUFRING 1
39 #endif
40
41 #ifdef DEBUG_BUFRING
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #endif
45
46 struct buf_ring {
47 volatile uint32_t br_prod_head;
48 volatile uint32_t br_prod_tail;
49 int br_prod_size;
50 int br_prod_mask;
51 uint64_t br_drops;
52 uint64_t br_prod_bufs;
53 uint64_t br_prod_bytes;
54 /*
55 * Pad out to next L2 cache line
56 */
57 uint64_t _pad0[11];
58
59 volatile uint32_t br_cons_head;
60 volatile uint32_t br_cons_tail;
61 int br_cons_size;
62 int br_cons_mask;
63
64 /*
65 * Pad out to next L2 cache line
66 */
67 uint64_t _pad1[14];
68 #ifdef DEBUG_BUFRING
69 struct mtx *br_lock;
70 #endif
71 void *br_ring[0];
72 };
7374 /*
75 * multi-producer safe lock-free ring buffer enqueue
76 *
77 */
78 static __inline int
79 buf_ring_enqueue_bytes(struct buf_ring *br, void *buf, int nbytes)
80 {
81 uint32_t prod_head, prod_next;
82 uint32_t cons_tail;
83 int success;
84 #ifdef DEBUG_BUFRING
85 int i;
86 for (i = br->br_cons_head; i != br->br_prod_head;
87 i = ((i + 1) & br->br_cons_mask))
88 if(br->br_ring[i] == buf)
89 panic("buf=%p already enqueue at %d prod=%d cons=%d",
90 buf, i, br->br_prod_tail, br->br_cons_tail);
91 #endif
92 critical_enter();
93 do {
94 prod_head = br->br_prod_head;
95 cons_tail = br->br_cons_tail;
96
97 prod_next = (prod_head + 1) & br->br_prod_mask;
98