内存泄漏系列专题分析之三十五:开机内存性能优化之一:Camx进程启动提前加载so库
【关注我,后续持续新增专题博文,谢谢!!!】
上一篇我们讲了:
这一篇我们开始讲: 内存泄漏系列专题分析之 : 开机内存&&性能优化之一:Camx进程启动提前加载so
目录
一、问题背景
二、实现方案
2.1:基于原理分析
2.2 :Camx HAL进程启动相关代码
2.3 :实现提前加载so库
一、问题背景
在处理相关Camera性能问题时,发现冷启动性能很差,进行拆解发现打开相机过程中会加载很多so库,而加载so库是IO操作,加载so会耗费大量的时间,因此我们在Camx进程启动时就提前加载相关耗时so到进程,这样冷启动时,就无需重新加载,这样冷启动性能将提升很多。
二、实现方案
2.1:基于原理分析
Camx HAL进程启动时加载,那么我们分析进程启动流程,在对应的地方加载即可,那么一般在构造函数中加载即可。
2.2 :Camx HAL进程启动相关代码
我们在HALDevice* HALDevice::Create里的CamxResult HALDevice::Initialize()函数中添加即可。
\camx\src\core\hal\camxhaldevice.cpp//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HALDevice::~HALDevice //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HALDevice::~HALDevice() { }//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HALDevice::Create //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HALDevice* HALDevice::Create(const HwModule* pHwModule,UINT32 cameraId,UINT32 frameworkId) {CamxResult result = CamxResultENoMemory;HALDevice* pHALDevice = CAMX_NEW HALDevice;ATRACE_BEGIN("HALDevice::Create");if (NULL != pHALDevice){pHALDevice->m_fwId = frameworkId;result = pHALDevice->Initialize(pHwModule, cameraId);if (CamxResultSuccess != result){pHALDevice->Destroy();pHALDevice = NULL;}}ATRACE_END();return pHALDevice; }CamxResult HALDevice::Initialize(const HwModule* pHwModule,UINT32 cameraId) {CamxResult result = CamxResultSuccess;CSLCameraPlatform CSLPlatform = {};m_cameraId = cameraId;m_pKMDDebugBufferInfo = NULL;ATRACE_BEGIN("HALDevice::Initialize");PinFile();//加载soif (CamxResultSuccess == result){m_camera3Device.hwDevice.tag = HARDWARE_DEVICE_TAG; /// @todo (CAMX-351) Get from local macrom_camera3Device.hwDevice.close = reinterpret_cast<CloseFunc>(GetHwDeviceCloseFunc());m_camera3Device.pDeviceOps = reinterpret_cast<Camera3DeviceOps*>(GetCamera3DeviceOps());m_camera3Device.pPrivateData = this;// NOWHINE CP036a: Need exception herem_camera3Device.hwDevice.pModule = const_cast<HwModule*>(pHwModule);m_HALCallbacks.process_capture_result = ProcessCaptureResult;m_HALCallbacks.notify_result = Notify;m_HALCallbacks.trigger_system_event = DumpEvent;m_HALCallbacks.request_stream_buffers = RequestStreamBuffers;m_HALCallbacks.return_stream_buffers = ReturnStreamBuffers;}ClearFrameworkRequestBuffer();for (UINT i = 0; i < static_cast<UINT>(TIMER_MAX); i++){m_pCameraTimerLock[i] = Mutex::Create("CameraTimerMutex");m_pCameraTimerCondition[i] = Condition::Create("CameraTimer");if ((NULL == m_pCameraTimerLock[i]) ||(NULL == m_pCameraTimerCondition[i])){result = CamxResultEFailed;CAMX_LOG_ERROR(CamxLogGroupHAL, "Warning: create CameraTimer failed!");}}SIZE_T entryCapacity;SIZE_T dataSize;HAL3MetadataUtil::CalculateSizeAllMeta(&entryCapacity, &dataSize, TagSectionVisibleToFramework);m_pResultMetadata = HAL3MetadataUtil::CreateMetadata(entryCapacity,dataSize);for (UINT i = RequestTemplatePreview; i <= RequestTemplateCount; i++){ConstructDefaultRequestSettings(static_cast<Camera3RequestTemplate>(i));}const StaticSettings* pStaticSettings = HwEnvironment::GetInstance()->GetStaticSettings();m_numPartialResult = pStaticSettings->numMetadataResults;/* We will increment the Partial result count by 1 if CHI also has its own implementation */if (CHIPartialDataSeparate == pStaticSettings->enableCHIPartialData){m_numPartialResult++;}m_tracingZoom = FALSE;m_tracingZoomRatio = FALSE;ATRACE_END();return result; }
2.3 :实现提前加载so库
读取PinSos里的所有so库,通过mmap方式加载到进程中,并且是在开机时就加载到开机内存中。
[PinSos]so[0]=/vendor/lib64/libthermalclient.soso[1]=/vendor/lib64/libcamxtintlessalgo.soso[2]=/vendor/lib64/libswregistrationalgo.soso[3]=/vendor/lib64/libcamxswprocessalgo.soso[4]=/vendor/lib64/libipebpsstriping.soso[5]=/vendor/lib64/hw/android.hardware.graphics.mapper@4.0-impl-qti-display.soso[6]=/vendor/lib64/android.hardware.camera.device@1.0.soso[7]=/vendor/lib64/camera/components/com.qti.stats.haf.soso[8]=/vendor/lib64/camera/components/com.qti.stats.hafoverride.soso[9]=/vendor/lib64/camera/components/com.qti.stats.pdlib.soso[10]=/vendor/lib64/libcamxexternalformatutils.soso[11]=/vendor/lib64/libllvm-qgl.soso[12]=/vendor/lib64/com.qualcomm.mcx.distortionmapper.soso[13]=/vendor/lib64/com.qualcomm.mcx.linearmapper.soso[14]=/vendor/lib64/com.qualcomm.mcx.policy.mfl.soso[15]=/vendor/lib64/libhme.soVOID PinFile() {CDKResult result = CDKResultSuccess;static BOOL useDlopen = false;const char* pGroup = "PinSos";const char* pKey = "so";const CHAR* pValue = NULL;UINT32 count = 0;count = GetKeyCount(pGroup);for (UINT i = 0; i < count; i++){char index[256];snprintf(index, sizeof(index), "%u", i);GetString(pGroup, pKey, index, &pValue);result = PinFileRanges(pValue);if (CDKResultEFailed == result){CHX_LOG_INFO("pin file failed");}} }UINT32 PinFileRanges(const char* fileToPin) {int fd = 0;int mapsize = 0;void* address = NULL;struct stat buf;FILE *F = fopen(fileToPin,"r");if (F == NULL){CHX_LOG_INFO("PinFileRanges fail to open file %s,maybe not exist",fileToPin);}else{fd = fileno(F);if (stat(fileToPin,&buf) == -1){CHX_LOG_ERROR("PinFileRanges fail to stat");}mapsize = buf.st_size;address = mmap(NULL,mapsize,PROT_READ,MAP_SHARED,fd,0);if (address == MAP_FAILED){CHX_LOG_INFO("%s map failed",fileToPin);result = CDKResultEFailed;}int pagesize = getpagesize();int pinStart = 0;int pinLength = mapsize;pinLength += pinStart % pagesize;pinStart -= pinStart % pagesize;if(pinLength % pagesize !=0){pinLength += pagesize - pinLength%pagesize;}if (pinLength > 0){UINT64 sum = 0;for (int i = 0; i < pinLength; i++){sum += *((char *)address+i);}result = mlock((char *)address + pinStart,pinLength);if (result == -1){CHX_LOG_INFO("mlock failed");result = CDKResultEFailed;}else{CHX_LOG_INFO("mlock success");}}fclose(F);}return result; }
【关注我,后续持续新增专题博文,谢谢!!!】
下一篇讲解: