Girish | 1f002cf | 2023-02-17 00:36:29 +0000 | [diff] [blame^] | 1 | /* |
| 2 | ** |
| 3 | ** Copyright 2023, The Android Open Source Project |
| 4 | ** |
| 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | ** you may not use this file except in compliance with the License. |
| 7 | ** You may obtain a copy of the License at |
| 8 | ** |
| 9 | ** http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | ** |
| 11 | ** Unless required by applicable law or agreed to in writing, software |
| 12 | ** distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | ** See the License for the specific language governing permissions and |
| 15 | ** limitations under the License. |
| 16 | */ |
| 17 | |
| 18 | //#define LOG_NDEBUG 0 |
| 19 | #define LOG_TAG "ResourceManagerMetrics" |
| 20 | #include <utils/Log.h> |
| 21 | #include <mediautils/ProcessInfo.h> |
| 22 | |
| 23 | #include <stats_media_metrics.h> |
| 24 | |
| 25 | #include "UidObserver.h" |
| 26 | #include "ResourceManagerMetrics.h" |
| 27 | |
| 28 | #include <cmath> |
| 29 | #include <sstream> |
| 30 | |
| 31 | namespace android { |
| 32 | |
| 33 | using stats::media_metrics::stats_write; |
| 34 | using stats::media_metrics::MEDIA_CODEC_STARTED; |
| 35 | using stats::media_metrics::MEDIA_CODEC_STOPPED; |
| 36 | // Disabling this for now. |
| 37 | #ifdef ENABLE_MEDIA_CODEC_CONCURRENT_USAGE_REPORTED |
| 38 | using stats::media_metrics::MEDIA_CODEC_CONCURRENT_USAGE_REPORTED; |
| 39 | #endif |
| 40 | using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED; |
| 41 | using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS; |
| 42 | using stats::media_metrics::\ |
| 43 | MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS; |
| 44 | using stats::media_metrics::\ |
| 45 | MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES; |
| 46 | |
| 47 | inline const char* getCodecType(MediaResourceSubType codecType) { |
| 48 | switch (codecType) { |
| 49 | case MediaResourceSubType::kAudioCodec: return "Audio"; |
| 50 | case MediaResourceSubType::kVideoCodec: return "Video"; |
| 51 | case MediaResourceSubType::kImageCodec: return "Image"; |
| 52 | case MediaResourceSubType::kUnspecifiedSubType: |
| 53 | default: |
| 54 | return "Unspecified"; |
| 55 | } |
| 56 | return "Unspecified"; |
| 57 | } |
| 58 | |
| 59 | static CodecBucket getCodecBucket(bool isHardware, |
| 60 | bool isEncoder, |
| 61 | MediaResourceSubType codecType) { |
| 62 | if (isHardware) { |
| 63 | switch (codecType) { |
| 64 | case MediaResourceSubType::kAudioCodec: |
| 65 | if (isEncoder) return HwAudioEncoder; |
| 66 | return HwAudioDecoder; |
| 67 | case MediaResourceSubType::kVideoCodec: |
| 68 | if (isEncoder) return HwVideoEncoder; |
| 69 | return HwVideoDecoder; |
| 70 | case MediaResourceSubType::kImageCodec: |
| 71 | if (isEncoder) return HwImageEncoder; |
| 72 | return HwImageDecoder; |
| 73 | case MediaResourceSubType::kUnspecifiedSubType: |
| 74 | default: |
| 75 | return CodecBucketUnspecified; |
| 76 | } |
| 77 | } else { |
| 78 | switch (codecType) { |
| 79 | case MediaResourceSubType::kAudioCodec: |
| 80 | if (isEncoder) return SwAudioEncoder; |
| 81 | return SwAudioDecoder; |
| 82 | case MediaResourceSubType::kVideoCodec: |
| 83 | if (isEncoder) return SwVideoEncoder; |
| 84 | return SwVideoDecoder; |
| 85 | case MediaResourceSubType::kImageCodec: |
| 86 | if (isEncoder) return SwImageEncoder; |
| 87 | return SwImageDecoder; |
| 88 | case MediaResourceSubType::kUnspecifiedSubType: |
| 89 | default: |
| 90 | return CodecBucketUnspecified; |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | return CodecBucketUnspecified; |
| 95 | } |
| 96 | |
| 97 | static bool getLogMessage(int hwCount, int swCount, std::stringstream& logMsg) { |
| 98 | bool update = false; |
| 99 | logMsg.clear(); |
| 100 | |
| 101 | if (hwCount > 0) { |
| 102 | logMsg << " HW: " << hwCount; |
| 103 | update = true; |
| 104 | } |
| 105 | if (swCount > 0) { |
| 106 | logMsg << " SW: " << swCount; |
| 107 | update = true; |
| 108 | } |
| 109 | |
| 110 | if (update) { |
| 111 | logMsg << " ] "; |
| 112 | } |
| 113 | return update; |
| 114 | } |
| 115 | |
| 116 | ResourceManagerMetrics::ResourceManagerMetrics(const sp<ProcessInfoInterface>& processInfo) { |
| 117 | // Create a process termination watcher, with 5seconds of polling frequency. |
| 118 | mUidObserver = sp<UidObserver>::make(processInfo, |
| 119 | [this] (int32_t pid, uid_t uid) { |
| 120 | onProcessTerminated(pid, uid); |
| 121 | }); |
| 122 | mUidObserver->start(); |
| 123 | } |
| 124 | |
| 125 | ResourceManagerMetrics::~ResourceManagerMetrics() { |
| 126 | mUidObserver->stop(); |
| 127 | } |
| 128 | |
| 129 | void ResourceManagerMetrics::addPid(int pid, uid_t uid) { |
| 130 | if (uid != 0) { |
| 131 | std::scoped_lock lock(mLock); |
| 132 | mUidObserver->add(pid, uid); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | void ResourceManagerMetrics::notifyClientCreated(const ClientInfoParcel& clientInfo) { |
| 137 | std::scoped_lock lock(mLock); |
| 138 | // Update the resource instance count. |
| 139 | std::map<std::string, int>::iterator found = mConcurrentResourceCountMap.find(clientInfo.name); |
| 140 | if (found == mConcurrentResourceCountMap.end()) { |
| 141 | mConcurrentResourceCountMap[clientInfo.name] = 1; |
| 142 | } else { |
| 143 | found->second++; |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | void ResourceManagerMetrics::notifyClientReleased(const ClientInfoParcel& clientInfo) { |
| 148 | bool stopCalled = true; |
| 149 | ClientConfigMap::iterator found; |
| 150 | { |
| 151 | std::scoped_lock lock(mLock); |
| 152 | found = mClientConfigMap.find(clientInfo.id); |
| 153 | if (found != mClientConfigMap.end()) { |
| 154 | // Release is called without Stop! |
| 155 | stopCalled = false; |
| 156 | } |
| 157 | } |
| 158 | if (!stopCalled) { |
| 159 | // call Stop to update the metrics. |
| 160 | notifyClientStopped(found->second); |
| 161 | } |
| 162 | { |
| 163 | std::scoped_lock lock(mLock); |
| 164 | // Update the resource instance count also. |
| 165 | std::map<std::string, int>::iterator found = |
| 166 | mConcurrentResourceCountMap.find(clientInfo.name); |
| 167 | if (found != mConcurrentResourceCountMap.end()) { |
| 168 | if (found->second > 0) { |
| 169 | found->second--; |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clientConfig) { |
| 176 | std::scoped_lock lock(mLock); |
| 177 | int pid = clientConfig.clientInfo.pid; |
| 178 | // We need to observer this process. |
| 179 | mUidObserver->add(pid, clientConfig.clientInfo.uid); |
| 180 | |
| 181 | // Update the client config for thic client. |
| 182 | mClientConfigMap[clientConfig.clientInfo.id] = clientConfig; |
| 183 | |
| 184 | // Update the concurrent codec count for this process. |
| 185 | CodecBucket codecBucket = getCodecBucket(clientConfig.isHardware, |
| 186 | clientConfig.isEncoder, |
| 187 | clientConfig.codecType); |
| 188 | increaseConcurrentCodecs(pid, codecBucket); |
| 189 | |
| 190 | if (clientConfig.codecType == MediaResourceSubType::kVideoCodec || |
| 191 | clientConfig.codecType == MediaResourceSubType::kImageCodec) { |
| 192 | // Update the pixel count for this process |
| 193 | increasePixelCount(pid, clientConfig.width * (long)clientConfig.height); |
| 194 | } |
| 195 | |
| 196 | // System concurrent codec usage |
| 197 | int systemConcurrentCodecCount = mConcurrentCodecsMap[codecBucket]; |
| 198 | // Process/Application concurrent codec usage for this type of codec |
| 199 | int appConcurrentCodecCount = mProcessConcurrentCodecsMap[pid].mCurrent[codecBucket]; |
| 200 | // Process/Application's current pixel count. |
| 201 | long pixelCount = 0; |
| 202 | std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid); |
| 203 | if (it != mProcessPixelsMap.end()) { |
| 204 | pixelCount = it->second.mCurrent; |
| 205 | } |
| 206 | |
| 207 | int result = stats_write( |
| 208 | MEDIA_CODEC_STARTED, |
| 209 | clientConfig.clientInfo.uid, |
| 210 | clientConfig.id, |
| 211 | clientConfig.clientInfo.name.c_str(), |
| 212 | static_cast<int32_t>(clientConfig.codecType), |
| 213 | clientConfig.isEncoder, |
| 214 | clientConfig.isHardware, |
| 215 | clientConfig.width, clientConfig.height, |
| 216 | systemConcurrentCodecCount, |
| 217 | appConcurrentCodecCount, |
| 218 | pixelCount); |
| 219 | |
| 220 | ALOGV("%s: Pushed MEDIA_CODEC_STARTED atom: " |
| 221 | "Process[pid(%d): uid(%d)] " |
| 222 | "Codec: [%s: %ju] is %s %s %s " |
| 223 | "Timestamp: %jd " |
| 224 | "Resolution: %d x %d " |
| 225 | "ConcurrentCodec[%d]={System: %d App: %d} " |
| 226 | "result: %d", |
| 227 | __func__, |
| 228 | pid, clientConfig.clientInfo.uid, |
| 229 | clientConfig.clientInfo.name.c_str(), |
| 230 | clientConfig.id, |
| 231 | clientConfig.isHardware? "hardware" : "software", |
| 232 | getCodecType(clientConfig.codecType), |
| 233 | clientConfig.isEncoder? "encoder" : "decoder", |
| 234 | clientConfig.timeStamp, |
| 235 | clientConfig.width, clientConfig.height, |
| 236 | codecBucket, systemConcurrentCodecCount, appConcurrentCodecCount, |
| 237 | result); |
| 238 | } |
| 239 | |
| 240 | void ResourceManagerMetrics::notifyClientStopped(const ClientConfigParcel& clientConfig) { |
| 241 | std::scoped_lock lock(mLock); |
| 242 | int pid = clientConfig.clientInfo.pid; |
| 243 | // Update the concurrent codec count for this process. |
| 244 | CodecBucket codecBucket = getCodecBucket(clientConfig.isHardware, |
| 245 | clientConfig.isEncoder, |
| 246 | clientConfig.codecType); |
| 247 | decreaseConcurrentCodecs(pid, codecBucket); |
| 248 | |
| 249 | if (clientConfig.codecType == MediaResourceSubType::kVideoCodec || |
| 250 | clientConfig.codecType == MediaResourceSubType::kImageCodec) { |
| 251 | // Update the pixel count for this process |
| 252 | decreasePixelCount(pid, clientConfig.width * (long)clientConfig.height); |
| 253 | } |
| 254 | |
| 255 | // System concurrent codec usage |
| 256 | int systemConcurrentCodecCount = mConcurrentCodecsMap[codecBucket]; |
| 257 | // Process/Application concurrent codec usage for this type of codec |
| 258 | int appConcurrentCodecCount = 0; |
| 259 | std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid); |
| 260 | if (found != mProcessConcurrentCodecsMap.end()) { |
| 261 | appConcurrentCodecCount = found->second.mCurrent[codecBucket]; |
| 262 | } |
| 263 | // Process/Application's current pixel count. |
| 264 | long pixelCount = 0; |
| 265 | std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid); |
| 266 | if (it != mProcessPixelsMap.end()) { |
| 267 | pixelCount = it->second.mCurrent; |
| 268 | } |
| 269 | |
| 270 | // calculate the usageTime as: |
| 271 | // MediaCodecStopped.clientConfig.timeStamp - |
| 272 | // MediaCodecStarted.clientConfig.timeStamp |
| 273 | int64_t usageTime = 0; |
| 274 | ClientConfigMap::iterator entry = mClientConfigMap.find(clientConfig.clientInfo.id); |
| 275 | if (entry != mClientConfigMap.end()) { |
| 276 | usageTime = clientConfig.timeStamp - entry->second.timeStamp; |
| 277 | // And we can erase this config now. |
| 278 | mClientConfigMap.erase(entry); |
| 279 | } else { |
| 280 | ALOGW("%s: Start Config is missing!", __func__); |
| 281 | } |
| 282 | |
| 283 | int result = stats_write( |
| 284 | MEDIA_CODEC_STOPPED, |
| 285 | clientConfig.clientInfo.uid, |
| 286 | clientConfig.id, |
| 287 | clientConfig.clientInfo.name.c_str(), |
| 288 | static_cast<int32_t>(clientConfig.codecType), |
| 289 | clientConfig.isEncoder, |
| 290 | clientConfig.isHardware, |
| 291 | clientConfig.width, clientConfig.height, |
| 292 | systemConcurrentCodecCount, |
| 293 | appConcurrentCodecCount, |
| 294 | pixelCount, |
| 295 | usageTime); |
| 296 | ALOGV("%s: Pushed MEDIA_CODEC_STOPPED atom: " |
| 297 | "Process[pid(%d): uid(%d)] " |
| 298 | "Codec: [%s: %ju] is %s %s %s " |
| 299 | "Timestamp: %jd Usage time: %jd " |
| 300 | "Resolution: %d x %d " |
| 301 | "ConcurrentCodec[%d]={System: %d App: %d} " |
| 302 | "result: %d", |
| 303 | __func__, |
| 304 | pid, clientConfig.clientInfo.uid, |
| 305 | clientConfig.clientInfo.name.c_str(), |
| 306 | clientConfig.id, |
| 307 | clientConfig.isHardware? "hardware" : "software", |
| 308 | getCodecType(clientConfig.codecType), |
| 309 | clientConfig.isEncoder? "encoder" : "decoder", |
| 310 | clientConfig.timeStamp, usageTime, |
| 311 | clientConfig.width, clientConfig.height, |
| 312 | codecBucket, systemConcurrentCodecCount, appConcurrentCodecCount, |
| 313 | result); |
| 314 | } |
| 315 | |
| 316 | void ResourceManagerMetrics::onProcessTerminated(int32_t pid, uid_t uid) { |
| 317 | std::scoped_lock lock(mLock); |
| 318 | // post MediaCodecConcurrentUsageReported for this terminated pid. |
| 319 | pushConcurrentUsageReport(pid, uid); |
| 320 | } |
| 321 | |
| 322 | void ResourceManagerMetrics::pushConcurrentUsageReport(int32_t pid, uid_t uid) { |
| 323 | // Process/Application peak concurrent codec usage |
| 324 | std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid); |
| 325 | if (found == mProcessConcurrentCodecsMap.end()) { |
| 326 | ALOGI("%s: No MEDIA_CODEC_CONCURRENT_USAGE_REPORTED atom Entry for: " |
| 327 | "Application[pid(%d): uid(%d)]", __func__, pid, uid); |
| 328 | return; |
| 329 | } |
| 330 | const ConcurrentCodecsMap& codecsMap = found->second.mPeak; |
| 331 | int peakHwAudioEncoderCount = codecsMap[HwAudioEncoder]; |
| 332 | int peakHwAudioDecoderCount = codecsMap[HwAudioDecoder]; |
| 333 | int peakHwVideoEncoderCount = codecsMap[HwVideoEncoder]; |
| 334 | int peakHwVideoDecoderCount = codecsMap[HwVideoDecoder]; |
| 335 | int peakHwImageEncoderCount = codecsMap[HwImageEncoder]; |
| 336 | int peakHwImageDecoderCount = codecsMap[HwImageDecoder]; |
| 337 | int peakSwAudioEncoderCount = codecsMap[SwAudioEncoder]; |
| 338 | int peakSwAudioDecoderCount = codecsMap[SwAudioDecoder]; |
| 339 | int peakSwVideoEncoderCount = codecsMap[SwVideoEncoder]; |
| 340 | int peakSwVideoDecoderCount = codecsMap[SwVideoDecoder]; |
| 341 | int peakSwImageEncoderCount = codecsMap[SwImageEncoder]; |
| 342 | int peakSwImageDecoderCount = codecsMap[SwImageDecoder]; |
| 343 | |
| 344 | long peakPixels = 0; |
| 345 | std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid); |
| 346 | if (it == mProcessPixelsMap.end()) { |
| 347 | ALOGI("%s: No Video Codec Entry for Application[pid(%d): uid(%d)]", |
| 348 | __func__, pid, uid); |
| 349 | } else { |
| 350 | peakPixels = it->second.mPeak; |
| 351 | } |
| 352 | std::string peakPixelsLog("Peak Pixels: " + std::to_string(peakPixels)); |
| 353 | |
| 354 | std::stringstream peakCodecLog; |
| 355 | peakCodecLog << "Peak { "; |
| 356 | std::stringstream logMsg; |
| 357 | if (getLogMessage(peakHwAudioEncoderCount, peakSwAudioEncoderCount, logMsg)) { |
| 358 | peakCodecLog << "AudioEnc[" << logMsg.str(); |
| 359 | } |
| 360 | if (getLogMessage(peakHwAudioDecoderCount, peakSwAudioDecoderCount, logMsg)) { |
| 361 | peakCodecLog << "AudioDec[" << logMsg.str(); |
| 362 | } |
| 363 | if (getLogMessage(peakHwVideoEncoderCount, peakSwVideoEncoderCount, logMsg)) { |
| 364 | peakCodecLog << "VideoEnc[" << logMsg.str(); |
| 365 | } |
| 366 | if (getLogMessage(peakHwVideoDecoderCount, peakSwVideoDecoderCount, logMsg)) { |
| 367 | peakCodecLog << "VideoDec[" << logMsg.str(); |
| 368 | } |
| 369 | if (getLogMessage(peakHwImageEncoderCount, peakSwImageEncoderCount, logMsg)) { |
| 370 | peakCodecLog << "ImageEnc[" << logMsg.str(); |
| 371 | } |
| 372 | if (getLogMessage(peakHwImageDecoderCount, peakSwImageDecoderCount, logMsg)) { |
| 373 | peakCodecLog << "ImageDec[" << logMsg.str(); |
| 374 | } |
| 375 | peakCodecLog << "}"; |
| 376 | |
| 377 | #ifdef ENABLE_MEDIA_CODEC_CONCURRENT_USAGE_REPORTED |
| 378 | int result = stats_write( |
| 379 | MEDIA_CODEC_CONCURRENT_USAGE_REPORTED, |
| 380 | uid, |
| 381 | peakHwVideoDecoderCount, |
| 382 | peakHwVideoEncoderCount, |
| 383 | peakSwVideoDecoderCount, |
| 384 | peakSwVideoEncoderCount, |
| 385 | peakHwAudioDecoderCount, |
| 386 | peakHwAudioEncoderCount, |
| 387 | peakSwAudioDecoderCount, |
| 388 | peakSwAudioEncoderCount, |
| 389 | peakHwImageDecoderCount, |
| 390 | peakHwImageEncoderCount, |
| 391 | peakSwImageDecoderCount, |
| 392 | peakSwImageEncoderCount, |
| 393 | peakPixels); |
| 394 | ALOGI("%s: Pushed MEDIA_CODEC_CONCURRENT_USAGE_REPORTED atom: " |
| 395 | "Process[pid(%d): uid(%d)] %s %s result: %d", |
| 396 | __func__, pid, uid, peakCodecLog.str().c_str(), peakPixelsLog.c_str(), result); |
| 397 | #else |
| 398 | ALOGI("%s: Concurrent Codec Usage Report for the Process[pid(%d): uid(%d)] is %s %s", |
| 399 | __func__, pid, uid, peakCodecLog.str().c_str(), peakPixelsLog.c_str()); |
| 400 | #endif |
| 401 | } |
| 402 | |
| 403 | void ResourceManagerMetrics::pushReclaimAtom(const ClientInfoParcel& clientInfo, |
| 404 | const std::vector<int>& priorities, |
| 405 | const Vector<std::shared_ptr<IResourceManagerClient>>& clients, |
| 406 | const PidUidVector& idList, bool reclaimed) { |
| 407 | // Construct the metrics for codec reclaim as a pushed atom. |
| 408 | // 1. Information about the requester. |
| 409 | // - UID and the priority (oom score) |
| 410 | int32_t callingPid = clientInfo.pid; |
| 411 | int32_t requesterUid = clientInfo.uid; |
| 412 | std::string clientName = clientInfo.name; |
| 413 | int requesterPriority = priorities[0]; |
| 414 | |
| 415 | // 2. Information about the codec. |
| 416 | // - Name of the codec requested |
| 417 | // - Number of concurrent codecs running. |
| 418 | int32_t noOfConcurrentCodecs = 0; |
| 419 | std::map<std::string, int>::iterator found = mConcurrentResourceCountMap.find(clientName); |
| 420 | if (found != mConcurrentResourceCountMap.end()) { |
| 421 | noOfConcurrentCodecs = found->second; |
| 422 | } |
| 423 | |
| 424 | // 3. Information about the Reclaim: |
| 425 | // - Status of reclaim request |
| 426 | // - How many codecs are reclaimed |
| 427 | // - For each codecs reclaimed, information of the process that it belonged to: |
| 428 | // - UID and the Priority (oom score) |
| 429 | int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS; |
| 430 | if (!reclaimed) { |
| 431 | if (clients.size() == 0) { |
| 432 | // No clients to reclaim from |
| 433 | reclaimStatus = |
| 434 | MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS; |
| 435 | } else { |
| 436 | // Couldn't reclaim resources from the clients |
| 437 | reclaimStatus = |
| 438 | MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES; |
| 439 | } |
| 440 | } |
| 441 | int32_t noOfCodecsReclaimed = clients.size(); |
| 442 | int32_t targetIndex = 1; |
| 443 | for (PidUidVector::const_reference id : idList) { |
| 444 | int32_t targetUid = id.second; |
| 445 | int targetPriority = priorities[targetIndex]; |
| 446 | // Post the pushed atom |
| 447 | int result = stats_write( |
| 448 | MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED, |
| 449 | requesterUid, |
| 450 | requesterPriority, |
| 451 | clientName.c_str(), |
| 452 | noOfConcurrentCodecs, |
| 453 | reclaimStatus, |
| 454 | noOfCodecsReclaimed, |
| 455 | targetIndex, |
| 456 | targetUid, |
| 457 | targetPriority); |
| 458 | ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: " |
| 459 | "Requester[pid(%d): uid(%d): priority(%d)] " |
| 460 | "Codec: [%s] " |
| 461 | "No of concurrent codecs: %d " |
| 462 | "Reclaim Status: %d " |
| 463 | "No of codecs reclaimed: %d " |
| 464 | "Target[%d][pid(%d): uid(%d): priority(%d)] result: %d", |
| 465 | __func__, callingPid, requesterUid, requesterPriority, |
| 466 | clientName.c_str(), noOfConcurrentCodecs, |
| 467 | reclaimStatus, noOfCodecsReclaimed, |
| 468 | targetIndex, id.first, targetUid, targetPriority, result); |
| 469 | targetIndex++; |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | void ResourceManagerMetrics::increaseConcurrentCodecs(int32_t pid, |
| 474 | CodecBucket codecBucket) { |
| 475 | // Increase the codec usage across the system. |
| 476 | mConcurrentCodecsMap[codecBucket]++; |
| 477 | |
| 478 | // Now update the codec usage for this (pid) process. |
| 479 | std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid); |
| 480 | if (found == mProcessConcurrentCodecsMap.end()) { |
| 481 | ConcurrentCodecs codecs; |
| 482 | codecs.mCurrent[codecBucket] = 1; |
| 483 | codecs.mPeak[codecBucket] = 1; |
| 484 | mProcessConcurrentCodecsMap.emplace(pid, codecs); |
| 485 | } else { |
| 486 | found->second.mCurrent[codecBucket]++; |
| 487 | // Check if it's the peak count for this slot. |
| 488 | if (found->second.mPeak[codecBucket] < found->second.mCurrent[codecBucket]) { |
| 489 | found->second.mPeak[codecBucket] = found->second.mCurrent[codecBucket]; |
| 490 | } |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | void ResourceManagerMetrics::decreaseConcurrentCodecs(int32_t pid, |
| 495 | CodecBucket codecBucket) { |
| 496 | // Decrease the codec usage across the system. |
| 497 | if (mConcurrentCodecsMap[codecBucket] > 0) { |
| 498 | mConcurrentCodecsMap[codecBucket]--; |
| 499 | } |
| 500 | |
| 501 | // Now update the codec usage for this (pid) process. |
| 502 | std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid); |
| 503 | if (found != mProcessConcurrentCodecsMap.end()) { |
| 504 | if (found->second.mCurrent[codecBucket] > 0) { |
| 505 | found->second.mCurrent[codecBucket]--; |
| 506 | } |
| 507 | } |
| 508 | } |
| 509 | |
| 510 | void ResourceManagerMetrics::increasePixelCount(int32_t pid, long pixels) { |
| 511 | // Now update the current pixel usage for this (pid) process. |
| 512 | std::map<int32_t, PixelCount>::iterator found = mProcessPixelsMap.find(pid); |
| 513 | if (found == mProcessPixelsMap.end()) { |
| 514 | PixelCount pixelCount {pixels, pixels}; |
| 515 | mProcessPixelsMap.emplace(pid, pixelCount); |
| 516 | } else { |
| 517 | if (__builtin_add_overflow(found->second.mCurrent, pixels, &found->second.mCurrent)) { |
| 518 | ALOGI("Pixel Count overflow"); |
| 519 | return; |
| 520 | } |
| 521 | // Check if it's the peak count for this slot. |
| 522 | if (found->second.mPeak < found->second.mCurrent) { |
| 523 | found->second.mPeak = found->second.mCurrent; |
| 524 | } |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | void ResourceManagerMetrics::decreasePixelCount(int32_t pid, long pixels) { |
| 529 | // Now update the current pixel usage for this (pid) process. |
| 530 | std::map<int32_t, PixelCount>::iterator found = mProcessPixelsMap.find(pid); |
| 531 | if (found != mProcessPixelsMap.end()) { |
| 532 | if (found->second.mCurrent < pixels) { |
| 533 | found->second.mCurrent = 0; |
| 534 | } else { |
| 535 | if (__builtin_sub_overflow(found->second.mCurrent, pixels, &found->second.mCurrent)) { |
| 536 | ALOGI("Pixel Count overflow"); |
| 537 | return; |
| 538 | } |
| 539 | } |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | long ResourceManagerMetrics::getPeakConcurrentPixelCount(int pid) const { |
| 544 | std::map<int32_t, PixelCount>::const_iterator found = mProcessPixelsMap.find(pid); |
| 545 | if (found != mProcessPixelsMap.end()) { |
| 546 | return found->second.mPeak; |
| 547 | } |
| 548 | |
| 549 | return 0; |
| 550 | } |
| 551 | |
| 552 | long ResourceManagerMetrics::getCurrentConcurrentPixelCount(int pid) const { |
| 553 | std::map<int32_t, PixelCount>::const_iterator found = mProcessPixelsMap.find(pid); |
| 554 | if (found != mProcessPixelsMap.end()) { |
| 555 | return found->second.mCurrent; |
| 556 | } |
| 557 | |
| 558 | return 0; |
| 559 | } |
| 560 | |
| 561 | } // namespace android |