* src/tgba/bdddict.cc, src/tgba/bdddict.hh (free_annonymous_list_of):

Rename as ...
(free_anonymous_list_of): ... this, and correct their update on
release.  Also correct yesterday's the correction (ahem!).
(dump): Improve verbosity.
* src/misc/freelist.cc (free_list::remove, free_list::insert): Fix
longstanding thinkos.
(free_list::free_count): New function.
This commit is contained in:
Alexandre Duret-Lutz 2006-07-14 15:30:23 +00:00
parent 064319b3e4
commit 9e97543e33
5 changed files with 123 additions and 49 deletions

View file

@ -1,5 +1,14 @@
2006-07-14 Alexandre Duret-Lutz <adl@src.lip6.fr> 2006-07-14 Alexandre Duret-Lutz <adl@src.lip6.fr>
* src/tgba/bdddict.cc, src/tgba/bdddict.hh (free_annonymous_list_of):
Rename as ...
(free_anonymous_list_of): ... this, and correct their update on
release. Also correct yesterday's the correction (ahem!).
(dump): Improve verbosity.
* src/misc/freelist.cc (free_list::remove, free_list::insert): Fix
longstanding thinkos.
(free_list::free_count): New function.
Merge this fix from proviso-branch: Merge this fix from proviso-branch:
2006-05-22 Alexandre Duret-Lutz <adl@src.lip6.fr> 2006-05-22 Alexandre Duret-Lutz <adl@src.lip6.fr>
* src/misc/bddalloc.cc (bdd_allocator::bdd_allocator): Count the * src/misc/bddalloc.cc (bdd_allocator::bdd_allocator): Count the

View file

@ -1,4 +1,4 @@
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
@ -73,13 +73,31 @@ namespace spot
for (cur = fl.begin(); cur != fl.end(); ++cur) for (cur = fl.begin(); cur != fl.end(); ++cur)
{ {
int cend = cur->first + cur->second; int cend = cur->first + cur->second;
// cur [...]
// to insert [...]
// -----------------------
// result [...] [...]
// (Insert a new range, unconnected.)
if (cur->first > end)
{
break;
}
// cur [...]
// to insert [...]
// -----------------------
// result unknown : we should look at the rest of the freelist.
else if (base > cend)
{
continue;
}
// cur [....[ [......[ // cur [....[ [......[
// to insert [....[ [..[ // to insert [....[ [..[
// ---------------------------------- // ----------------------------------
// result [......[ [......[ // result [......[ [......[
if (cend >= base) else if (cur->first <= base)
{ {
if (cend >= end) if (cend >= end)
// second case : nothing to do
return; return;
// cur->second is set below. // cur->second is set below.
} }
@ -87,27 +105,21 @@ namespace spot
// to insert [....[ [.......[ // to insert [....[ [.......[
// ---------------------------------- // ----------------------------------
// result [......[ [.......[ // result [......[ [.......[
else if (cend >= base && cur->first <= end) else
{ {
cur->first = base; cur->first = base;
if (cend >= end)
return;
// cur->second is set below. // cur->second is set below.
} }
else if (cur->first > end)
// Insert a new range, unconnected.
break;
else
continue;
// We get here in one of these two situations: // We get here in one of these three situations:
// //
// cur [....[ [..[ // cur [....[ [....[ [..[
// to insert [....[ [.......[ // to insert [....[ [....[ [.......[
// ---------------------------------- // -------------------------------------------
// result [......[ [.......[ // result [......[ [......[ [.......[
// //
// cur->first is already set, be cur->second has yet to be. // cur->first is already set, be cur->second has yet to be.
end = std::max(cend, end);
cur->second = end - cur->first; cur->second = end - cur->first;
// Since we have extended the current range, maybe the next // Since we have extended the current range, maybe the next
// items on the list should be merged. // items on the list should be merged.
@ -115,8 +127,8 @@ namespace spot
++next; ++next;
while (next != fl.end() && next->first <= end) while (next != fl.end() && next->first <= end)
{ {
cur->second = end = std::max(next->first + next->second, end);
std::max(next->first + next->second, end) - cur->first; cur->second = end - cur->first;
free_list_type::iterator next2 = next++; free_list_type::iterator next2 = next++;
fl.erase(next2); fl.erase(next2);
} }
@ -133,13 +145,17 @@ namespace spot
{ {
free_list_type::iterator cur = fl.begin(); free_list_type::iterator cur = fl.begin();
int end = base + n; int end = base + n;
while (cur != fl.end() && cur->first <= end) while (cur != fl.end() && cur->first < end)
{ {
int cend = cur->first + cur->second; int cend = cur->first + cur->second;
// Remove may invalidate the current iterator, so advance it first. // Remove may invalidate the current iterator, so advance it first.
free_list_type::iterator old = cur++; free_list_type::iterator old = cur++;
if (cend >= end) if (cend >= base)
remove(old, base, std::max(n, cend - base)); {
int newbase = std::max(base, old->first);
int q = std::min(cend, end) - newbase;
remove(old, newbase, q);
}
} }
} }
@ -148,6 +164,7 @@ namespace spot
{ {
if (base == i->first) if (base == i->first)
{ {
// Removing at the beginning of the range
i->second -= n; i->second -= n;
assert(i->second >= 0); assert(i->second >= 0);
// Erase the range if it's now empty. // Erase the range if it's now empty.
@ -158,6 +175,7 @@ namespace spot
} }
else if (base + n == i->first + i->second) else if (base + n == i->first + i->second)
{ {
// Removing at the end of the range
i->second -= n; i->second -= n;
assert(i->second > 0); // cannot be empty because base != i->first assert(i->second > 0); // cannot be empty because base != i->first
} }
@ -166,7 +184,7 @@ namespace spot
// Removing in the middle of a range. // Removing in the middle of a range.
int b1 = i->first; int b1 = i->first;
int n1 = base - i->first; int n1 = base - i->first;
int n2 = i->second - n - base; int n2 = i->first + i->second - base - n;
assert(n1 > 0); assert(n1 > 0);
assert(n2 > 0); assert(n2 > 0);
*i = pos_lenght_pair(base + n, n2); *i = pos_lenght_pair(base + n, n2);
@ -174,7 +192,6 @@ namespace spot
} }
} }
void void
free_list::release_n(int base, int n) free_list::release_n(int base, int n)
{ {
@ -190,5 +207,14 @@ namespace spot
return os; return os;
} }
int
free_list::free_count() const
{
int res = 0;
free_list_type::const_iterator i;
for (i = fl.begin(); i != fl.end(); ++i)
res += i->second;
return res;
}
} }

View file

@ -1,4 +1,4 @@
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
@ -55,6 +55,9 @@ namespace spot
/// Remove \a n consecutive entries from the list, starting at \a base. /// Remove \a n consecutive entries from the list, starting at \a base.
void remove(int base, int n = 0); void remove(int base, int n = 0);
/// Return the number of free integers on the list.
int free_count() const;
protected: protected:
/// Allocate \a n integer. /// Allocate \a n integer.

View file

@ -33,7 +33,7 @@ namespace spot
next_to_now(bdd_newpair()), next_to_now(bdd_newpair()),
now_to_next(bdd_newpair()) now_to_next(bdd_newpair())
{ {
free_annonymous_list_of[0] = annon_free_list(this); free_anonymous_list_of[0] = anon_free_list(this);
} }
bdd_dict::~bdd_dict() bdd_dict::~bdd_dict()
@ -143,18 +143,20 @@ namespace spot
int int
bdd_dict::register_anonymous_variables(int n, const void* for_me) bdd_dict::register_anonymous_variables(int n, const void* for_me)
{ {
free_annonymous_list_of_type::iterator i = free_anonymous_list_of_type::iterator i =
free_annonymous_list_of.find(for_me); free_anonymous_list_of.find(for_me);
if (i == free_annonymous_list_of.end()) if (i == free_anonymous_list_of.end())
{ {
typedef free_annonymous_list_of_type fal; typedef free_anonymous_list_of_type fal;
i = (free_annonymous_list_of.insert i = (free_anonymous_list_of.insert
(fal::value_type(for_me, free_annonymous_list_of[0]))).first; (fal::value_type(for_me, free_anonymous_list_of[0]))).first;
} }
int res = i->second.register_n(n); int res = i->second.register_n(n);
while (n--) while (n--)
var_refs[res + n].insert(for_me); var_refs[res + n].insert(for_me);
return res; return res;
} }
@ -170,7 +172,11 @@ namespace spot
if (s.find(from_other) != s.end()) if (s.find(from_other) != s.end())
s.insert(for_me); s.insert(for_me);
} }
free_annonymous_list_of[for_me] = free_annonymous_list_of[from_other];
free_anonymous_list_of_type::const_iterator j =
free_anonymous_list_of.find(from_other);
if (j != free_anonymous_list_of.end())
free_anonymous_list_of[for_me] = j->second;
} }
void void
@ -188,14 +194,23 @@ namespace spot
ref_set::iterator si = s.find(me); ref_set::iterator si = s.find(me);
if (si == s.end()) if (si == s.end())
return; return;
s.erase(si); s.erase(si);
int var = cur->first;
// If var is anonymous, we should reinsert it into the free list
// of ME's anonymous variables.
if (var_formula_map.find(var) == var_formula_map.end()
&& now_formula_map.find(var) == now_formula_map.end()
&& acc_formula_map.find(var) == acc_formula_map.end())
free_anonymous_list_of[me].release_n(var, 1);
if (!s.empty()) if (!s.empty())
return; return;
// ME was the last user of this variable. // ME was the last user of this variable.
// Let's free it. First, we need to find // Let's free it. First, we need to find
// if this is a Now, a Var, or an Acc variable. // if this is a Now, a Var, or an Acc variable.
int var = cur->first;
int n = 1; int n = 1;
const ltl::formula* f = 0; const ltl::formula* f = 0;
vf_map::iterator vi = var_formula_map.find(var); vf_map::iterator vi = var_formula_map.find(var);
@ -228,10 +243,13 @@ namespace spot
} }
else else
{ {
free_annonymous_list_of_type::iterator i; free_anonymous_list_of_type::iterator i;
for (i = free_annonymous_list_of.begin(); // Nobody use this variable as an anonymous variable
i != free_annonymous_list_of.end(); ++i) // anymore, so remove it entirely from the anonymous
i->second.release_n(var, n); // free list so it can be used for something else.
for (i = free_anonymous_list_of.begin();
i != free_anonymous_list_of.end(); ++i)
i->second.remove(var, n);
} }
} }
} }
@ -254,7 +272,7 @@ namespace spot
vr_map::iterator cur = i++; vr_map::iterator cur = i++;
unregister_variable(cur, me); unregister_variable(cur, me);
} }
free_annonymous_list_of.erase(me); free_anonymous_list_of.erase(me);
} }
bool bool
@ -315,6 +333,24 @@ namespace spot
<< var_refs.find(fi->second)->second.size() << "): Acc["; << var_refs.find(fi->second)->second.size() << "): Acc[";
to_string(fi->first, os) << "]" << std::endl; to_string(fi->first, os) << "]" << std::endl;
} }
os << "Ref counts:" << std::endl;
vr_map::const_iterator ri;
for (ri = var_refs.begin(); ri != var_refs.end(); ++ri)
{
os << " " << ri->first << " :";
for (ref_set::const_iterator si = ri->second.begin();
si != ri->second.end(); ++si)
os << " " << *si;
os << std::endl;
}
os << "Anonymous lists:" << std::endl;
free_anonymous_list_of_type::const_iterator ai;
for (ai = free_anonymous_list_of.begin();
ai != free_anonymous_list_of.end(); ++ai)
{
os << " [" << ai->first << "] ";
ai->second.dump_free_list(os) << std::endl;
}
os << "Free list:" << std::endl; os << "Free list:" << std::endl;
dump_free_list(os); dump_free_list(os);
os << std::endl; os << std::endl;
@ -368,20 +404,20 @@ namespace spot
} }
bdd_dict::annon_free_list::annon_free_list(bdd_dict* d) bdd_dict::anon_free_list::anon_free_list(bdd_dict* d)
: dict_(d) : dict_(d)
{ {
} }
int int
bdd_dict::annon_free_list::extend(int n) bdd_dict::anon_free_list::extend(int n)
{ {
assert(dict_); assert(dict_);
int b = dict_->allocate_variables(n); int b = dict_->allocate_variables(n);
free_annonymous_list_of_type::iterator i; free_anonymous_list_of_type::iterator i;
for (i = dict_->free_annonymous_list_of.begin(); for (i = dict_->free_anonymous_list_of.begin();
i != dict_->free_annonymous_list_of.end(); ++i) i != dict_->free_anonymous_list_of.end(); ++i)
if (&i->second != this) if (&i->second != this)
i->second.insert(b, n); i->second.insert(b, n);
return b; return b;

View file

@ -1,4 +1,4 @@
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
@ -172,13 +172,13 @@ namespace spot
// SWIG does not grok the following definition, no idea why. // SWIG does not grok the following definition, no idea why.
// It's not important for the Python interface anyway. // It's not important for the Python interface anyway.
#ifndef SWIG #ifndef SWIG
class annon_free_list : public spot::free_list class anon_free_list : public spot::free_list
{ {
public: public:
// WARNING: We need a default constructor so this can be used in // WARNING: We need a default constructor so this can be used in
// a hash; but we should ensure that no object in the hash is // a hash; but we should ensure that no object in the hash is
// constructed with d==0. // constructed with d==0.
annon_free_list(bdd_dict* d = 0); anon_free_list(bdd_dict* d = 0);
virtual int extend(int n); virtual int extend(int n);
private: private:
bdd_dict* dict_; bdd_dict* dict_;
@ -186,8 +186,8 @@ namespace spot
#endif #endif
/// List of unused anonymous variable number for each automaton. /// List of unused anonymous variable number for each automaton.
typedef std::map<const void*, annon_free_list> free_annonymous_list_of_type; typedef std::map<const void*, anon_free_list> free_anonymous_list_of_type;
free_annonymous_list_of_type free_annonymous_list_of; free_anonymous_list_of_type free_anonymous_list_of;
private: private:
// Disallow copy. // Disallow copy.