]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.1/liblfds601/src/lfds601_ringbuffer/lfds601_ringbuffer_get_and_put.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.1 / liblfds601 / src / lfds601_ringbuffer / lfds601_ringbuffer_get_and_put.c
1 #include "lfds601_ringbuffer_internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 struct lfds601_freelist_element *lfds601_ringbuffer_get_read_element( struct lfds601_ringbuffer_state *rs, struct lfds601_freelist_element **fe )\r
9 {\r
10   assert( rs != NULL );\r
11   assert( fe != NULL );\r
12 \r
13   lfds601_queue_dequeue( rs->qs, (void **) fe );\r
14 \r
15   return( *fe );\r
16 }\r
17 \r
18 \r
19 \r
20 \r
21 \r
22 /****************************************************************************/\r
23 struct lfds601_freelist_element *lfds601_ringbuffer_get_write_element( struct lfds601_ringbuffer_state *rs, struct lfds601_freelist_element **fe, int *overwrite_flag )\r
24 {\r
25   assert( rs != NULL );\r
26   assert( fe != NULL );\r
27   // TRD : overwrite_flag can be NULL\r
28 \r
29   /* TRD : we try to obtain an element from the lfds601_freelist\r
30            if we can, we populate it and add it to the lfds601_queue\r
31 \r
32            if we cannot, then the lfds601_ringbuffer is full\r
33            so instead we grab the current read element and\r
34            use that instead\r
35 \r
36            dequeue may fail since the lfds601_queue may be emptied\r
37            during our dequeue attempt\r
38 \r
39            so what we actually do here is a loop, attempting\r
40            the lfds601_freelist and if it fails then a dequeue, until\r
41            we obtain an element\r
42 \r
43            once we have an element, we lfds601_queue it\r
44 \r
45            you may be wondering why this operation is in a loop\r
46            remember - these operations are lock-free; anything\r
47            can happen in between\r
48 \r
49            so for example the pop could fail because the lfds601_freelist\r
50            is empty; but by the time we go to get an element from\r
51            the lfds601_queue, the whole lfds601_queue has been emptied back into\r
52            the lfds601_freelist!\r
53 \r
54            if overwrite_flag is provided, we set it to 0 if we\r
55            obtained a new element from the lfds601_freelist, 1 if we\r
56            stole an element from the lfds601_queue\r
57   */\r
58 \r
59   do\r
60   {\r
61     if( overwrite_flag != NULL )\r
62       *overwrite_flag = 0;\r
63 \r
64     lfds601_freelist_pop( rs->fs, fe );\r
65 \r
66     if( *fe == NULL )\r
67     {\r
68       lfds601_ringbuffer_get_read_element( rs, fe );\r
69 \r
70       if( overwrite_flag != NULL and *fe != NULL )\r
71         *overwrite_flag = 1;\r
72     }\r
73   }\r
74   while( *fe == NULL );\r
75 \r
76   return( *fe );\r
77 }\r
78 \r
79 \r
80 \r
81 \r
82 \r
83 /****************************************************************************/\r
84 void lfds601_ringbuffer_put_read_element( struct lfds601_ringbuffer_state *rs, struct lfds601_freelist_element *fe )\r
85 {\r
86   assert( rs != NULL );\r
87   assert( fe != NULL );\r
88 \r
89   lfds601_freelist_push( rs->fs, fe );\r
90 \r
91   return;\r
92 }\r
93 \r
94 \r
95 \r
96 \r
97 \r
98 /****************************************************************************/\r
99 void lfds601_ringbuffer_put_write_element( struct lfds601_ringbuffer_state *rs, struct lfds601_freelist_element *fe )\r
100 {\r
101   assert( rs != NULL );\r
102   assert( fe != NULL );\r
103 \r
104   lfds601_queue_enqueue( rs->qs, fe );\r
105 \r
106   return;\r
107 }\r
108 \r