From: Gabriel Corona Date: Thu, 17 Dec 2015 10:07:40 +0000 (+0100) Subject: [xbt] Type-safe Facetable levels X-Git-Tag: v3_13~1434^2~4 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/c93f053fe60b1880db916d2dc83ad03b0bb436a7 [xbt] Type-safe Facetable levels For compatibility with C, the type-safety is currently not strongly enforced. --- diff --git a/include/xbt/Facetable.hpp b/include/xbt/Facetable.hpp index 08be86eb45..84fe635033 100644 --- a/include/xbt/Facetable.hpp +++ b/include/xbt/Facetable.hpp @@ -8,12 +8,27 @@ #define SIMGRID_XBT_LIB_HPP #include - +#include #include namespace simgrid { namespace xbt { +template class FacetLevel; +template class Facetable; + +template +class FacetLevel { + static const std::size_t INVALID_ID = std::numeric_limits::max(); + std::size_t id_; + friend class Facetable; + constexpr FacetLevel(std::size_t id) : id_(id) {} +public: + constexpr FacetLevel() : id_(INVALID_ID) {} + std::size_t id() const { return id_; } + bool valid() { return id_ != INVALID_ID; } +}; + /** A Facetable is an object that you can extend with external facets. * * Facets are similar to the concept of mixins, that is, a set of behavior that is injected into a class without derivation. @@ -29,7 +44,6 @@ namespace xbt { * Instead, you should add a new facet to the Host class, that happens to be Facetable. * */ - template class Facetable { private: @@ -37,16 +51,21 @@ private: protected: std::vector facets_; public: - static std::size_t add_level(void (*deleter)(void*)) + static size_t add_level(void (*deleter)(void*)) { std::size_t res = deleters_.size(); deleters_.push_back(deleter); return res; } + template + static FacetLevel add_level(void (*deleter)(void*)) + { + return FacetLevel(add_level(deleter)); + } template static - std::size_t add_level() + FacetLevel add_level() { - return add_level([](void* p){ delete (U*)p; }); + return add_level([](void* p){ delete static_cast(p); }); } Facetable() : facets_(deleters_.size(), nullptr) {} ~Facetable() @@ -56,7 +75,7 @@ public: deleters_[i](facets_[i]); } - // TODO, make type-safe versions of this + // Type-unsafe versions of the facet access methods: void* facet(std::size_t level) { if (level >= facets_.size()) @@ -73,6 +92,22 @@ public: if (use_dtor && old_value != nullptr && deleters_[level]) deleters_[level](old_value); } + + // Type safe versions of the facet access methods: + template + U* facet(FacetLevel level) + { + return static_cast(facet(level.id())); + } + template + void set_facet(FacetLevel level, U* value, bool use_dtor = true) + { + set_facet(level.id(), value, use_dtor); + } + + // Convnience facet access when the type has a associated LEVEL: + template U* facet() { return facet(U::LEVEL); } + template void set_facet(U* p) { set_facet(U::LEVEL, p); } }; template diff --git a/src/simdag/sd_global.c b/src/simdag/sd_global.c index dad96a3992..b625857f8b 100644 --- a/src/simdag/sd_global.c +++ b/src/simdag/sd_global.c @@ -211,7 +211,7 @@ void SD_create_environment(const char *platform_file) xbt_dict_cursor_t cursor = NULL; simgrid_Host* host = NULL; xbt_dict_foreach(host_list, cursor, name, host){ - surf_Host* surf_host = (surf_Host*) sg_host_get_facet(host, SURF_HOST_LEVEL); + surf_Host* surf_host = (surf_Host*) surf_host_resource_priv(host); if (surf_host != NULL) __SD_workstation_create(surf_host, NULL); } diff --git a/src/simgrid/host.cpp b/src/simgrid/host.cpp index d7ec5f14fe..f2d53f3b65 100644 --- a/src/simgrid/host.cpp +++ b/src/simgrid/host.cpp @@ -58,7 +58,6 @@ int MSG_HOST_LEVEL; int SD_HOST_LEVEL; int SIMIX_HOST_LEVEL; int ROUTING_HOST_LEVEL; -int SURF_CPU_LEVEL; int USER_HOST_LEVEL; #include "src/msg/msg_private.h" // MSG_host_priv_free. FIXME: killme @@ -81,7 +80,7 @@ void sg_host_init() }); SD_HOST_LEVEL = simgrid::Host::add_level(__SD_workstation_destroy); SIMIX_HOST_LEVEL = simgrid::Host::add_level(SIMIX_host_destroy); - SURF_CPU_LEVEL = simgrid::Host::add_level(surf_cpu_free); + simgrid::surf::Cpu::init(); ROUTING_HOST_LEVEL = simgrid::Host::add_level(routing_asr_host_free); USER_HOST_LEVEL = simgrid::Host::add_level(NULL); } @@ -131,10 +130,10 @@ void sg_host_simix_destroy(sg_host_t host) { // ========== SURF CPU ============ surf_cpu_t sg_host_surfcpu(sg_host_t host) { - return (surf_cpu_t) host->facet(SURF_CPU_LEVEL); + return host->facet(); } void sg_host_surfcpu_set(sg_host_t host, surf_cpu_t cpu) { - host->set_facet(SURF_CPU_LEVEL, cpu); + host->set_facet(simgrid::surf::Cpu::LEVEL, cpu); } void sg_host_surfcpu_register(sg_host_t host, surf_cpu_t cpu) { @@ -143,7 +142,7 @@ void sg_host_surfcpu_register(sg_host_t host, surf_cpu_t cpu) sg_host_surfcpu_set(host, cpu); } void sg_host_surfcpu_destroy(sg_host_t host) { - host->set_facet(SURF_CPU_LEVEL, nullptr); + host->set_facet(nullptr); } // ========== RoutingEdge ============ surf_RoutingEdge *sg_host_edge(sg_host_t host) { diff --git a/src/surf/cpu_interface.cpp b/src/surf/cpu_interface.cpp index a8d80c7106..17029dbf13 100644 --- a/src/surf/cpu_interface.cpp +++ b/src/surf/cpu_interface.cpp @@ -20,6 +20,14 @@ simgrid::surf::CpuModel *surf_cpu_model_vm; namespace simgrid { namespace surf { +simgrid::xbt::FacetLevel Cpu::LEVEL; + +void Cpu::init() +{ + if (!LEVEL.valid()) + LEVEL = simgrid::Host::add_level(); +} + /************* * Callbacks * *************/ diff --git a/src/surf/cpu_interface.hpp b/src/surf/cpu_interface.hpp index c74e737bbc..79bc81dc71 100644 --- a/src/surf/cpu_interface.hpp +++ b/src/surf/cpu_interface.hpp @@ -100,6 +100,8 @@ public: */ XBT_PUBLIC_CLASS Cpu : public simgrid::surf::Resource { public: + static simgrid::xbt::FacetLevel LEVEL; + static void init(); Cpu(); /** diff --git a/src/surf/host_clm03.cpp b/src/surf/host_clm03.cpp index a54d7337c9..fd7e4458e1 100644 --- a/src/surf/host_clm03.cpp +++ b/src/surf/host_clm03.cpp @@ -53,7 +53,7 @@ Host *HostCLM03Model::createHost(const char *name,RoutingEdge *netElm, Cpu *cpu) netElm, cpu); surf_callback_emit(hostCreatedCallbacks, host); XBT_DEBUG("Create host %s with %ld mounted disks", name, xbt_dynar_length(host->p_storage)); - simgrid::Host::by_name_or_null(name)->set_facet(SURF_HOST_LEVEL, host); + simgrid::Host::by_name_or_null(name)->set_facet(host); return host; } diff --git a/src/surf/host_interface.cpp b/src/surf/host_interface.cpp index 737583bcee..81037bc3b1 100644 --- a/src/surf/host_interface.cpp +++ b/src/surf/host_interface.cpp @@ -6,6 +6,8 @@ #include "host_interface.hpp" +#include + #include "src/simix/smx_private.h" #include "cpu_cas01.hpp" #include "simgrid/sg_config.h" @@ -28,7 +30,9 @@ void host_add_traces(){ namespace simgrid { namespace surf { - + +simgrid::xbt::FacetLevel Host::LEVEL; + surf_callback(void, simgrid::surf::Host*) hostCreatedCallbacks; surf_callback(void, simgrid::surf::Host*) hostDestructedCallbacks; surf_callback(void, simgrid::surf::Host*, e_surf_resource_state_t, e_surf_resource_state_t) hostStateChangedCallbacks; @@ -76,6 +80,15 @@ void HostModel::adjustWeightOfDummyCpuActions() /************ * Resource * ************/ + +void Host::init() +{ + if (!LEVEL.valid()) { + LEVEL = simgrid::Host::add_level(); + SURF_HOST_LEVEL = LEVEL.id(); + } +} + Host::Host(simgrid::surf::Model *model, const char *name, xbt_dict_t props, xbt_dynar_t storage, RoutingEdge *netElm, Cpu *cpu) : Resource(model, name, props) diff --git a/src/surf/host_interface.hpp b/src/surf/host_interface.hpp index 70b7c1ca84..915c14ade6 100644 --- a/src/surf/host_interface.hpp +++ b/src/surf/host_interface.hpp @@ -96,6 +96,8 @@ public: */ class Host : public simgrid::surf::Resource { public: + static simgrid::xbt::FacetLevel LEVEL; + static void init(); /** * @brief Host constructor * diff --git a/src/surf/host_ptask_L07.cpp b/src/surf/host_ptask_L07.cpp index 82a0951719..6d92e97c61 100644 --- a/src/surf/host_ptask_L07.cpp +++ b/src/surf/host_ptask_L07.cpp @@ -275,7 +275,7 @@ Host *HostL07Model::createHost(const char *name,RoutingEdge *netElm, Cpu *cpu) HostL07 *host = new HostL07(this, name, NULL, netElm, cpu); surf_callback_emit(hostCreatedCallbacks, host); - simgrid::Host::by_name_or_create(name)->set_facet(SURF_HOST_LEVEL, host); + simgrid::Host::by_name_or_create(name)->set_facet(host); return host; } diff --git a/src/surf/surf_c_bindings.cpp b/src/surf/surf_c_bindings.cpp index fb4004a49c..740ed9d6f2 100644 --- a/src/surf/surf_c_bindings.cpp +++ b/src/surf/surf_c_bindings.cpp @@ -171,7 +171,7 @@ void routing_get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst, surf_host_model_t surf_host_get_model(sg_host_t host) { simgrid::surf::Host* surf_host = - (simgrid::surf::Host*) host->facet(SURF_HOST_LEVEL); + (simgrid::surf::Host*) host->facet(); return (surf_host_model_t) surf_host->getModel(); } @@ -396,7 +396,7 @@ void surf_vm_destroy(sg_host_t resource){ sg_host_surfcpu_destroy(resource); sg_host_edge_destroy(resource,1); // TODO, use backlink from simgrid::surf::Host to simgrid::Host - simgrid::Host::by_name_or_null(name)->set_facet(SURF_HOST_LEVEL, nullptr); + simgrid::Host::by_name_or_null(name)->set_facet((simgrid::surf::Host*)nullptr); /* TODO: comment out when VM storage is implemented. */ // host->set_facet(SURF_STORAGE_LEVEL, nullptr); diff --git a/src/surf/surf_interface.cpp b/src/surf/surf_interface.cpp index e5cee4109a..0f43bcf638 100644 --- a/src/surf/surf_interface.cpp +++ b/src/surf/surf_interface.cpp @@ -269,11 +269,6 @@ static XBT_INLINE void routing_asr_prop_free(void *p) //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster } -static XBT_INLINE void surf_host_free(void *r) -{ - delete static_cast(r); -} - static XBT_INLINE void surf_storage_free(void *r) { delete static_cast(r); @@ -321,7 +316,7 @@ void surf_init(int *argc, char **argv) ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free); XBT_DEBUG("Add SURF levels"); - SURF_HOST_LEVEL = simgrid::Host::add_level(surf_host_free); + simgrid::surf::Host::init(); SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free); xbt_init(argc, argv); diff --git a/src/surf/virtual_machine.cpp b/src/surf/virtual_machine.cpp index 9be8a78fa9..9fc07fc868 100644 --- a/src/surf/virtual_machine.cpp +++ b/src/surf/virtual_machine.cpp @@ -38,7 +38,7 @@ VirtualMachine::VirtualMachine(Model *model, const char *name, xbt_dict_t props, : Host(model, name, props, NULL, netElm, cpu) { VMModel::ws_vms.push_back(*this); - simgrid::Host::by_name_or_create(name)->set_facet(SURF_HOST_LEVEL, this); + simgrid::Host::by_name_or_create(name)->set_facet(this); } /*