Click
Loading...
Searching...
No Matches
storage.hh
1// -*- c-basic-offset: 4 -*-
2#ifndef CLICK_STORAGE_HH
3#define CLICK_STORAGE_HH
4#include <click/machine.hh>
5#include <click/atomic.hh>
6CLICK_DECLS
7class Packet;
8
9class Storage { public:
10
11 typedef uint32_t index_type;
12 typedef int32_t signed_index_type;
13 static const index_type invalid_index = (index_type) -1;
14
15 Storage() : _head(0), _tail(0) { }
16
17 operator bool() const { return _head != _tail; }
18 bool empty() const { return _head == _tail; }
19 int size() const;
20 int size(index_type head, index_type tail) const;
21 int capacity() const { return _capacity; }
22
23 index_type head() const { return _head; }
24 index_type tail() const { return _tail; }
25
26 index_type next_i(index_type i) const {
27 return (i!=_capacity ? i+1 : 0);
28 }
29 index_type prev_i(index_type i) const {
30 return (i!=0 ? i-1 : _capacity);
31 }
32
33 // to be used with care
34 void set_capacity(index_type c) { _capacity = c; }
35 inline void set_head(index_type h); // acquire barrier (read pkt)
36 inline void set_tail(index_type t); // release barrier (write pkt)
37 inline void set_head_release(index_type h); // release barrier (LIFO)
38 inline void set_tail_acquire(index_type t); // acquire barrier (LIFO)
39 inline index_type reserve_tail_atomic();
40
41 static inline void packet_memory_barrier(Packet* volatile& packet,
42 volatile index_type& index)
43 __attribute__((deprecated));
44 inline void packet_memory_barrier(Packet* volatile& packet)
45 __attribute__((deprecated));
46
47 protected:
48 index_type _capacity;
49
50 private:
51 volatile index_type _head;
52 volatile index_type _tail;
53
54};
55
56inline int
57Storage::size(index_type head, index_type tail) const
58{
59 index_type x = tail - head;
60 return (signed_index_type(x) >= 0 ? x : _capacity + x + 1);
61}
62
63inline int
64Storage::size() const
65{
66 return size(_head, _tail);
67}
68
69inline void
70Storage::set_head(index_type h)
71{
72 click_read_fence();
73 _head = h;
74}
75
76inline void
77Storage::set_tail(index_type t)
78{
79 click_write_fence();
80 _tail = t;
81}
82
83inline void
84Storage::set_head_release(index_type h)
85{
86 click_write_fence();
87 _head = h;
88}
89
90inline void
91Storage::set_tail_acquire(index_type t)
92{
93 click_read_fence();
94 _tail = t;
95}
96
97inline Storage::index_type
98Storage::reserve_tail_atomic()
99{
100 index_type t, nt;
101 do {
102 t = _tail;
103 nt = next_i(t);
104 if (nt == _head)
105 return invalid_index;
106#if ! CLICK_ATOMIC_COMPARE_SWAP
107 } while (!atomic_uint32_t::compare_and_swap(_tail, t, nt));
108#else
109 } while (atomic_uint32_t::compare_swap(_tail, t, nt) != t);
110#endif
111 return t;
112}
113
114inline void
115Storage::packet_memory_barrier(Packet* volatile& packet, volatile index_type& index)
116{
117 __asm__ volatile("" : : "m" (packet), "m" (index));
118}
119
120inline void
121Storage::packet_memory_barrier(Packet * volatile &packet)
122{
123 __asm__ volatile("" : : "m" (packet), "m" (_head), "m" (_tail));
124}
125
126CLICK_ENDDECLS
127#endif
An atomic 32-bit integer.
A network packet.
Definition packet.hh:68
bool compare_and_swap(uint32_t expected, uint32_t desired) CLICK_BUILTINS_NONDEPRECATED
Perform a compare-and-swap operation.
Definition atomic.hh:734