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 ++ 5 files changed, 114 insertions(+), 26 deletions(-) (limited to 'starts/meaning-vm/level-0') 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; } -- cgit v1.2.3