]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_write.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.0.0 / liblfds700 / src / lfds700_ringbuffer / lfds700_ringbuffer_write.c
1 /***** includes *****/
2 #include "lfds700_ringbuffer_internal.h"
3
4
5
6
7
8 /****************************************************************************/
9 void lfds700_ringbuffer_write( struct lfds700_ringbuffer_state *rs,
10                                void *key,
11                                void *value,
12                                enum lfds700_misc_flag *overwrite_occurred_flag,
13                                void **overwritten_key,
14                                void **overwritten_value,
15                                struct lfds700_misc_prng_state *ps )
16 {
17   int
18     rv = 0;
19
20   struct lfds700_freelist_element
21     *fe;
22
23   struct lfds700_queue_element
24     *qe;
25
26   struct lfds700_ringbuffer_element
27     *re = NULL;
28
29   LFDS700_PAL_ASSERT( rs != NULL );
30   // TRD : key can be NULL
31   // TRD : value can be NULL
32   // TRD : overwrite_occurred_flag can be NULL
33   // TRD : overwritten_key can be NULL
34   // TRD : overwritten_value can be NULL
35   LFDS700_PAL_ASSERT( ps != NULL );
36
37   if( overwrite_occurred_flag != NULL )
38     *overwrite_occurred_flag = LFDS700_MISC_FLAG_LOWERED;
39
40   do
41   {
42     rv = lfds700_freelist_pop( &rs->fs, &fe, ps );
43
44     if( rv == 1 )
45       re = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
46
47     if( rv == 0 )
48     {
49       // TRD : the queue can return empty as well - remember, we're lock-free; anything could have happened since the previous instruction
50       rv = lfds700_queue_dequeue( &rs->qs, &qe, ps );
51
52       if( rv == 1 )
53       {
54         re = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
55         re->qe_use = (struct lfds700_queue_element *) qe;
56
57         if( overwrite_occurred_flag != NULL )
58           *overwrite_occurred_flag = LFDS700_MISC_FLAG_RAISED;
59
60         if( overwritten_key != NULL )
61           *overwritten_key = re->key;
62
63         if( overwritten_value != NULL )
64           *overwritten_value = re->value;
65       }
66     }
67   }
68   while( rv == 0 );
69
70   re->key = key;
71   re->value = value;
72
73   LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( *re->qe_use, re );
74   lfds700_queue_enqueue( &rs->qs, re->qe_use, ps );
75
76   return;
77 }
78