GCC Code Coverage Report


Directory: ./
File: include/hpp/pinocchio/pool.hh
Date: 2025-05-04 12:09:19
Exec Total Coverage
Lines: 35 36 97.2%
Branches: 17 33 51.5%

Line Branch Exec Source
1 //
2 // Copyright (c) 2018 CNRS
3 // Author: Joseph Mirabel
4 //
5 //
6
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // 1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //
14 // 2. Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30
31 #ifndef HPP_PINOCCHIO_POOL_HH
32 #define HPP_PINOCCHIO_POOL_HH
33
34 #include <boost/thread/condition_variable.hpp>
35 #include <boost/thread/mutex.hpp>
36 #include <hpp/pinocchio/config.hh>
37 #include <vector>
38
39 namespace hpp {
40 namespace pinocchio {
41
42 /// \brief Pool of objects
43 ///
44 /// Usage:
45 /// \code
46 /// Pool<Foo> pool;
47 /// std::vector<Foo*> temporary_foos;
48 /// // Fill temporary_foos new objects.
49 /// // The ownership is passed to the pool.
50 /// pool.push_back (foo.begin(), foo.end());
51 ///
52 /// Foo* foo = pool.acquire();
53 /// // Access to foo is thread safe.
54 /// pool.release(foo);
55 /// \endcode
56 template <typename T>
57 class HPP_PINOCCHIO_DLLAPI Pool {
58 public:
59 /// Get an object from the pool.
60 /// If the pool is empty, wait until one element becomes available.
61 1103 T* acquire() {
62
1/2
✓ Branch 1 taken 1106 times.
✗ Branch 2 not taken.
1103 boost::mutex::scoped_lock lock(mutex_);
63
1/2
✓ Branch 2 taken 1106 times.
✗ Branch 3 not taken.
1106 condVariable_.wait(lock, OneIsAvailable(*this));
64 1106 T* ret = NULL;
65 1106 std::swap(ret, Ts_[lastFree_]);
66 1106 lastFree_++;
67 1106 return ret;
68 1106 }
69
70 /// Release a previously acquired object.
71 /// \warning There is no check that the object was actually one returned
72 /// by Pool::acquire
73 1088 void release(T* t) {
74
1/2
✓ Branch 1 taken 1106 times.
✗ Branch 2 not taken.
1088 boost::mutex::scoped_lock lock(mutex_);
75 // At least one T* is not free.
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1106 times.
1106 assert(lastFree_ > 0);
77
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1106 times.
1106 assert(Ts_[lastFree_ - 1] == NULL);
78 1106 Ts_[lastFree_ - 1] = t;
79 1106 lastFree_--;
80 1106 condVariable_.notify_one();
81 1106 }
82
83 /// Returns true is at least one object is not locked.
84 bool available() const { return OneIsAvailable(*this)(); }
85
86 2479 std::size_t size() const { return Ts_.size(); }
87
88 /// Deletes all internal objects.
89 218 void clear() {
90
1/2
✓ Branch 1 taken 218 times.
✗ Branch 2 not taken.
218 boost::mutex::scoped_lock lock(mutex_);
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218 times.
218 if (lastFree_ > 0)
92 throw std::logic_error("Cannot free pool when some objects are in use.");
93
4/5
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 101 times.
✓ Branch 7 taken 217 times.
322 for (std::size_t i = 0; i < size(); ++i) delete Ts_[i];
94
1/2
✓ Branch 1 taken 218 times.
✗ Branch 2 not taken.
218 Ts_.resize(0);
95 218 }
96
97 /// Adds an object to the pool
98 /// The pool takes ownership of the object
99 4 void push_back(T* t) {
100
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 boost::mutex::scoped_lock lock(mutex_);
101
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 Ts_.push_back(t);
102 4 }
103
104 /// Add objects to the pool
105 /// The pool takes ownership of the object
106 template <class InputIterator>
107 155 void push_back(InputIterator first, InputIterator last) {
108
1/2
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
155 boost::mutex::scoped_lock lock(mutex_);
109
1/2
✓ Branch 3 taken 155 times.
✗ Branch 4 not taken.
155 Ts_.insert(Ts_.end(), first, last);
110 155 }
111
112 /// Destructor
113 /// Calls Pool::clear()
114 32 ~Pool() { clear(); }
115
116 /// Constructor
117
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 Pool() : lastFree_(0) {}
118
119 private:
120 struct OneIsAvailable {
121 const Pool& p;
122 1106 OneIsAvailable(const Pool& pool) : p(pool) {}
123 2033 bool operator()() { return p.lastFree_ < p.size(); }
124 };
125
126 boost::mutex mutex_;
127 boost::condition_variable condVariable_;
128 std::vector<T*> Ts_;
129 std::size_t lastFree_;
130 }; // class Pool
131 } // namespace pinocchio
132 } // namespace hpp
133
134 #endif // HPP_PINOCCHIO_DEVICE_HH
135