openflow build environment setup
This commit is contained in:
123
openflow/include/click/standard/storage.hh
Normal file
123
openflow/include/click/standard/storage.hh
Normal file
@@ -0,0 +1,123 @@
|
||||
// -*- c-basic-offset: 4 -*-
|
||||
#ifndef CLICK_STORAGE_HH
|
||||
#define CLICK_STORAGE_HH
|
||||
#include <click/machine.hh>
|
||||
#include <click/atomic.hh>
|
||||
CLICK_DECLS
|
||||
class Packet;
|
||||
|
||||
class Storage { public:
|
||||
|
||||
typedef uint32_t index_type;
|
||||
typedef int32_t signed_index_type;
|
||||
static const index_type invalid_index = (index_type) -1;
|
||||
|
||||
Storage() : _head(0), _tail(0) { }
|
||||
|
||||
operator bool() const { return _head != _tail; }
|
||||
bool empty() const { return _head == _tail; }
|
||||
int size() const;
|
||||
int size(index_type head, index_type tail) const;
|
||||
int capacity() const { return _capacity; }
|
||||
|
||||
index_type head() const { return _head; }
|
||||
index_type tail() const { return _tail; }
|
||||
|
||||
index_type next_i(index_type i) const {
|
||||
return (i!=_capacity ? i+1 : 0);
|
||||
}
|
||||
index_type prev_i(index_type i) const {
|
||||
return (i!=0 ? i-1 : _capacity);
|
||||
}
|
||||
|
||||
// to be used with care
|
||||
void set_capacity(index_type c) { _capacity = c; }
|
||||
inline void set_head(index_type h); // acquire barrier (read pkt)
|
||||
inline void set_tail(index_type t); // release barrier (write pkt)
|
||||
inline void set_head_release(index_type h); // release barrier (LIFO)
|
||||
inline void set_tail_acquire(index_type t); // acquire barrier (LIFO)
|
||||
inline index_type reserve_tail_atomic();
|
||||
|
||||
static inline void packet_memory_barrier(Packet* volatile& packet,
|
||||
volatile index_type& index)
|
||||
__attribute__((deprecated));
|
||||
inline void packet_memory_barrier(Packet* volatile& packet)
|
||||
__attribute__((deprecated));
|
||||
|
||||
protected:
|
||||
index_type _capacity;
|
||||
|
||||
private:
|
||||
volatile index_type _head;
|
||||
volatile index_type _tail;
|
||||
|
||||
};
|
||||
|
||||
inline int
|
||||
Storage::size(index_type head, index_type tail) const
|
||||
{
|
||||
index_type x = tail - head;
|
||||
return (signed_index_type(x) >= 0 ? x : _capacity + x + 1);
|
||||
}
|
||||
|
||||
inline int
|
||||
Storage::size() const
|
||||
{
|
||||
return size(_head, _tail);
|
||||
}
|
||||
|
||||
inline void
|
||||
Storage::set_head(index_type h)
|
||||
{
|
||||
click_read_fence();
|
||||
_head = h;
|
||||
}
|
||||
|
||||
inline void
|
||||
Storage::set_tail(index_type t)
|
||||
{
|
||||
click_write_fence();
|
||||
_tail = t;
|
||||
}
|
||||
|
||||
inline void
|
||||
Storage::set_head_release(index_type h)
|
||||
{
|
||||
click_write_fence();
|
||||
_head = h;
|
||||
}
|
||||
|
||||
inline void
|
||||
Storage::set_tail_acquire(index_type t)
|
||||
{
|
||||
click_read_fence();
|
||||
_tail = t;
|
||||
}
|
||||
|
||||
inline Storage::index_type
|
||||
Storage::reserve_tail_atomic()
|
||||
{
|
||||
index_type t, nt;
|
||||
do {
|
||||
t = _tail;
|
||||
nt = next_i(t);
|
||||
if (nt == _head)
|
||||
return invalid_index;
|
||||
} while (atomic_uint32_t::compare_swap(_tail, t, nt) != t);
|
||||
return t;
|
||||
}
|
||||
|
||||
inline void
|
||||
Storage::packet_memory_barrier(Packet* volatile& packet, volatile index_type& index)
|
||||
{
|
||||
__asm__ volatile("" : : "m" (packet), "m" (index));
|
||||
}
|
||||
|
||||
inline void
|
||||
Storage::packet_memory_barrier(Packet * volatile &packet)
|
||||
{
|
||||
__asm__ volatile("" : : "m" (packet), "m" (_head), "m" (_tail));
|
||||
}
|
||||
|
||||
CLICK_ENDDECLS
|
||||
#endif
|
||||
Reference in New Issue
Block a user