/*========================== begin_copyright_notice ============================
Copyright (C) 2021-2024 Intel Corporation

SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/

/*!
 * @file Interface of the memory buffer intended to store profile data
 */

#ifndef IGT_PROFILE_BUFFER_H_
#define IGT_PROFILE_BUFFER_H_

#include "gt_basic_defs.h"
#include "gt_gpu_defs.h"

namespace gtpin
{
#pragma pack(push, 8)

/*! @addtogroup GTPIN_PROFILE_BUFFER 
@{
*/

/// Offset in the profilile buffer; -1 denotes invalid offset
using GtProfileBufferOffset = Uint32Validatable<>;

/* ===================================================================================================== */
// Class IGtProfileBuffer
/* ===================================================================================================== */
/*!
 * @brief Abstract representation of the profile data storage
 * 
 * @par Availability:
 * - IGtTool::OnKernelRun
 * - IGtTool::OnKernelComplete
 */
class IGtProfileBuffer
{
public:
    /// Return size of the profile buffer, in bytes
    virtual uint32_t Size() const = 0;

    /*!
     * @brief Copy memory block from the profile buffer into specified host memory location
     * @param[in]      offset   Offset of the memory block within profile buffer
     * @param[in, out] dst      Destination address in the host memory
     * @param[in]      size     Number of bytes to copy
     * @return true - success, false - failure
     *         In case of error, the IGtCore::LastError() function provides the specific failure reason
     */
    virtual bool Read(uint32_t offset, void* dst, uint32_t size) const = 0;

    /*!
     * @brief Copy memory block from the specified host memory location into profile buffer
     * @param[in]      offset   Offset of the memory block within profile buffer
     * @param[in]      src      Source address in the host memory
     * @param[in]      size     Number of bytes to copy
     * @return true - success, false - failure
     *         In case of error, the IGtCore::LastError() function provides the specific failure reason
     */
    virtual bool Write(uint32_t offset, const void* src, uint32_t size) = 0;

    /*!
     * @brief Assign the given value to all bytes of the specified memory block within profile buffer
     * @param[in]      offset   Offset of the memory block within profile buffer
     * @param[in]      size     Number of bytes to fill in
     * @param[in]      val      The value to be assigned
     * @return true - success, false - failure
     *         In case of error, the IGtCore::LastError() function provides the specific failure reason
     */
    virtual bool Fill(uint32_t offset, uint32_t size, uint8_t val) = 0;

    /*!
     * @brief Assign the given value to all bytes of this profile buffer
     * @param[in]      val      The value to be assigned
     * @return true - success, false - failure
     *         In case of error, the IGtCore::LastError() function provides the specific failure reason
     */
    virtual bool Fill(uint8_t val = 0) = 0;

    /*!
     * @brief Given offset within profile buffer, get virtual address of the corresponding device memory location
     * @param[in]      offset   Offset of the location within profile buffer
     * @return Address in the virtual address space of the device, or invalid address if offset > Size()
     */
    virtual GtDeviceAddr DeviceAddr(uint32_t offset = 0) const = 0;

protected:
    /// @internal Protected destructor
    virtual ~IGtProfileBuffer() = default;
};
GTPIN_ASSERT_PURE_ABSTRACT(IGtProfileBuffer);

/* ===================================================================================================== */
// Class IGtProfileBufferAllocator
/* ===================================================================================================== */
/*!
 * @brief Abstract class that provides interface for allocation (reservation) memory blocks in the profile buffer
 * 
 * @par Availability:
 * - IGtTool::OnKernelBuild
 */
class IGtProfileBufferAllocator
{
public:
    /*!
     * @brief Reserve space for a memory block of the specified size in the profile buffer
     * @param[in]   size        Size of the memory block in bytes
     * @param[in]   alignment   Minimal alignment of the memory block.
     *                          Must be power of two, not exceeding page size
     * @return Offset of the block allocated in the profile buffer, or -1 if allocation failed
     */
    virtual GtProfileBufferOffset Allocate(uint32_t size, uint32_t alignment = 64) = 0;

    /// Return total number of bytes, allocated (reserved) in the profile buffer so far
    virtual uint32_t TotalSize() const = 0;

protected:
    /// @internal Protected destructor
    virtual ~IGtProfileBufferAllocator() = default;
};
GTPIN_ASSERT_PURE_ABSTRACT(IGtProfileBufferAllocator);
/*! @} */

#pragma pack(pop)
}
#endif
