1 #ifndef HALIDE_OBJECT_INSTANCE_REGISTRY_H 2 #define HALIDE_OBJECT_INSTANCE_REGISTRY_H 3 4 /** \file 5 * 6 * Provides a single global registry of Generators, GeneratorParams, 7 * and Params indexed by this pointer. This is used for finding the 8 * parameters inside of a Generator. NOTE: this is threadsafe only 9 * if you are compiling with C++11 enabled. 10 */ 11 12 #include <stddef.h> 13 #include <stdint.h> 14 15 #include <map> 16 #include <mutex> 17 #include <vector> 18 19 namespace Halide { 20 namespace Internal { 21 22 class ObjectInstanceRegistry { 23 public: 24 enum Kind { 25 Invalid, 26 Generator, 27 GeneratorParam, 28 GeneratorInput, 29 GeneratorOutput, 30 FilterParam 31 }; 32 33 /** Add an instance to the registry. The size may be 0 for Param Kinds, 34 * but not for Generator. subject_ptr is the value actually associated 35 * with this instance; it is usually (but not necessarily) the same 36 * as this_ptr. Assert if this_ptr is already registered. 37 * 38 * If 'this' is directly heap allocated (not a member of a 39 * heap-allocated object) and you want the introspection subsystem 40 * to know about it and its members, set the introspection_helper 41 * argument to a pointer to a global variable with the same true 42 * type as 'this'. For example: 43 * 44 * MyObject *obj = new MyObject; 45 * static MyObject *introspection_helper = nullptr; 46 * register_instance(obj, sizeof(MyObject), kind, obj, &introspection_helper); 47 * 48 * I.e. introspection_helper should be a pointer to a pointer to 49 * an object instance. The inner pointer can be null. The 50 * introspection subsystem will then assume this new object is of 51 * the matching type, which will help its members deduce their 52 * names on construction. 53 */ 54 static void register_instance(void *this_ptr, size_t size, Kind kind, void *subject_ptr, 55 const void *introspection_helper); 56 57 /** Remove an instance from the registry. Assert if not found. 58 */ 59 static void unregister_instance(void *this_ptr); 60 61 /** Returns the list of subject pointers for objects that have 62 * been directly registered within the given range. If there is 63 * another containing object inside the range, instances within 64 * that object are skipped. 65 */ 66 static std::vector<void *> instances_in_range(void *start, size_t size, Kind kind); 67 68 private: 69 static ObjectInstanceRegistry &get_registry(); 70 71 struct InstanceInfo { 72 void *subject_ptr; // May be different from the this_ptr in the key 73 size_t size; // May be 0 for params 74 Kind kind; 75 bool registered_for_introspection; 76 InstanceInfoInstanceInfo77 InstanceInfo() 78 : subject_ptr(nullptr), size(0), kind(Invalid), registered_for_introspection(false) { 79 } InstanceInfoInstanceInfo80 InstanceInfo(size_t size, Kind kind, void *subject_ptr, bool registered_for_introspection) 81 : subject_ptr(subject_ptr), size(size), kind(kind), registered_for_introspection(registered_for_introspection) { 82 } 83 }; 84 85 std::mutex mutex; 86 std::map<uintptr_t, InstanceInfo> instances; 87 88 ObjectInstanceRegistry() = default; 89 ObjectInstanceRegistry(ObjectInstanceRegistry &rhs) = delete; 90 }; 91 92 } // namespace Internal 93 } // namespace Halide 94 95 #endif // HALIDE_OBJECT_INSTANCE_REGISTRY_H 96