OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
label_block.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef ctrlplane_label_block_h
6 #define ctrlplane_label_block_h
7 
8 #include <vector>
9 #include <boost/intrusive_ptr.hpp>
10 #include <tbb/mutex.h>
11 
12 #include "base/bitset.h"
13 
14 class LabelBlock;
16 
17 typedef boost::intrusive_ptr<LabelBlockManager> LabelBlockManagerPtr;
18 typedef boost::intrusive_ptr<LabelBlock> LabelBlockPtr;
19 
20 //
21 // This class represents the manager for a label space. The label space could
22 // be for the local node or for a remote node. The manager maintains a list
23 // of LabelBlocks from which labels can be allocated.
24 //
25 // Clients locate LabelBLocks by specifying the first and last label values for
26 // a block. A new LabelBlock is created or the refcount for an existing one is
27 // updated as appropriate. Note that we always return an intrusive pointer to
28 // LabelBlock, so that the removal of the LabelBlock happens automatically.
29 //
31 public:
34  LabelBlockPtr LocateBlock(uint32_t first, uint32_t last);
35  void RemoveBlock(LabelBlock *block);
36  tbb::mutex &mutex() { return mutex_; }
37 
38 private:
39  friend class LabelBlockTest;
40  friend void intrusive_ptr_add_ref(LabelBlockManager *block_manager);
41  friend void intrusive_ptr_release(LabelBlockManager *block_manager);
42 
43  typedef std::vector<LabelBlock *> LabelBlockList;
44 
45  size_t size();
46 
47  tbb::atomic<int> refcount_;
48 
49  // The vector of LabelBlocks is protected via the mutex_. This is needed
50  // because we need to handle concurrent calls to LocateBlock/RemoveBLock.
51  tbb::mutex mutex_;
53 };
54 
55 inline void intrusive_ptr_add_ref(LabelBlockManager *block_manager) {
56  block_manager->refcount_.fetch_and_increment();
57 }
58 inline void intrusive_ptr_release(LabelBlockManager *block_manager) {
59  int prev = block_manager->refcount_.fetch_and_decrement();
60  if (prev == 1) {
61  delete block_manager;
62  }
63 }
64 
65 //
66 // This class represents a block of labels within a label space. Clients can
67 // make requests to allocate/release a single label from within this block.
68 // As mentioned above, clients always maintain an intrusive pointer to these
69 // objects.
70 //
71 // A BitSet is used to keep track of used/allocated values. A position in the
72 // BitSet represents an offset from the first value e.g. label value of first
73 // corresponds to bit position 0.
74 //
75 // TBD: A BitSet is not time efficient when managing a large label space so
76 // we should revisit the implementation of this class. Perhaps we could use
77 // an itable or a hierarchy of BitSets.
78 //
79 class LabelBlock {
80 public:
81  LabelBlock(uint32_t first, uint32_t last);
82  LabelBlock(LabelBlockManager *block_manager, uint32_t first, uint32_t last);
83  ~LabelBlock();
84 
85  uint32_t AllocateLabel();
86  void ReleaseLabel(uint32_t value);
87  std::string ToString() const;
88  uint32_t first() { return first_; }
89  uint32_t last() { return last_; }
91 
92 private:
93  friend class LabelBlockManager;
94  friend class LabelBlockTest;
95  friend void intrusive_ptr_add_ref(LabelBlock *block);
96  friend void intrusive_ptr_release(LabelBlock *block);
97 
99  uint32_t first_, last_;
100  size_t prev_pos_;
101  tbb::atomic<int> refcount_;
102 
103  // The BitSet of used labels is protected via the mutex_. This is needed
104  // since we need to handle concurrent calls to AllocateLabel/ReleaseLabel.
105  tbb::mutex mutex_;
107 };
108 
109 inline void intrusive_ptr_add_ref(LabelBlock *block) {
110  block->refcount_.fetch_and_increment();
111 }
112 inline void intrusive_ptr_release(LabelBlock *block) {
113  tbb::mutex mutex;
114 
115  tbb::mutex::scoped_lock lock(block->block_manager() ?
116  block->block_manager()->mutex() : mutex);
117 
118  int prev = block->refcount_.fetch_and_decrement();
119  if (prev == 1) {
120  delete block;
121  }
122 }
123 
124 #endif
int intrusive_ptr_add_ref(const AsPath *cpath)
Definition: bgp_aspath.h:147
BitSet used_bitset_
Definition: label_block.h:106
LabelBlockManagerPtr block_manager_
Definition: label_block.h:98
uint32_t last_
Definition: label_block.h:99
boost::intrusive_ptr< LabelBlockManager > LabelBlockManagerPtr
Definition: label_block.h:15
tbb::mutex mutex_
Definition: label_block.h:105
std::string ToString() const
Definition: label_block.cc:106
boost::intrusive_ptr< LabelBlock > LabelBlockPtr
Definition: label_block.h:18
friend void intrusive_ptr_add_ref(LabelBlock *block)
Definition: label_block.h:109
tbb::atomic< int > refcount_
Definition: label_block.h:47
uint32_t first()
Definition: label_block.h:88
friend class LabelBlockTest
Definition: label_block.h:94
friend class LabelBlockTest
Definition: label_block.h:39
void RemoveBlock(LabelBlock *block)
Definition: label_block.cc:38
tbb::atomic< int > refcount_
Definition: label_block.h:101
void ReleaseLabel(uint32_t value)
Definition: label_block.cc:98
friend void intrusive_ptr_add_ref(LabelBlockManager *block_manager)
Definition: label_block.h:55
uint32_t AllocateLabel()
Definition: label_block.cc:77
Definition: bitset.h:17
friend void intrusive_ptr_release(LabelBlock *block)
Definition: label_block.h:112
uint32_t last()
Definition: label_block.h:89
uint32_t first_
Definition: label_block.h:99
tbb::mutex mutex_
Definition: label_block.h:51
std::vector< LabelBlock * > LabelBlockList
Definition: label_block.h:43
void intrusive_ptr_release(const AsPath *cpath)
Definition: bgp_aspath.h:155
LabelBlockPtr LocateBlock(uint32_t first, uint32_t last)
Definition: label_block.cc:22
LabelBlockList blocks_
Definition: label_block.h:52
LabelBlockManagerPtr block_manager()
Definition: label_block.h:90
tbb::mutex & mutex()
Definition: label_block.h:36
LabelBlock(uint32_t first, uint32_t last)
Definition: label_block.cc:54
size_t prev_pos_
Definition: label_block.h:100
friend void intrusive_ptr_release(LabelBlockManager *block_manager)
Definition: label_block.h:58