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