/**

 * Copyright (c) 2026 Huawei Technologies Co., Ltd.

 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of

 * CANN Open Software License Agreement Version 2.0 (the "License").

 * Please refer to the License for details. You may not use this file except in compliance with the License.

 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,

 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.

 * See LICENSE in the root of the software repository for the full text of the License.

 */

#include "api_c.h"

#include "api.hpp"

#include "api_handle_guard.h"

#include "base.hpp"

#include "osal.hpp"

#include "global_state_manager.hpp"



using namespace cce::runtime;

namespace cce {

namespace runtime {

TIMESTAMP_EXTERN(rtMemAllocManaged);

TIMESTAMP_EXTERN(rtMemFreeManaged);

TIMESTAMP_EXTERN(rtMemManagedGetAttr);

TIMESTAMP_EXTERN(rtMemManagedGetAttrs);

} // namespace runtime

} // namespace cce



#ifdef __cplusplus

extern "C" {

#endif // __cplusplus



VISIBILITY_DEFAULT

rtError_t rtMemAllocManaged(void** ptr, uint64_t size, uint32_t flag, const uint16_t moduleId)

{

    GLOBAL_STATE_WAIT_IF_LOCKED();

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    TIMESTAMP_BEGIN(rtMemAllocManaged);

    const rtError_t error = apiInstance->ManagedMemAlloc(ptr, size, flag, moduleId);

    TIMESTAMP_END(rtMemAllocManaged);

    if (unlikely(error != RT_ERROR_NONE)) {

        return GetRtExtErrCodeAndSetGlobalErr(error);

    }

    return ACL_RT_SUCCESS;

}



VISIBILITY_DEFAULT

rtError_t rtMemFreeManaged(void* ptr)

{

    GLOBAL_STATE_WAIT_IF_LOCKED();

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    TIMESTAMP_BEGIN(rtMemFreeManaged);

    const rtError_t error = apiInstance->ManagedMemFree(ptr);

    TIMESTAMP_END(rtMemFreeManaged);

    ERROR_RETURN_WITH_EXT_ERRCODE(error);

    return ACL_RT_SUCCESS;

}



VISIBILITY_DEFAULT

rtError_t rtMemManagedAdvise(const void* const ptr, uint64_t size, uint16_t advise, rtMemManagedLocation location)

{

    GLOBAL_STATE_WAIT_IF_LOCKED();

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    const rtError_t error = apiInstance->MemManagedAdvise(ptr, size, advise, location);

    COND_RETURN_WITH_NOLOG(error == RT_ERROR_DRV_NOT_SUPPORT, ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    ERROR_RETURN_WITH_EXT_ERRCODE(error);

    return ACL_RT_SUCCESS;

}



VISIBILITY_DEFAULT

rtError_t rtMemManagedGetAttr(

    rtMemManagedRangeAttribute attribute, const void* ptr, size_t size, void* data, size_t dataSize)

{

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    TIMESTAMP_BEGIN(rtMemManagedGetAttr);

    const rtError_t error = apiInstance->MemManagedGetAttr(attribute, ptr, size, data, dataSize);

    TIMESTAMP_END(rtMemManagedGetAttr);

    COND_RETURN_WITH_NOLOG(error == RT_ERROR_DRV_NOT_SUPPORT, ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    COND_RETURN_WITH_NOLOG(error == RT_ERROR_FEATURE_NOT_SUPPORT, ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    ERROR_RETURN_WITH_EXT_ERRCODE(error);

    return ACL_RT_SUCCESS;

}



VISIBILITY_DEFAULT

rtError_t rtMemManagedGetAttrs(

    rtMemManagedRangeAttribute* attributes, size_t numAttributes, const void* ptr, size_t size, void** data,

    size_t* dataSizes)

{

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    TIMESTAMP_BEGIN(rtMemManagedGetAttrs);

    const rtError_t error = apiInstance->MemManagedGetAttrs(attributes, numAttributes, ptr, size, data, dataSizes);

    TIMESTAMP_END(rtMemManagedGetAttrs);

    COND_RETURN_WITH_NOLOG(error == RT_ERROR_DRV_NOT_SUPPORT, ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    COND_RETURN_WITH_NOLOG(error == RT_ERROR_FEATURE_NOT_SUPPORT, ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    ERROR_RETURN_WITH_EXT_ERRCODE(error);

    return ACL_RT_SUCCESS;

}



VISIBILITY_DEFAULT

rtError_t rtMemManagedPrefetchAsync(

    const void* ptr, size_t size, rtMemManagedLocation location, uint32_t flags, rtStream_t stream)

{

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    RT_VALIDATE_AND_UNWRAP_OBJECT(stream, Stream, streamPtr);

    const rtError_t error = apiInstance->MemManagedPrefetchAsync(ptr, size, location, flags, streamPtr);

    COND_RETURN_WITH_NOLOG(

        ((error == RT_ERROR_FEATURE_NOT_SUPPORT) || (error == RT_ERROR_DRV_NOT_SUPPORT)),

        ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    ERROR_RETURN_WITH_EXT_ERRCODE(error);

    return ACL_RT_SUCCESS;

}



VISIBILITY_DEFAULT

rtError_t rtMemManagedPrefetchBatchAsync(

    const void** ptrs, size_t* sizes, size_t count, rtMemManagedLocation* prefetchLocs, size_t* prefetchLocIdxs,

    size_t numPrefetchLocs, uint64_t flags, rtStream_t stream)

{

    Api* const apiInstance = Api::Instance();

    NULL_RETURN_ERROR_WITH_EXT_ERRCODE(apiInstance);

    RT_VALIDATE_AND_UNWRAP_OBJECT(stream, Stream, streamPtr);

    const rtError_t error = apiInstance->MemManagedPrefetchBatchAsync(

        ptrs, sizes, count, prefetchLocs, prefetchLocIdxs, numPrefetchLocs, flags, streamPtr);

    COND_RETURN_WITH_NOLOG(

        ((error == RT_ERROR_FEATURE_NOT_SUPPORT) || (error == RT_ERROR_DRV_NOT_SUPPORT)),

        ACL_ERROR_RT_FEATURE_NOT_SUPPORT);

    ERROR_RETURN_WITH_EXT_ERRCODE(error);

    return ACL_RT_SUCCESS;

}



#ifdef __cplusplus

}

#endif // __cplusplus