1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // ring_logic.h author Russ Combs <rucombs@cisco.com>
19 
20 #ifndef RING_LOGIC_H
21 #define RING_LOGIC_H
22 
23 // Logic for simple ring implementation
24 
25 class RingLogic
26 {
27 public:
28     RingLogic(int size);
29 
30     // return next available position or -1
31     int read();
32     int write();
33 
34     // return true if index advanced
35     bool push();
36     bool pop();
37 
38     int count();
39     bool full();
40     bool empty();
41 
42 private:
next(int ix)43     int next(int ix)
44     { return ( ++ix < sz ) ? ix : 0; }
45 
46 private:
47     int sz;
48     volatile int rx;
49     volatile int wx;
50 };
51 
RingLogic(int size)52 inline RingLogic::RingLogic(int size)
53 {
54     sz = size;
55     rx = 0;
56     wx = 1;
57 }
58 
read()59 inline int RingLogic::read()
60 {
61     int nx = next(rx);
62     return ( nx == wx ) ? -1 : nx;
63 }
64 
write()65 inline int RingLogic::write()
66 {
67     int nx = next(wx);
68     return ( nx == rx ) ? -1 : wx;
69 }
70 
push()71 inline bool RingLogic::push()
72 {
73     int nx = next(wx);
74     if ( nx == rx )
75         return false;
76     wx = nx;
77     return true;
78 }
79 
pop()80 inline bool RingLogic::pop()
81 {
82     int nx = next(rx);
83     if ( nx == wx )
84         return false;
85     rx = nx;
86     return true;
87 }
88 
count()89 inline int RingLogic::count()
90 {
91     int c = wx - rx - 1;
92     if ( c < 0 )
93         c += sz;
94     return c;
95 }
96 
full()97 inline bool RingLogic::full()
98 {
99     return ( count() == sz );
100 }
101 
empty()102 inline bool RingLogic::empty()
103 {
104     return ( count() == 0 );
105 }
106 
107 #endif
108 
109