#ifndef HALIDE_OBJECT_INSTANCE_REGISTRY_H #define HALIDE_OBJECT_INSTANCE_REGISTRY_H /** \file * * Provides a single global registry of Generators, GeneratorParams, * and Params indexed by this pointer. This is used for finding the * parameters inside of a Generator. NOTE: this is threadsafe only * if you are compiling with C++11 enabled. */ #include <stddef.h> #include <stdint.h> #include <map> #include <mutex> #include <vector> namespace Halide { namespace Internal { class ObjectInstanceRegistry { public: enum Kind { Invalid, Generator, GeneratorParam, GeneratorInput, GeneratorOutput, FilterParam, ScheduleParam }; /** Add an instance to the registry. The size may be 0 for Param Kinds, * but not for Generator. subject_ptr is the value actually associated * with this instance; it is usually (but not necessarily) the same * as this_ptr. Assert if this_ptr is already registered. * * If 'this' is directly heap allocated (not a member of a * heap-allocated object) and you want the introspection subsystem * to know about it and its members, set the introspection_helper * argument to a pointer to a global variable with the same true * type as 'this'. For example: * * MyObject *obj = new MyObject; * static MyObject *introspection_helper = nullptr; * register_instance(obj, sizeof(MyObject), kind, obj, &introspection_helper); * * I.e. introspection_helper should be a pointer to a pointer to * an object instance. The inner pointer can be null. The * introspection subsystem will then assume this new object is of * the matching type, which will help its members deduce their * names on construction. */ static void register_instance(void *this_ptr, size_t size, Kind kind, void *subject_ptr, const void *introspection_helper); /** Remove an instance from the registry. Assert if not found. */ static void unregister_instance(void *this_ptr); /** Returns the list of subject pointers for objects that have * been directly registered within the given range. If there is * another containing object inside the range, instances within * that object are skipped. */ static std::vector<void *> instances_in_range(void *start, size_t size, Kind kind); private: static ObjectInstanceRegistry &get_registry(); struct InstanceInfo { void *subject_ptr; // May be different from the this_ptr in the key size_t size; // May be 0 for params Kind kind; bool registered_for_introspection; InstanceInfo() : subject_ptr(nullptr), size(0), kind(Invalid), registered_for_introspection(false) {} InstanceInfo(size_t size, Kind kind, void *subject_ptr, bool registered_for_introspection) : subject_ptr(subject_ptr), size(size), kind(kind), registered_for_introspection(registered_for_introspection) {} }; std::mutex mutex; std::map<uintptr_t, InstanceInfo> instances; ObjectInstanceRegistry() {} ObjectInstanceRegistry(ObjectInstanceRegistry &rhs); // unimplemented }; } // namespace Internal } // namespace Halide #endif // HALIDE_OBJECT_INSTANCE_REGISTRY_H