mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +01:00
get MemoryContext with get()
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -75,3 +75,5 @@ fabric.properties
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
Testing
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "VM.h"
|
||||
|
||||
int main() {
|
||||
MemoryContext mc;
|
||||
Handle repl;
|
||||
{
|
||||
Parser parser;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -14,7 +15,6 @@
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
#include "Cell.h"
|
||||
#include "Handle.h"
|
||||
@@ -28,6 +28,8 @@ public:
|
||||
MemoryContext();
|
||||
~MemoryContext();
|
||||
|
||||
static MemoryContext &get();
|
||||
|
||||
template<typename CT, typename... Args>
|
||||
Handle create_cell(Args... args) {
|
||||
return alloc_cell<CT>(std::forward<Args>(args)...);
|
||||
@@ -136,6 +138,4 @@ private:
|
||||
std::atomic<bool> _gc_thread_stop = false;
|
||||
};
|
||||
|
||||
extern std::atomic<MemoryContext *> CURRENT_MC;
|
||||
|
||||
#endif//PSIL_MEMORYCONTEXT_H
|
||||
|
||||
@@ -8,17 +8,17 @@
|
||||
|
||||
Handle::Handle(Cell *target) : _target(target) {
|
||||
if (target != nullptr)
|
||||
CURRENT_MC.load()->add_root(target);
|
||||
MemoryContext::get().add_root(target);
|
||||
}
|
||||
|
||||
Handle::~Handle() {
|
||||
if (_target != nullptr)
|
||||
CURRENT_MC.load()->remove_root(_target);
|
||||
MemoryContext::get().remove_root(_target);
|
||||
}
|
||||
|
||||
Handle::Handle(Handle const &other) : _target(other._target) {
|
||||
if (_target != nullptr)
|
||||
CURRENT_MC.load()->add_root(_target);
|
||||
MemoryContext::get().add_root(_target);
|
||||
}
|
||||
|
||||
Handle &Handle::operator=(Handle other) {
|
||||
@@ -27,7 +27,7 @@ Handle &Handle::operator=(Handle other) {
|
||||
}
|
||||
|
||||
Handle Handle::cons(const Handle &car, const Handle &cdr) {
|
||||
auto ret = CURRENT_MC.load()->create_cell<ConsCell>(car.get(), cdr.get());
|
||||
auto ret = MemoryContext::get().create_cell<ConsCell>(car.get(), cdr.get());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -70,22 +70,22 @@ void Handle::splice(const Handle &what) {
|
||||
}
|
||||
|
||||
Handle Handle::makeNumCell(int64_t val) {
|
||||
return CURRENT_MC.load()->create_cell<NumAtomCell>(val);
|
||||
return MemoryContext::get().create_cell<NumAtomCell>(val);
|
||||
}
|
||||
|
||||
Handle Handle::makeStrCell(std::string val) {
|
||||
return CURRENT_MC.load()->create_cell<StrAtomCell>(std::move(val));
|
||||
return MemoryContext::get().create_cell<StrAtomCell>(std::move(val));
|
||||
}
|
||||
|
||||
void Handle::setcar(const Handle &car) {
|
||||
CURRENT_MC.load()->run_dirty<void>([&](std::function<void(Cell *)> dirty) -> void {
|
||||
MemoryContext::get().run_dirty<void>([&](std::function<void(Cell *)> dirty) -> void {
|
||||
dirty(dynamic_cast<ConsCell &>(*_target)._car);
|
||||
dynamic_cast<ConsCell &>(*_target)._car = car.get();
|
||||
});
|
||||
}
|
||||
|
||||
void Handle::setcdr(const Handle &cdr) {
|
||||
CURRENT_MC.load()->run_dirty<void>([&](std::function<void(Cell *)> dirty) -> void {
|
||||
MemoryContext::get().run_dirty<void>([&](std::function<void(Cell *)> dirty) -> void {
|
||||
dirty(dynamic_cast<ConsCell &>(*_target)._cdr);
|
||||
dynamic_cast<ConsCell &>(*_target)._cdr = cdr.get();
|
||||
});
|
||||
|
||||
@@ -10,12 +10,8 @@
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
std::atomic<MemoryContext *> CURRENT_MC = nullptr;
|
||||
|
||||
MemoryContext::MemoryContext() {
|
||||
MemoryContext *expected = nullptr;
|
||||
if (!CURRENT_MC.compare_exchange_strong(expected, this)) throw std::runtime_error("MC already exists!");
|
||||
|
||||
_gc_thread = std::thread(std::bind(&MemoryContext::gc_thread_entry, this));
|
||||
}
|
||||
|
||||
@@ -29,11 +25,6 @@ MemoryContext::~MemoryContext() {
|
||||
|
||||
assert(cell_count() == 0);
|
||||
|
||||
MemoryContext *expected = this;
|
||||
if (!CURRENT_MC.compare_exchange_strong(expected, nullptr)) {
|
||||
std::cerr << "Global MC pointer was overwritten!" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
_gc_thread_stop = true;
|
||||
_gc_request_cv.notify_all();
|
||||
_gc_thread.join();
|
||||
@@ -253,4 +244,8 @@ void MemoryContext::gc_thread_entry() {
|
||||
_gc_done_cv.notify_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MemoryContext &MemoryContext::get() {
|
||||
static MemoryContext mc;
|
||||
return mc;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ TEST(CompilerTest, BasicHello) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC 3 EVAL PRINT STOP)");
|
||||
@@ -26,7 +26,7 @@ TEST(CompilerTest, BasicLet) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC (let ((x 1)) x) EVAL PRINT STOP)");
|
||||
@@ -41,7 +41,7 @@ TEST(CompilerTest, BasicFn) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC (let ((plfn (lambda (a b) (+ a b)))) (plfn 2 3)) EVAL PRINT STOP)");
|
||||
@@ -56,7 +56,7 @@ TEST(CompilerTest, BasicFnIfT) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC (let ((plfn (lambda (a) (if a 1 2)))) (plfn 1)) EVAL PRINT STOP)");
|
||||
@@ -70,7 +70,7 @@ TEST(CompilerTest, BasicFnIfF) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC (let ((plfn (lambda (a) (if a 1 2)))) (plfn 0)) EVAL PRINT STOP)");
|
||||
@@ -84,7 +84,7 @@ TEST(CompilerTest, RecursiveFn) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC (letrec ((fib (lambda (n) (if n (if (+ n -1) (+ (fib (+ n -1)) (fib(+ n -2))) 1) 0) ))) (fib 10)) EVAL PRINT STOP)");
|
||||
|
||||
@@ -7,96 +7,96 @@
|
||||
#include "MemoryContext.h"
|
||||
|
||||
TEST(GCTest, GCTest) {
|
||||
MemoryContext mc;
|
||||
|
||||
{
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
c.append(Handle::makeNumCell(1));
|
||||
c.append(Handle::makeNumCell(2));
|
||||
mc.request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(c.car().val(), 1);
|
||||
EXPECT_EQ(c.cdr().car().val(), 2);
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
{
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
c.push(Handle::makeNumCell(1));
|
||||
c.push(Handle::makeNumCell(2));
|
||||
mc.request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(c.car().val(), 2);
|
||||
EXPECT_EQ(c.cdr().car().val(), 1);
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
}
|
||||
|
||||
TEST(GCTest, GCTestAppend) {
|
||||
MemoryContext mc;
|
||||
|
||||
for (int i = 0; i < 25000; i++) {
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
c.append(Handle::makeNumCell(1));
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
EXPECT_EQ(c.car().val(), 1);
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
}
|
||||
TEST(GCTest, GCTestPop) {
|
||||
MemoryContext mc;
|
||||
|
||||
{
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
static constexpr int test_size = 20000;
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
c.push(Handle::makeNumCell(i));
|
||||
}
|
||||
for (int i = test_size - 1; i >= 0; i--) {
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
EXPECT_EQ(i, c.pop().val());
|
||||
}
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
}
|
||||
|
||||
TEST(GCTest, GCTestAppend2) {
|
||||
MemoryContext mc;
|
||||
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
static constexpr int test_size = 2000;
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
c.append(Handle::makeNumCell(i));
|
||||
}
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
EXPECT_EQ(i, c.pop().val());
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
}
|
||||
|
||||
TEST(GCTest, GCTestAppend3) {
|
||||
MemoryContext mc;
|
||||
|
||||
for (int i = 0; i < 250000; i++) {
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
c.append(Handle::makeNumCell(1));
|
||||
c.append(Handle::makeNumCell(2));
|
||||
mc.request_gc();
|
||||
MemoryContext::get().request_gc();
|
||||
Handle n = c.cdr();
|
||||
c.setcdr(nullptr);
|
||||
EXPECT_EQ(n.car().val(), 2);
|
||||
EXPECT_EQ(c.car().val(), 1);
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ TEST(VMTest, BasicHello) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Handle newc(Handle::cons(nullptr, nullptr));
|
||||
newc.append(Handle::makeStrCell("NIL"));
|
||||
|
||||
@@ -7,7 +7,7 @@ TEST(VMWithParserTest, BasicHello) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(LDC 104 PUTCHAR STOP)");
|
||||
@@ -22,7 +22,7 @@ TEST(VMWithParserTest, BasicBranch) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr(
|
||||
@@ -38,7 +38,7 @@ TEST(VMWithParserTest, BasicFunction) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
{
|
||||
MemoryContext mc;
|
||||
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
parser.loadStr("(NIL LDC 1 CONS LDC 2 CONS LDF (LD (1 . 1) LD (1.2) ADD RET) AP PUTNUM STOP)");
|
||||
@@ -52,7 +52,7 @@ TEST(VMWithParserTest, BasicFunction) {
|
||||
TEST(VMWithParserTest, RecFunction) {
|
||||
std::stringstream ssin;
|
||||
std::stringstream ssout;
|
||||
MemoryContext mc;
|
||||
|
||||
{
|
||||
VM vm(ssin, ssout);
|
||||
Parser parser;
|
||||
@@ -61,9 +61,9 @@ TEST(VMWithParserTest, RecFunction) {
|
||||
vm.loadControl(parser.parseExpr());
|
||||
vm.run();
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(mc.cell_count(), 0);
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
MemoryContext::get().request_gc_and_wait();
|
||||
EXPECT_EQ(MemoryContext::get().cell_count(), 0);
|
||||
ssout.flush();
|
||||
EXPECT_EQ(ssout.str(), "6765");
|
||||
}
|
||||
Reference in New Issue
Block a user