简体   繁体   中英

How to calculate cpu usage of an APP in ios using swift latest version? I am on xCode 11 as of now

I am currently using this code:

public func cpuUsage(_ cpuModel:CpuIosModel?) -> Float { guard let cpuModel = cpuModel else {

        print("cpuUsage is empty")
        return -1
    }

    var kr: kern_return_t
    var task_info_count: mach_msg_type_number_t
   
    task_info_count = mach_msg_type_number_t(TASK_INFO_MAX)
    var tinfo = [integer_t](repeating: 0, count: Int(task_info_count))

    kr = task_info(mach_task_self_, task_flavor_t(TASK_BASIC_INFO), &tinfo, &task_info_count)
    if kr != KERN_SUCCESS {
        return -1
    }

    var thread_list: thread_act_array_t? = UnsafeMutablePointer(mutating: [thread_act_t]())
    var thread_count: mach_msg_type_number_t = 0
    defer {
        if let thread_list = thread_list {
            vm_deallocate(mach_task_self_, vm_address_t(UnsafePointer(thread_list).pointee), vm_size_t(thread_count))
        }
    }
    kr = task_threads(mach_task_self_, &thread_list, &thread_count)

    if kr != KERN_SUCCESS {

        return -1
    }

    var tot_cpu: Float = 0
    var usr_space_time: Int = 0      //time in ms
    var system_space_time:Int = 0    //time in ms
    var thread_sleep_time: Int = 0   // time in sec
    var counter:Int = 0

    if let thread_list = thread_list {

        for j in 0 ..< Int(thread_count) {
            var thread_info_count = mach_msg_type_number_t(THREAD_INFO_MAX)
            var thinfo = [integer_t](repeating: 0, count: Int(thread_info_count))
            kr = thread_info(thread_list[j], thread_flavor_t(THREAD_BASIC_INFO),
                             &thinfo, &thread_info_count)

            let threadBasicInfo = convertThreadInfoToThreadBasicInfo(thinfo)

            if threadBasicInfo.flags != TH_FLAGS_IDLE {
                tot_cpu += (Float(threadBasicInfo.cpu_usage) / Float(TH_USAGE_SCALE)) * 100.0
                usr_space_time += Int(threadBasicInfo.user_time.microseconds/1000)
                system_space_time += Int(threadBasicInfo.system_time.microseconds/1000)
                thread_sleep_time += Int(threadBasicInfo.sleep_time)
                counter = counter + 1
            }
           

        } // for each thread

        if counter != 0 {
            //setCpuData(tot_cpu,usr_space_time,system_space_time)
            setCpuData(tot_cpu: tot_cpu, usr_space_time: usr_space_time, system_space_time: system_space_time, thread_sleep_time: thread_sleep_time,cpuModel: cpuModel)
            print(usr_space_time)
            return -1
        }
    }
    return tot_cpu
}

fileprivate func convertThreadInfoToThreadBasicInfo(_ threadInfo: [integer_t]) -> thread_basic_info {
    var result = thread_basic_info()
    result.user_time = time_value_t(seconds: threadInfo[0], microseconds: threadInfo[1])
    result.system_time = time_value_t(seconds: threadInfo[2], microseconds: threadInfo[3])
    result.cpu_usage = threadInfo[4]
    result.policy = threadInfo[5]
    result.run_state = threadInfo[6]
    result.flags = threadInfo[7]
    result.suspend_count = threadInfo[8]
    result.sleep_time = threadInfo[9]
    return result
}

But this is always giving tot_cpu as 0. Please help if you have a working code. Also i got this piece of code from internet. Can someone please explain why threadInfo[4] in convertThreadInfoToThreadBasicInfo() function is holding cpu usage value. Is this a pre defined thing.

I'm not sure if it's what you are looking for or not but you can take a look at this implementation:

func cpuUsage() -> Double {
  var totalUsageOfCPU: Double = 0.0
  var threadsList = UnsafeMutablePointer(mutating: [thread_act_t]())
  var threadsCount = mach_msg_type_number_t(0)
  let threadsResult = withUnsafeMutablePointer(to: &threadsList) {
    return $0.withMemoryRebound(to: thread_act_array_t?.self, capacity: 1) {
      task_threads(mach_task_self_, $0, &threadsCount)
    }
  }
  
  if threadsResult == KERN_SUCCESS {
    for index in 0..<threadsCount {
      var threadInfo = thread_basic_info()
      var threadInfoCount = mach_msg_type_number_t(THREAD_INFO_MAX)
      let infoResult = withUnsafeMutablePointer(to: &threadInfo) {
        $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
          thread_info(threadsList[Int(index)], thread_flavor_t(THREAD_BASIC_INFO), $0, &threadInfoCount)
        }
      }
      
      guard infoResult == KERN_SUCCESS else {
        break
      }
      
      let threadBasicInfo = threadInfo as thread_basic_info
      if threadBasicInfo.flags & TH_FLAGS_IDLE == 0 {
        totalUsageOfCPU = (totalUsageOfCPU + (Double(threadBasicInfo.cpu_usage) / Double(TH_USAGE_SCALE) * 100.0))
      }
    }
  }
  
  vm_deallocate(mach_task_self_, vm_address_t(UInt(bitPattern: threadsList)), vm_size_t(Int(threadsCount) * MemoryLayout<thread_t>.stride))
  return totalUsageOfCPU
}

Refer: https://github.com/dani-gavrilov/GDPerformanceView-Swift/blob/1ee9895fa9279c9858e2b72c3eea579608bf7597/GDPerformanceView-Swift/GDPerformanceMonitoring/Performance%D0%A1alculator.swift#L94

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM