From 9469d09c57345ed4872725a2b519511f2f0cace7 Mon Sep 17 00:00:00 2001 From: Kruno Tomola Fabro <krunotf@memgraph.io> Date: Fri, 26 Aug 2016 12:21:42 +0100 Subject: [PATCH] Poc example works. --- include/barrier/barrier.hpp | 0 include/barrier/common.hpp | 0 poc/CMakeLists.txt | 5 ++ poc/isolation.cpp | 24 +++++++ poc/isolation/db.hpp | 28 ++++++++ poc/isolation/header.cpp | 59 +++++++++++++++++ poc/isolation/header.hpp | 123 ++++++++++++++++++++++++++++++++++++ poc/isolation/isolated.hpp | 17 +++++ src/barrier/barrier.cpp | 0 9 files changed, 256 insertions(+) create mode 100644 include/barrier/barrier.hpp create mode 100644 include/barrier/common.hpp create mode 100644 poc/isolation.cpp create mode 100644 poc/isolation/db.hpp create mode 100644 poc/isolation/header.cpp create mode 100644 poc/isolation/header.hpp create mode 100644 poc/isolation/isolated.hpp create mode 100644 src/barrier/barrier.cpp diff --git a/include/barrier/barrier.hpp b/include/barrier/barrier.hpp new file mode 100644 index 000000000..e69de29bb diff --git a/include/barrier/common.hpp b/include/barrier/common.hpp new file mode 100644 index 000000000..e69de29bb diff --git a/poc/CMakeLists.txt b/poc/CMakeLists.txt index 89856093b..cb6a5cd8b 100644 --- a/poc/CMakeLists.txt +++ b/poc/CMakeLists.txt @@ -11,3 +11,8 @@ add_executable(profile profile.cpp) target_link_libraries(profile memgraph) target_link_libraries(profile Threads::Threads) target_link_libraries(profile ${fmt_static_lib}) + +include_directories(${CMAKE_SOURCE_DIR}/poc) + +add_executable(isolation isolation.cpp isolation/header.cpp) +target_link_libraries(isolation ${fmt_static_lib}) diff --git a/poc/isolation.cpp b/poc/isolation.cpp new file mode 100644 index 000000000..493b83949 --- /dev/null +++ b/poc/isolation.cpp @@ -0,0 +1,24 @@ +// Making it as first import will prevent accidentaly importing to isolated +// other code. +#include "isolation/isolated.hpp" + +#include <iostream> + +#include "isolation/db.hpp" +#include "isolation/header.hpp" + +using namespace base; + +int main() +{ + std::cout << sizeof(Accessor) << " : " << alignof(Accessor) << "\n"; + + Db db; + db.data = 207; + + auto ret = sha::do_something(reinterpret_cast<sha::Db &>(db)); + + std::cout << ret << std::endl; + + return 0; +} diff --git a/poc/isolation/db.hpp b/poc/isolation/db.hpp new file mode 100644 index 000000000..87e8eb3ff --- /dev/null +++ b/poc/isolation/db.hpp @@ -0,0 +1,28 @@ +#include <string> + +namespace base +{ +class Accessor +{ +public: + char before = ~((char)-1); + int data = 0; + size_t after = ~((size_t)-1); +}; + +class Name +{ +public: + Name(const char *str) : name(std::string(str)) {} + + std::string name; +}; + +class Db +{ +public: + int accessed = 0; + int data = 0; + Name name = {"name"}; +}; +} diff --git a/poc/isolation/header.cpp b/poc/isolation/header.cpp new file mode 100644 index 000000000..fffc646fa --- /dev/null +++ b/poc/isolation/header.cpp @@ -0,0 +1,59 @@ +#include "isolation/header.hpp" + +#include "isolation/db.hpp" + +template <class TO, class FROM> +TO &ref_as(FROM &ref) +{ + return (*reinterpret_cast<TO *>(&ref)); +} + +template <class TO, class FROM> +TO value_as(FROM &&ref) +{ + return std::move((*reinterpret_cast<TO *>(&ref))); +} + +sha::Accessor::Accessor(const sha::Accessor::Accessor &other) + : Sized(sizeof(base::Accessor), alignof(base::Accessor)) +{ + as<base::Accessor>() = other.as<base::Accessor>(); +} + +sha::Accessor::Accessor(sha::Accessor::Accessor &&other) + : Sized(sizeof(base::Accessor), alignof(base::Accessor)) +{ + as<base::Accessor>() = value_as<base::Accessor>(other); +} + +sha::Accessor &sha::Accessor::operator=(const sha::Accessor::Accessor &other) +{ + // TODO + return *this; +} +sha::Accessor &sha::Accessor::operator=(sha::Accessor::Accessor &&other) +{ + // TODO + return *this; +} + +int sha::Accessor::get_prop(sha::Name &name) +{ + return as<base::Accessor>().data; +} + +sha::Accessor sha::Db::access() +{ + auto &db = as<base::Db>(); + db.accessed++; + base::Accessor acc; + acc.data = db.data; + return sha::Accessor(value_as<sha::Accessor>(acc)); +} + +sha::Name &sha::Db::get_name(const char *str) +{ + auto &db = as<base::Db>(); + db.accessed++; + return ref_as<sha::Name>(db.name); +} diff --git a/poc/isolation/header.hpp b/poc/isolation/header.hpp new file mode 100644 index 000000000..56e8319dd --- /dev/null +++ b/poc/isolation/header.hpp @@ -0,0 +1,123 @@ +#pragma once + +// All fake types should be defined here as a interface. + +#include <cassert> +#include <type_traits> + +namespace sha +{ + +// Sized +class Name; +class Db; + +// Unsized +class Accessor; + +// Marks types which will be passed only be ref/pointer. +class Unsized +{ +public: + // This will assure that this class/derived classes can't be instantiated, + // copyed or moved. + // This way the other side can't "accidentaly" create/copy/move or destroy + // this type because that would be errornus. + Unsized() = delete; + Unsized(const Unsized &other) = delete; + Unsized(Unsized &&other) = delete; + ~Unsized() = delete; + Unsized &operator=(const Unsized &other) = delete; + Unsized &operator=(Unsized &&other) = delete; + +protected: + template <class T> + T &as() + { + return (*reinterpret_cast<T *>(this)); + } + + template <class T> + const T &as() const + { + return (*reinterpret_cast<const T *>(this)); + } +}; + +// Every type which will be passed by value must extends this class. +template <std::size_t size_B, std::size_t alignment_B> +class Sized +{ +public: + // This will assure that this/derived class can't be instantiated. + // This way if other side can't "accidentaly" create this/derived type + // because that would be errornus. + Sized() = delete; + + // This constructr also serves as a check for correctness of size and + // aligment. + Sized(std::size_t _size_B, std::size_t _alignment_B) + { + assert(size_B == _size_B); + assert(alignment_B == _alignment_B); + } + +protected: + template <class T> + T &as() + { + return (*reinterpret_cast<T *>(&data)); + } + + template <class T> + const T &as() const + { + return (*reinterpret_cast<const T *>(&data)); + } + +private: + // Here the first argument for template is size of struct in bytes. While + // the second one is aligment of struct in bytes. Every class which will be + // passed by value must have this kind of aligned storage with correct size + // and aligment for that type. Unit tests to check this must be present. + // Example would be: + // std::aligned_storage<sizeof(std::set<int>), alignof(std::set<int>)> + // While the resoults of sizeof and alignof would be passed as template + // argumetns. + // This values would be checked in tests like the following for example + // above: + // assert(sizeof(Accessor)==sizeof(std::set<int>)); + // assert(alignof(Accessor)==alignof(std::set<int>)); + std::aligned_storage<size_B, alignment_B> data; +}; + +// Type which will be passed by value so it's real size matters. +class Accessor : private Sized<16, 8> +{ +public: + // If the underlying type can't be copyed or moved this two constructors + // would be deleted. + Accessor(const Accessor &other); + Accessor(Accessor &&other); + + // If the underlying type can't be copyed or moved this two operators + // would be deleted. + Accessor &operator=(const Accessor &other); + Accessor &operator=(Accessor &&other); + + int get_prop(Name &name); +}; + +// Type which will be passed by ref/pointer only so it's size doesnt matter. +class Name : private Unsized +{ +}; + +// Type which will be passed by ref/pointer only so it's size doesnt matter. +class Db : public Unsized +{ +public: + Accessor access(); + Name &get_name(const char *str); +}; +} diff --git a/poc/isolation/isolated.hpp b/poc/isolation/isolated.hpp new file mode 100644 index 000000000..e11ccb17a --- /dev/null +++ b/poc/isolation/isolated.hpp @@ -0,0 +1,17 @@ +// This is the file of isolated code. It has access only to header.hpp + +#include "isolation/header.hpp" + +namespace sha +{ +int do_something(Db &db) +{ + auto &name = db.get_name("name"); + + auto acc = db.access(); + + auto ret = acc.get_prop(name); + + return ret; +} +} diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp new file mode 100644 index 000000000..e69de29bb