64 template <
class T>
class ratelier_scatter
67 ratelier_scatter(
unsigned int size,
signed int flag = 0);
68 ratelier_scatter(
const ratelier_scatter & ref) =
delete;
69 ratelier_scatter(ratelier_scatter && ref) =
default;
70 ratelier_scatter & operator = (
const ratelier_scatter & ref) =
delete;
71 ratelier_scatter & operator = (ratelier_scatter && ref)
noexcept =
default;
72 virtual ~ratelier_scatter() =
default;
84 void scatter(std::unique_ptr<T> & one,
signed int flag = 0);
94 std::unique_ptr<T>
worker_get_one(
unsigned int & slot,
signed int & flag);
103 static const unsigned int cond_empty = 0;
104 static const unsigned int cond_full = 1;
108 std::unique_ptr<T> obj;
113 slot(
signed int val) { empty =
true; flag = val; };
114 slot(
const slot & ref) { obj.reset(); empty = ref.empty; index = ref.index; flag = ref.flag; };
117 unsigned int next_index;
118 unsigned int lowest_index;
119 std::vector<slot> table;
120 std::map<unsigned int, unsigned int> corres;
121 std::deque<unsigned int> empty_slot;
138 unsigned int tableindex;
143 while(empty_slot.empty())
144 verrou.wait(cond_full);
146 tableindex = empty_slot.back();
150 if(tableindex >= table.size())
152 if( ! table[tableindex].empty)
157 table[tableindex].empty =
false;
158 table[tableindex].obj = std::move(one);
159 table[tableindex].index = next_index;
160 table[tableindex].flag = flag;
162 corres[next_index] = tableindex;
165 empty_slot.pop_back();
166 if(verrou.get_waiting_thread_count(cond_empty) > 0)
167 verrou.signal(cond_empty);
172 verrou.broadcast(cond_empty);
173 verrou.broadcast(cond_full);
181 std::unique_ptr<T> ret;
186 std::map<unsigned int, unsigned int>::iterator it = corres.begin();
192 if(it != corres.end())
194 if(it->first < lowest_index)
201 if(it->second >= table.size())
203 if(table[it->second].empty)
205 if( ! table[it->second].obj)
210 ret = std::move(table[it->second].obj);
211 slot = table[it->second].index;
212 flag = table[it->second].flag;
213 table[it->second].empty =
true;
215 if(lowest_index != slot)
221 empty_slot.push_back(it->second);
224 if(verrou.get_waiting_thread_count(cond_full) > 0)
225 verrou.signal(cond_full);
232 verrou.wait(cond_empty);
241 verrou.broadcast(cond_empty);
242 verrou.broadcast(cond_full);