#pragma once #include #include #include #include #include #include #include namespace wfr { // Forward declarations namespace wfs { class AtomicActivityImplementation; } namespace resource { class AbstractResource { // Invariant properties that can be accessed directly. public: const ResourceClass resourceClass; const std::string resourceIdentifier; const wfr_id_t resourceId; // Public Functions public: AbstractResource( ResourceClass resourceClass, const std::string& resourceIdentifier, const wfr_id_t resourceId ) noexcept : resourceClass(resourceClass), resourceIdentifier(resourceIdentifier), resourceId(resourceId) {} virtual ~AbstractResource() {} virtual bool hasCapability(const RequiredResourceCapability& type) const noexcept = 0; }; class AbstractResourceType { // Invariant properties that can be accessed directly. public: const ResourceClass resourceClass; const std::string resourceTypeName; // Mutable properties that need to be accessed via getter-/setter-functions. protected: std::set capabilities; std::map properties; // Public Functions public: AbstractResourceType( ResourceClass resourceClass, const std::string& resourceName, const std::set& capabilities = std::set(), const std::map& properties = std::map() ) noexcept : resourceClass(resourceClass), resourceTypeName(resourceName), capabilities(capabilities), properties(properties) {} virtual ~AbstractResourceType() {} wfr_size_t getCapabilityCount() const noexcept { return capabilities.size(); } const std::set& getCapabilities() const noexcept { return capabilities; } bool hasCapability(const RequiredResourceCapability& type) const noexcept; bool hasCapability(wfr::resource::ResourceCapabilityType type) const noexcept; wfr_size_t getPropertyCount() const noexcept { return properties.size(); } const std::map& getProperties() const noexcept { return properties; } std::vector getPropertyKeys() const noexcept; std::string getProperty(const std::string& key) const noexcept; }; template class ResourceTypeBase : public AbstractResourceType { // Mutable properties that need to be accessed via getter-/setter-functions. private: std::vector resources; // Public Functions public: ResourceTypeBase( ResourceClass resourceClass, const std::string& resourceName, const std::set& capabilities = std::set(), const std::map& properties = std::map() ) noexcept : AbstractResourceType(resourceClass, resourceName, capabilities, properties) {} wfr_size_t getResourceCount() const noexcept { return resources.size(); } const std::vector getResources() const noexcept { return resources; } void addResource(Resource* resource) noexcept { resources.push_back(resource); } }; template class ResourceBase : public AbstractResource { // Invariant properties that can be accessed directly. public: RType& resourceType; // Public Functions public: ResourceBase(ResourceClass resourceClass, const std::string& resourceIdentifier, const wfr_id_t resourceId, RType& resourceType ) noexcept : AbstractResource(resourceClass, resourceIdentifier, resourceId), resourceType(resourceType) {} virtual bool hasCapability(const RequiredResourceCapability& type) const noexcept { return resourceType.hasCapability(type); } virtual bool hasCapability(wfr::resource::ResourceCapabilityType type) const noexcept { return resourceType.hasCapability(type); } }; class ComputingResource; class ComputingResourceType : public ResourceTypeBase { // Invariant properties that can be accessed directly. public: const ComputingDeviceClass computingDeviceClass; const wfr_size_t maxSlots; // Public Functions public: ComputingResourceType( const std::string& resourceName, ComputingDeviceClass computingDeviceClass, wfr_size_t maxSlots, const std::set& capabilities = std::set(), const std::map& properties = std::map() ) noexcept : ResourceTypeBase(ResourceClass::ComputingResource, resourceName, capabilities, properties), computingDeviceClass(computingDeviceClass), maxSlots(maxSlots) {} }; class ComputingResource : public ResourceBase { // Mutable properties that need to be accessed via getter-/setter-functions. protected: wfr_size_t reservedSlots =0; wfr_size_t busySlots = 0; // Public Functions public: ComputingResource( const std::string& resourceIdentifier, const wfr_id_t resourceId, ComputingResourceType& resourceType ) noexcept : ResourceBase(ResourceClass::ComputingResource, resourceIdentifier, resourceId, resourceType) { resourceType.addResource(this); } wfr_size_t getMaxSlotCount() const noexcept { return resourceType.maxSlots; } wfr_size_t getReservedSlotCount() const noexcept { return reservedSlots; } wfr_size_t getBusySlotCount() const noexcept { return busySlots; } wfr_size_t getFreeSlotCount() const noexcept { auto nonFreeSlots = busySlots + reservedSlots; return nonFreeSlots >= resourceType.maxSlots ? 0 : resourceType.maxSlots - nonFreeSlots; } bool reserveSlots(const wfr_size_t& slots, bool requireFreeSlots = false) noexcept; bool markReservedSlotsBusy(const wfr_size_t& slots) noexcept; bool markFreeSlotsBusy(const wfr_size_t& slots) noexcept; bool releaseBusySlots(const wfr_size_t& slots) noexcept; }; ComputingDeviceClass parseComputingDeviceType(const std::string& type); std::string getComputingDeviceTypeString(const ComputingDeviceClass& type); ResourceCapabilityType parseResourceCapabilityType(const std::string& type); std::string getResourceCapabilityTypeString(const ResourceCapabilityType& type); } /* namespace resource */ } /* namespace wfr */