import ctypes
from typing import List, Optional
from ubse.models.ubs_engine_model_mem import UbsMemNumaDesc
from ubse.ffi.ubs_engine_exceptions import UbsError, UbsErrNullPointer, UbsEngineConnectionError, UbsEngineAuthError, \
UbsEngineTimeoutError, UbsEngineInternalError, UbsEngineOutOfRangeError, UbsEngineNotExistError
from ubse.ffi.ubs_engine_types import UbsMemNumaDescT, UbsTopoNodeT
from ubse.ffi.ubs_engine_binding_base import UbsEngineBindingBase
class UbsEngineBindingMem(UbsEngineBindingBase):
"""mem相关接口"""
def __init__(self):
super().__init__()
self.setup_function_prototypes()
def ubs_handle_mem_result(self, result: int, operation: str):
error_map = {
3: ("UBS_ERR_NULL_POINTER", UbsErrNullPointer),
1000: ("UBS_ENGINE_ERR_OUT_OF_RANGE", UbsEngineOutOfRangeError),
1002: ("UBS_ENGINE_ERR_CONNECTION_FAILED", UbsEngineConnectionError),
1003: ("UBS_ENGINE_ERR_AUTH_FAILED", UbsEngineAuthError),
1004: ("UBS_ENGINE_ERR_TIMEOUT", UbsEngineTimeoutError),
1005: ("UBS_ENGINE_ERR_INTERNAL", UbsEngineInternalError),
1007: ("UBS_ENGINE_ERR_NOT_EXIST", UbsEngineNotExistError)
}
if result != 0:
error_info = error_map.get(result, (f"error: {result}", UbsError))
raise error_info[1](f"{operation} failed: {error_info[0]}")
def setup_function_prototypes(self):
"""设置C函数的参数和返回类型"""
if not self.lib_ubse:
return
self.lib_ubse.ubs_mem_numa_list.argtypes = [
ctypes.POINTER(ctypes.POINTER(UbsMemNumaDescT)),
ctypes.POINTER(ctypes.c_uint32)
]
self.lib_ubse.ubs_mem_numa_list.restype = ctypes.c_int32
self.lib_ubse.ubs_topo_node_list.argtypes = [
ctypes.POINTER(ctypes.POINTER(UbsTopoNodeT)),
ctypes.POINTER(ctypes.c_uint32)
]
self.lib_ubse.ubs_topo_node_list.restype = ctypes.c_int32
self.lib_ubse.ubs_topo_node_local_get.argtypes = [
ctypes.POINTER(UbsTopoNodeT)
]
self.lib_ubse.ubs_topo_node_local_get.restype = ctypes.c_int32
if hasattr(self.lib_ubse, 'free'):
self.lib_ubse.free.argtypes = [ctypes.c_void_p]
self.lib_ubse.free.restype = None
def ubs_mem_numa_list(self) -> List[UbsMemNumaDesc]:
"""查询本节点所有numa形态远端内存"""
if not self.lib_ubse:
raise ConnectionError("Native library not loaded")
numa_descs_ptr = ctypes.POINTER(UbsMemNumaDescT)()
numa_desc_cnt = ctypes.c_uint32(0)
try:
result = self.lib_ubse.ubs_mem_numa_list(
ctypes.byref(numa_descs_ptr),
ctypes.byref(numa_desc_cnt)
)
self.ubs_handle_mem_result(result, "ubs_mem_numa_list")
return self._convert_numa_descs(numa_descs_ptr, numa_desc_cnt.value)
except Exception as e:
print(f"调用拓扑接口失败: ubs_mem_numa_list failed: {e}")
raise
finally:
self._safe_free_numa_descs(numa_descs_ptr)
def _convert_numa_descs(self, numa_descs_ptr, desc_count) -> List[UbsMemNumaDesc]:
"""转换NUMA描述符数据"""
if not numa_descs_ptr or desc_count == 0:
return []
numa_descs = []
for i in range(desc_count):
desc_ptr = ctypes.cast(
ctypes.addressof(numa_descs_ptr.contents) + i * ctypes.sizeof(UbsMemNumaDescT),
ctypes.POINTER(UbsMemNumaDescT)
)
numa_descs.append(UbsMemNumaDesc.from_c_struct(desc_ptr.contents))
return numa_descs
def _safe_free_numa_descs(self, numa_descs_ptr):
"""安全释放NUMA描述符内存"""
if not numa_descs_ptr:
return
try:
if hasattr(self.lib_ubse, 'free'):
self.lib_ubse.free(numa_descs_ptr)
except Exception as e:
print(f"Warning: Failed to free numa desc memory: {e}")