From 3e3aeddec840fed915b0fa748dcd2f56d6f682ef Mon Sep 17 00:00:00 2001 From: user Date: Mon, 9 Dec 2019 15:01:24 -0800 Subject: wip level1 allocation groups --- starts/meaning-vm/level-1/concepts.cpp | 1 + starts/meaning-vm/level-1/concepts.hpp | 1 + starts/meaning-vm/level-1/funcs.cpp | 8 ++++++++ starts/meaning-vm/level-1/memorystore.cpp | 33 +++++++++++++++++++++++++++++++ starts/meaning-vm/level-1/memorystore.hpp | 14 +++++++++++++ starts/meaning-vm/level-2/funcs.cpp | 2 +- 6 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 starts/meaning-vm/level-1/memorystore.cpp create mode 100644 starts/meaning-vm/level-1/memorystore.hpp diff --git a/starts/meaning-vm/level-1/concepts.cpp b/starts/meaning-vm/level-1/concepts.cpp index 51cd693..890d8b2 100644 --- a/starts/meaning-vm/level-1/concepts.cpp +++ b/starts/meaning-vm/level-1/concepts.cpp @@ -9,6 +9,7 @@ ref is("is"); ref anonymous("anonymous"); ref link("link"); ref name("name"); +ref allocation("allocation"), part("part"), group("group"); } } diff --git a/starts/meaning-vm/level-1/concepts.hpp b/starts/meaning-vm/level-1/concepts.hpp index 6dfc64b..b75133e 100644 --- a/starts/meaning-vm/level-1/concepts.hpp +++ b/starts/meaning-vm/level-1/concepts.hpp @@ -12,6 +12,7 @@ extern ref name; // used as the link to value naming each concept extern ref is; // a link to define group relationships, links to the more general class extern ref anonymous; // a group given concepts with generated names extern ref link; // TODO: for concepts that are links, link them with is=link +extern ref allocation, part, group; // links structuring allocation groups //extern ref true, false; <-- casting provides as if these were declared } diff --git a/starts/meaning-vm/level-1/funcs.cpp b/starts/meaning-vm/level-1/funcs.cpp index 72d3c27..c1cf21a 100644 --- a/starts/meaning-vm/level-1/funcs.cpp +++ b/starts/meaning-vm/level-1/funcs.cpp @@ -29,6 +29,14 @@ static auto & namestruct() return namestruct; } +void givename(concept* con, std::string const & name) +{ + auto & ns = namestruct(); + level0::ref namestr = level0::alloc(name); + ns.conceptsByName.emplace(namestr.val(), con); + con.set(ns.nameref, namestr); +} + concept* getnamed(std::string const & name) { auto & ns = namestruct(); diff --git a/starts/meaning-vm/level-1/memorystore.cpp b/starts/meaning-vm/level-1/memorystore.cpp new file mode 100644 index 0000000..0bd109b --- /dev/null +++ b/starts/meaning-vm/level-1/memorystore.cpp @@ -0,0 +1,33 @@ +#include "memorystore.hpp" + +#include "concepts.hpp" + +#include "../level-0/memorystore.hpp" + +namespace intellect { +namespace level1 { + +ref allocation_group("allocation-group"); +ref allocation_part("allocation-part"); + +ref alloc(ref grp, std::any data) +{ + ref res = level0::alloc(data); + keep(res, grp); +} + +void keep(ref allocated, ref grp) +{ + allocated.link(allocation_group, grp); + grp.link(allocation_part, allocated); +} + +void dealloc(ref grp, ref metagroup) +{ + +//} + +std::size_t allocatedgroups(); + +} +} diff --git a/starts/meaning-vm/level-1/memorystore.hpp b/starts/meaning-vm/level-1/memorystore.hpp new file mode 100644 index 0000000..625dad9 --- /dev/null +++ b/starts/meaning-vm/level-1/memorystore.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "common.hpp" + +namespace intellect { +namespace level1 { + +ref alloc(ref group, std::any data = {}); +void keep(ref allocated, ref group); +void dealloc(ref group, ref metagroup = concepts::nothing); +std::size_t allocatedgroups(); + +} +} diff --git a/starts/meaning-vm/level-2/funcs.cpp b/starts/meaning-vm/level-2/funcs.cpp index ed50c39..a8835f4 100644 --- a/starts/meaning-vm/level-2/funcs.cpp +++ b/starts/meaning-vm/level-2/funcs.cpp @@ -40,7 +40,7 @@ ref dohabit(ref habit, std::initializer_list args) throw std::invalid_argument("wrong number of arguments to habit"); } posarg = posarg[next-positional-argument]; - // TODO: subcontexts + // TODO: subcontexts or call instances ref::context().set(posarg[argument], arg); } if (posarg.linked(next-positional-argument)) { -- cgit v1.2.3 From 1b8c47a8b14f784f6605eee3a73713dbce6ca572 Mon Sep 17 00:00:00 2001 From: olpc user Date: Mon, 9 Dec 2019 20:38:22 -0800 Subject: changed level-0 allocation to use groups --- starts/meaning-vm/level-0/baseref.hpp | 4 +- starts/meaning-vm/level-0/concept.cpp | 1 + starts/meaning-vm/level-0/memorystore.cpp | 94 +++++++++++++++++++++++-------- starts/meaning-vm/level-0/memorystore.hpp | 37 +++++++++++- starts/meaning-vm/level-0/ref.cpp | 4 ++ starts/meaning-vm/level-1/baseref.hpp | 2 +- starts/meaning-vm/level-1/funcs.cpp | 23 ++++---- starts/meaning-vm/level-1/funcs.hpp | 2 +- starts/meaning-vm/level-1/memorystore.cpp | 33 ----------- starts/meaning-vm/level-1/memorystore.hpp | 14 ----- starts/meaning-vm/level-1/sugar.cpp | 9 ++- starts/meaning-vm/level0.cpp | 36 +++++------- starts/meaning-vm/level1.cpp | 6 ++ 13 files changed, 154 insertions(+), 111 deletions(-) delete mode 100644 starts/meaning-vm/level-1/memorystore.cpp delete mode 100644 starts/meaning-vm/level-1/memorystore.hpp diff --git a/starts/meaning-vm/level-0/baseref.hpp b/starts/meaning-vm/level-0/baseref.hpp index fbb7a28..69880c8 100644 --- a/starts/meaning-vm/level-0/baseref.hpp +++ b/starts/meaning-vm/level-0/baseref.hpp @@ -57,7 +57,7 @@ public: template T& vget(ref const & type) const { return p->vget(type.p); } template - void vset(ref const & type, T const & v) { p->set(type.p, level0::alloc(v)); } + void vset(ref const & type, T const & v) { p->set(type.p, level0::alloc(self, v)); } template T& val() { return p->val(); } @@ -100,7 +100,7 @@ private: bool operator!=(mutit const & other) const { return self.it != other.it; } val & operator*() { return *(val*)&self.it.operator*(); } - val & operator->() { return *(val*)&self.it.operator->(); } + val * operator->() { return (val*)self.it.operator->(); } private: It it; diff --git a/starts/meaning-vm/level-0/concept.cpp b/starts/meaning-vm/level-0/concept.cpp index 9bb772d..0661edd 100644 --- a/starts/meaning-vm/level-0/concept.cpp +++ b/starts/meaning-vm/level-0/concept.cpp @@ -12,6 +12,7 @@ concept* concept::id() void concept::link(concept* type, concept* target) { + if (type == 0 || target == 0) { throw null_reference(); } links.insert({type, target}); } diff --git a/starts/meaning-vm/level-0/memorystore.cpp b/starts/meaning-vm/level-0/memorystore.cpp index adae8b2..61f8ec0 100644 --- a/starts/meaning-vm/level-0/memorystore.cpp +++ b/starts/meaning-vm/level-0/memorystore.cpp @@ -8,21 +8,66 @@ namespace intellect { namespace level0 { -static auto & concepts() +static auto & index() { - static std::unordered_set> concepts; - return concepts; + static std::unordered_set> index; + return index; } -ref alloc(std::any data) { + +namespace concepts { + ref allocator() { static ref ret = new concept(); return ret; }; + ref allocates() { static ref ret = new concept(); return ret; }; + ref allocations() { static ref ret = new concept(); return ret; }; + ref level0allocations() { static ref ret = new concept(); return ret; }; +} + +struct init { init() +{ + concepts::allocator().link(concepts::allocator(), concepts::level0allocations()); + concepts::level0allocations().link(concepts::allocates(), concepts::allocator()); + index().insert(concepts::allocator()); + + concepts::allocates().link(concepts::allocator(), concepts::level0allocations()); + concepts::level0allocations().link(concepts::allocates(), concepts::allocates()); + index().insert(concepts::allocates()); + + concepts::allocations().link(concepts::allocator(), concepts::level0allocations()); + concepts::level0allocations().link(concepts::allocates(), concepts::allocations()); + index().insert(concepts::allocations()); + + concepts::level0allocations().link(concepts::allocator(), concepts::level0allocations()); + concepts::level0allocations().link(concepts::allocates(), concepts::level0allocations()); + index().insert(concepts::level0allocations()); +} } _init; + +ref alloc(ref source, std::any data) +{ concept * r = new concept(); r->data = data; - concepts().insert(r); + alloc((ref)r, source); + index().insert(r); return r; } -static concept* referenced(ref r) { - for (ref r2 : concepts()) { +void alloc(ref r, ref source) +{ + r.link(concepts::allocator(), source); + source.link(concepts::allocates(), r); +} + +void realloc(ref r, ref newsource) +{ + ref oldsource = r.get(concepts::allocator()); + alloc(r, newsource); + dealloc(r, oldsource); +} + +static concept* referenced(ref r, ref source) { + for (ref r2 : index()) { + if (r2 == source) { + continue; + } if (r2 == r) { continue; } @@ -38,28 +83,33 @@ static concept* referenced(ref r) { return 0; } -void dealloc(ref r) { - concept * referenced = intellect::level0::referenced(r); - if (referenced) { - throw still_referenced_by(r, referenced); +void dealloc(ref r, ref source) { + auto it = index().find(r); + if (it == index().end()) { throw no_such_concept(r); } + + source.unlink(concepts::allocates(), r); + r.unlink(concepts::allocator(), source); + if (r.linked(concepts::allocator())) { return; } + + index().erase(it); + + auto ours = r.getAll(concepts::allocates()); + for (auto allocation : ours) { + dealloc(allocation, r); } - for ( - auto it = concepts().begin(); - it != concepts().end(); - ++ it) - { - if (*it == r) { - concepts().erase(it); - delete (concept*)r; - return; + + for (auto ghost : ours) { + concept * referenced = intellect::level0::referenced(ghost, source); + if (referenced) { + throw still_referenced_by(ghost, referenced); } } - throw no_such_concept(r); + delete (concept*)r; } std::size_t allocated() { - return concepts().size(); + return index().size(); } } diff --git a/starts/meaning-vm/level-0/memorystore.hpp b/starts/meaning-vm/level-0/memorystore.hpp index 7843513..eff4235 100644 --- a/starts/meaning-vm/level-0/memorystore.hpp +++ b/starts/meaning-vm/level-0/memorystore.hpp @@ -7,8 +7,41 @@ namespace intellect { namespace level0 { -ref alloc(std::any data = {}); -void dealloc(ref); +// self-reference loops are real. +// +// one person can feel urgent about issue A, and act on this urgency to engage +// another person around B, who acts in a different way to someone else, eventually +// cycling back to stress that stimulates the original person to feel more urgent +// about issue A. +// human behavior can make arbitrary positive or negative feedback loops. +// +// here in memory allocation, i've designed a system intended to reduce such loops +// by encouraging my usage to be a certain way, but it still readily provides for +// them. +// +// in process expansion / simple thought, we also have the issue of recursion. +// if we trust a task to complete, and it ends up triggering itself in a subcontext, +// we could wait forever. +// +// the solution to many of these things is to recognize repetition in systems. +// we also become skeptical as things continue constantly. we expect to develop +// some level of understanding that they will shrink, or we stop them and try +// something else. + +namespace concepts { + +extern ref allocator(); // link shows what is holding something alive +extern ref allocates(); // link shows what is being held alive + +extern ref allocations(); // to use as a basic allocator for simple things +extern ref level0allocations(); // allocator for concepts internal to level0 + +} + +ref alloc(ref allocator, std::any data = {}); // new concept +void alloc(ref allocated, ref allocator); // extra ownership for concept +void realloc(ref allocated, ref allocator); // move ownership for concept to allocator +void dealloc(ref allocated, ref allocator); // remove ownership for concept std::size_t allocated(); } diff --git a/starts/meaning-vm/level-0/ref.cpp b/starts/meaning-vm/level-0/ref.cpp index d4758bd..87e911a 100644 --- a/starts/meaning-vm/level-0/ref.cpp +++ b/starts/meaning-vm/level-0/ref.cpp @@ -1,10 +1,12 @@ #include "ref.hpp" #include "concept.hpp" #include "errors.hpp" +#include "memorystore.hpp" #include using namespace intellect::level0; +using namespace concepts; std::string ref::dump(ref skipmarkertype, ref skipmarkertarget) { @@ -13,10 +15,12 @@ std::string ref::dump(ref skipmarkertype, ref skipmarkertarget) } std::string ret = std::to_string((unsigned long)ptr()) + ":\n"; for (auto & link : self.links()) { + if (link.first.linked(allocator(), level0allocations())) { continue; } ret += " " + std::to_string((unsigned long)link.first.ptr()) + ": " + std::to_string((unsigned long)link.second.ptr()) + "\n"; } self.link(skipmarkertype, skipmarkertarget); for (auto & link : self.links()) { + if (link.first.linked(allocator(), level0allocations())) { continue; } if (link.first == skipmarkertype && link.second == skipmarkertarget) { continue; } diff --git a/starts/meaning-vm/level-1/baseref.hpp b/starts/meaning-vm/level-1/baseref.hpp index e97db2d..5055d44 100644 --- a/starts/meaning-vm/level-1/baseref.hpp +++ b/starts/meaning-vm/level-1/baseref.hpp @@ -31,7 +31,7 @@ struct baseref : public level0::baseref ref operator[](ref subref) const { return self.get(subref); } template - void vset(ref const & type, T const & v) { self.set(type, level1::alloc(v)); } + void vset(ref const & type, T const & v) { self.set(type, level1::alloc(level0::concepts::allocations(), v)); } template std::function & fun() { return self.template val>(); } diff --git a/starts/meaning-vm/level-1/funcs.cpp b/starts/meaning-vm/level-1/funcs.cpp index c1cf21a..cfb44b7 100644 --- a/starts/meaning-vm/level-1/funcs.cpp +++ b/starts/meaning-vm/level-1/funcs.cpp @@ -19,9 +19,9 @@ static auto & namestruct() std::unordered_map,std::equal_to> conceptsByName; ref nameref; name_t() - : nameref(level0::alloc()) + : nameref(level0::alloc(level0::concepts::allocations())) { - level0::ref namestr = alloc((std::string)("name")); + level0::ref namestr = level0::alloc(nameref.ptr(), (std::string)("name")); nameref.set(nameref, namestr); conceptsByName.emplace(namestr.val(), nameref); } @@ -32,9 +32,9 @@ static auto & namestruct() void givename(concept* con, std::string const & name) { auto & ns = namestruct(); - level0::ref namestr = level0::alloc(name); + level0::ref namestr = level0::alloc(con, name); ns.conceptsByName.emplace(namestr.val(), con); - con.set(ns.nameref, namestr); + con->set(ns.nameref, namestr); } concept* getnamed(std::string const & name) @@ -44,10 +44,8 @@ concept* getnamed(std::string const & name) if (res != ns.conceptsByName.end()) { return res->second; } else { - level1::ref con = level0::alloc(); - level0::ref namestr = level0::alloc(name); - ns.conceptsByName.emplace(namestr.val(), con); - con.set(ns.nameref, namestr); + level1::ref con = level0::alloc(level0::concepts::allocations()); + givename(con, name); return con.ptr(); } } @@ -71,10 +69,9 @@ bool isa(concept* member, concept* group) return false; } -concept* alloc(std::any val) +concept* alloc(concept* allocator, std::any val) { - - ref ret = level0::alloc(val); + ref ret = level0::alloc(allocator, val); std::stringstream ss; ss << val.type().name() << "("; if (false); @@ -88,7 +85,7 @@ concept* alloc(std::any val) #undef t else { ss << "?"; } ss << ")"; - ret.link(concepts::name, level0::alloc(ss.str())); + ret.link(concepts::name, level0::alloc(ret, ss.str())); return ret; } @@ -104,6 +101,7 @@ std::string dump(concept* what, concept* skipmarkertype, concept* skipmarkertarg } std::string ret; for (auto & link : ref(what).links()) { + if (link.first.linked(level0::concepts::allocator(), level0::concepts::level0allocations())) { continue; } if (link.first == concepts::name) { continue; } if (ret.size() == 0) { ret = ref(what).name() + ":\n"; @@ -112,6 +110,7 @@ std::string dump(concept* what, concept* skipmarkertype, concept* skipmarkertarg } what->link(skipmarkertype, skipmarkertarget); for (auto & link : ref(what).links()) { + if (link.first.linked(level0::concepts::allocator(), level0::concepts::level0allocations())) { continue; } if (link.first.ptr() == skipmarkertype && link.second.ptr() == skipmarkertarget) { continue; } diff --git a/starts/meaning-vm/level-1/funcs.hpp b/starts/meaning-vm/level-1/funcs.hpp index 4b53ddd..9361917 100644 --- a/starts/meaning-vm/level-1/funcs.hpp +++ b/starts/meaning-vm/level-1/funcs.hpp @@ -18,7 +18,7 @@ bool isa(concept* member, concept* group); concept* hyphenate(concept* a, concept* b); -concept* alloc(std::any val); +concept* alloc(concept* allocator, std::any val); std::string dump(concept * what, concept * skipmarkertype, concept * skipmarkertarget); diff --git a/starts/meaning-vm/level-1/memorystore.cpp b/starts/meaning-vm/level-1/memorystore.cpp deleted file mode 100644 index 0bd109b..0000000 --- a/starts/meaning-vm/level-1/memorystore.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "memorystore.hpp" - -#include "concepts.hpp" - -#include "../level-0/memorystore.hpp" - -namespace intellect { -namespace level1 { - -ref allocation_group("allocation-group"); -ref allocation_part("allocation-part"); - -ref alloc(ref grp, std::any data) -{ - ref res = level0::alloc(data); - keep(res, grp); -} - -void keep(ref allocated, ref grp) -{ - allocated.link(allocation_group, grp); - grp.link(allocation_part, allocated); -} - -void dealloc(ref grp, ref metagroup) -{ - -//} - -std::size_t allocatedgroups(); - -} -} diff --git a/starts/meaning-vm/level-1/memorystore.hpp b/starts/meaning-vm/level-1/memorystore.hpp deleted file mode 100644 index 625dad9..0000000 --- a/starts/meaning-vm/level-1/memorystore.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "common.hpp" - -namespace intellect { -namespace level1 { - -ref alloc(ref group, std::any data = {}); -void keep(ref allocated, ref group); -void dealloc(ref group, ref metagroup = concepts::nothing); -std::size_t allocatedgroups(); - -} -} diff --git a/starts/meaning-vm/level-1/sugar.cpp b/starts/meaning-vm/level-1/sugar.cpp index 24d59be..21f4001 100644 --- a/starts/meaning-vm/level-1/sugar.cpp +++ b/starts/meaning-vm/level-1/sugar.cpp @@ -49,15 +49,17 @@ ref movetoname(ref anonymous, ref name) // information is not available at this level. bool nonempty = false; for (auto & l : name.links()) { + if (l.first.linked(level0::concepts::allocator(), level0::concepts::level0allocations())) { continue; } if (l.first == concepts::name) { continue; } nonempty = true; } if (nonempty) { for (auto & link : anonymous.links()) { if (link.first == concepts::is && link.second == concepts::anonymous) { continue; } + if (link.first.linked(level0::concepts::allocator(), level0::concepts::level0allocations())) { continue; } if (link.first == concepts::name) { continue; } if (!name.linked(link.first, link.second)) { - throw std::logic_error(name.name() + " already defined otherwise from " + anonymous.get(concepts::is).name()); + throw std::logic_error(name.name() + " already defined otherwise from " + anonymous.getAll(concepts::is).begin()->name()); } } } @@ -66,12 +68,13 @@ ref movetoname(ref anonymous, ref name) anonymous.unlink(concepts::name, nam); if (!nonempty) { for (auto & l : anonymous.links()) { + if (l.first.linked(level0::concepts::allocator(), level0::concepts::level0allocations())) { continue; } name.link(l.first, l.second); } } anonymous.link(concepts::name, nam); - dealloc(anonymous); - dealloc(nam); + dealloc(anonymous, level0::concepts::allocations()); + //dealloc(nam, level0::concepts::allocations()); return name; } diff --git a/starts/meaning-vm/level0.cpp b/starts/meaning-vm/level0.cpp index 6ff0102..86ce0cd 100644 --- a/starts/meaning-vm/level0.cpp +++ b/starts/meaning-vm/level0.cpp @@ -5,17 +5,21 @@ using namespace intellect::level0; +#define out(name) std::cout << " " #name ":" << (long)name.ptr() + int main() { - ref a = alloc(); - ref b = alloc(); - ref c = alloc(); - ref d = alloc(); - ref e = alloc(); - auto numlink = alloc(); - auto codelink = alloc(); - - ref skip = alloc(); + ref store = alloc(concepts::allocations()); out(store); + ref a = alloc(store); out(a); + ref b = alloc(store); out(b); + ref c = alloc(store); out(c); + ref d = alloc(store); out(d); + ref e = alloc(store); out(e); + auto numlink = alloc(a); out(numlink); + auto codelink = alloc(a); out(codelink); + + ref skip = alloc(store); out(skip); + std::cout << std::endl; a.link( b, c, @@ -37,18 +41,8 @@ int main() std::cout << allocated() << " allocated" << std::endl; e.unlink(b, a); - auto num = a.get(numlink); - auto code = a.get(codelink); - dealloc(a); - dealloc(num); - dealloc(code); - dealloc(numlink); - dealloc(codelink); - dealloc(c); - dealloc(e); - dealloc(b); - dealloc(d); - dealloc(skip); + //dealloc(a, store); + dealloc(store, concepts::allocations()); std::cout << allocated() << " allocated" << std::endl; diff --git a/starts/meaning-vm/level1.cpp b/starts/meaning-vm/level1.cpp index 9498ddf..b1d06f1 100644 --- a/starts/meaning-vm/level1.cpp +++ b/starts/meaning-vm/level1.cpp @@ -7,6 +7,8 @@ using namespace intellect::level1::concepts; int main() { + std::cout << intellect::level0::allocated() << " allocated" << std::endl; + decls(make, linked, habit); decls(needs, assumes, makes); decls(not, topic); @@ -61,5 +63,9 @@ int main() std::cout << apple.dump("dumped", true) << std::endl; + std::cout << intellect::level0::allocated() << " allocated" << std::endl; + intellect::level0::dealloc(intellect::level0::concepts::allocations(), intellect::level0::concepts::level0allocations()); + std::cout << intellect::level0::allocated() << " allocated" << std::endl; + return 0; } -- cgit v1.2.3 From 363fea37f8943ca3d9b3241660bf271fb6e54bc5 Mon Sep 17 00:00:00 2001 From: olpc user Date: Tue, 10 Dec 2019 04:26:00 -0800 Subject: bugfix with level1 allocation demo --- starts/meaning-vm/level1.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/starts/meaning-vm/level1.cpp b/starts/meaning-vm/level1.cpp index b1d06f1..aa945b3 100644 --- a/starts/meaning-vm/level1.cpp +++ b/starts/meaning-vm/level1.cpp @@ -10,6 +10,7 @@ int main() std::cout << intellect::level0::allocated() << " allocated" << std::endl; decls(make, linked, habit); + std::cout << intellect::level0::allocated() << " allocated" << std::endl; decls(needs, assumes, makes); decls(not, topic); decls(A, B, C); @@ -64,7 +65,7 @@ int main() std::cout << apple.dump("dumped", true) << std::endl; std::cout << intellect::level0::allocated() << " allocated" << std::endl; - intellect::level0::dealloc(intellect::level0::concepts::allocations(), intellect::level0::concepts::level0allocations()); + intellect::level0::dealloc(intellect::level0::concepts::allocations(), intellect::level0::concepts::allocations()); std::cout << intellect::level0::allocated() << " allocated" << std::endl; return 0; -- cgit v1.2.3 From d84b81bc12e6a22e442d5dce38e59222119311f0 Mon Sep 17 00:00:00 2001 From: olpc user Date: Tue, 10 Dec 2019 06:55:35 -0800 Subject: readded basic allocation; held pointers with a std::unique_ptr; added some words around increasing relevence --- starts/meaning-vm/level-0/memorystore.cpp | 112 +++++++++++++++++++++++------- starts/meaning-vm/level-0/memorystore.hpp | 4 ++ starts/meaning-vm/level0.cpp | 2 + starts/meaning-vm/level1.cpp | 2 +- starts/meaning-vm/makefile | 2 +- 5 files changed, 93 insertions(+), 29 deletions(-) diff --git a/starts/meaning-vm/level-0/memorystore.cpp b/starts/meaning-vm/level-0/memorystore.cpp index 61f8ec0..220d0c3 100644 --- a/starts/meaning-vm/level-0/memorystore.cpp +++ b/starts/meaning-vm/level-0/memorystore.cpp @@ -3,50 +3,53 @@ #include "errors.hpp" #include "ref.hpp" -#include +#include +#include namespace intellect { namespace level0 { static auto & index() { - static std::unordered_set> index; + static std::unordered_map, std::hash> index; return index; } namespace concepts { - ref allocator() { static ref ret = new concept(); return ret; }; - ref allocates() { static ref ret = new concept(); return ret; }; - ref allocations() { static ref ret = new concept(); return ret; }; - ref level0allocations() { static ref ret = new concept(); return ret; }; + ref allocator() { static ref ret = basic_alloc(); return ret; }; + ref allocates() { static ref ret = basic_alloc(); return ret; }; + ref allocations() { static ref ret = basic_alloc(); return ret; }; + ref level0allocations() { static ref ret = basic_alloc(); return ret; }; } struct init { init() { concepts::allocator().link(concepts::allocator(), concepts::level0allocations()); concepts::level0allocations().link(concepts::allocates(), concepts::allocator()); - index().insert(concepts::allocator()); concepts::allocates().link(concepts::allocator(), concepts::level0allocations()); concepts::level0allocations().link(concepts::allocates(), concepts::allocates()); - index().insert(concepts::allocates()); concepts::allocations().link(concepts::allocator(), concepts::level0allocations()); concepts::level0allocations().link(concepts::allocates(), concepts::allocations()); - index().insert(concepts::allocations()); concepts::level0allocations().link(concepts::allocator(), concepts::level0allocations()); concepts::level0allocations().link(concepts::allocates(), concepts::level0allocations()); - index().insert(concepts::level0allocations()); } } _init; +ref basic_alloc(std::any data) +{ + ref r = new concept(); + r.ptr()->data = data; + index().emplace(r, r.ptr()); + return r; +} + ref alloc(ref source, std::any data) { - concept * r = new concept(); - r->data = data; - alloc((ref)r, source); - index().insert(r); + ref r = basic_alloc(data); + alloc(r, source); return r; } @@ -63,9 +66,10 @@ void realloc(ref r, ref newsource) dealloc(r, oldsource); } -static concept* referenced(ref r, ref source) { - for (ref r2 : index()) { - if (r2 == source) { +static concept* referenced(ref r, concept* source = 0) { + for (auto & r2pair : index()) { + ref r2 = r2pair.first; + if (r2.ptr() == source) { continue; } if (r2 == r) { @@ -83,28 +87,82 @@ static concept* referenced(ref r, ref source) { return 0; } -void dealloc(ref r, ref source) { +void basic_dealloc(ref r) +{ auto it = index().find(r); if (it == index().end()) { throw no_such_concept(r); } - source.unlink(concepts::allocates(), r); - r.unlink(concepts::allocator(), source); - if (r.linked(concepts::allocator())) { return; } + concept * referenced = intellect::level0::referenced(r); + if (referenced) { + throw still_referenced_by(r, referenced); + } index().erase(it); +} + +void dealloc_from(ref source) +{ + std::remove_reference::type forgotten; - auto ours = r.getAll(concepts::allocates()); + auto ours = source.getAll(concepts::allocates()); for (auto allocation : ours) { - dealloc(allocation, r); + source.unlink(concepts::allocates(), allocation); + allocation.unlink(concepts::allocator(), source); + if (allocation.linked(concepts::allocator())) { continue; } + + auto it = index().find(allocation); + if (it != index().end()) { + forgotten.insert(index().extract(it)); + } + } + try { + for (auto allocation : ours ) { + if (allocation.linked(concepts::allocates())) { + dealloc_from(allocation); + } + } + for (auto ghost : ours) { + concept * referenced = intellect::level0::referenced(ghost, source); + if (referenced) { + throw still_referenced_by(ghost, referenced); + } + } + } catch(...) { + // NOTE: this doesn't rebuild deallocated subgroups, but that could be done + // by returning them. + index().merge(forgotten); + for (auto allocation : ours) { + source.link(concepts::allocates(), allocation); + allocation.link(concepts::allocator(), source); + } + throw; } - for (auto ghost : ours) { - concept * referenced = intellect::level0::referenced(ghost, source); + // concepts in forgotten will be deallocated when they leave scope + // note: scoped allocation is just a plan to forget (at the end of a { } block) +} + +void dealloc(ref r, ref source) +{ + auto it = index().find(r); + if (it == index().end()) { throw no_such_concept(r); } + + source.unlink(concepts::allocates(), r); + r.unlink(concepts::allocator(), source); + if (r.linked(concepts::allocator())) { return; } + + try { + dealloc_from(r); + concept * referenced = intellect::level0::referenced(r, source); if (referenced) { - throw still_referenced_by(ghost, referenced); + throw still_referenced_by(r, referenced); } + + index().erase(it); + } catch(...) { + source.link(concepts::allocates(), r); + r.link(concepts::allocator(), source); } - delete (concept*)r; } std::size_t allocated() diff --git a/starts/meaning-vm/level-0/memorystore.hpp b/starts/meaning-vm/level-0/memorystore.hpp index eff4235..f4faa13 100644 --- a/starts/meaning-vm/level-0/memorystore.hpp +++ b/starts/meaning-vm/level-0/memorystore.hpp @@ -38,9 +38,13 @@ extern ref level0allocations(); // allocator for concepts internal to level0 } +ref basic_alloc(std::any data = {}); +void basic_dealloc(ref allocated); + ref alloc(ref allocator, std::any data = {}); // new concept void alloc(ref allocated, ref allocator); // extra ownership for concept void realloc(ref allocated, ref allocator); // move ownership for concept to allocator +[[deprecated("can make recursion: turn to workable habits")]] void dealloc(ref allocated, ref allocator); // remove ownership for concept std::size_t allocated(); diff --git a/starts/meaning-vm/level0.cpp b/starts/meaning-vm/level0.cpp index 86ce0cd..4ab8b7b 100644 --- a/starts/meaning-vm/level0.cpp +++ b/starts/meaning-vm/level0.cpp @@ -9,6 +9,8 @@ using namespace intellect::level0; int main() { + std::cout << allocated() << " allocated" << std::endl; + ref store = alloc(concepts::allocations()); out(store); ref a = alloc(store); out(a); ref b = alloc(store); out(b); diff --git a/starts/meaning-vm/level1.cpp b/starts/meaning-vm/level1.cpp index aa945b3..3c1a634 100644 --- a/starts/meaning-vm/level1.cpp +++ b/starts/meaning-vm/level1.cpp @@ -65,7 +65,7 @@ int main() std::cout << apple.dump("dumped", true) << std::endl; std::cout << intellect::level0::allocated() << " allocated" << std::endl; - intellect::level0::dealloc(intellect::level0::concepts::allocations(), intellect::level0::concepts::allocations()); + intellect::level0::dealloc(intellect::level0::concepts::allocations(), intellect::level0::concepts::level0allocations()); std::cout << intellect::level0::allocated() << " allocated" << std::endl; return 0; diff --git a/starts/meaning-vm/makefile b/starts/meaning-vm/makefile index 325a07c..637c4fe 100644 --- a/starts/meaning-vm/makefile +++ b/starts/meaning-vm/makefile @@ -1,4 +1,4 @@ -CXXFLAGS=-Wall -Werror -std=gnu++17 -fno-operator-names -ggdb -O0 +CXXFLAGS=-Wall -Werror -Wno-error=deprecated-declarations -std=gnu++17 -fno-operator-names -ggdb -O0 LINK.o=$(LINK.cc) all: level0 level1 habit-starts/rhythm -- cgit v1.2.3