Created
November 3, 2018 14:21
-
-
Save NSEGeorge/688a4a8eaaaec98f0e59507ca91724f5 to your computer and use it in GitHub Desktop.
Swift implementation of function for measuring application launch time. Call it from start or end didFinishLaunchingWithOptions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class LaunchTimeMeasurer { | |
private let pid = ProcessInfo().processIdentifier | |
private var currentTime = timeval(tv_sec: 0, tv_usec: 0) | |
private var bootTime = timeval() | |
private var size = MemoryLayout<kinfo_proc>.stride | |
private var mib: [Int32] | |
init() { | |
mib = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid] | |
} | |
func processLaunchTime() -> Double { | |
sysctl(&mib, u_int(mib.count), &bootTime, &size, nil, 0) | |
gettimeofday(¤tTime, nil) | |
return toSeconds(time: currentTime) - toSeconds(time: bootTime) | |
} | |
private func toSeconds(time: timeval) -> Double { | |
let microsecondsInSecond = 1000000.0 | |
return Double(time.tv_sec) + Double(time.tv_usec) / microsecondsInSecond | |
} | |
} |
I was able to figure out what was wrong, and it might help @RagulChandra too. sysctl takes a kinfo_proc, not a timeval. Using a timeval will still return the correct value, but causes memory corruption later on in your app's life cycle.
Here are the modifications that should be made to avoid memory corruption:
...
private var kp = kinfo_proc() // kp instead of bootTime
...
func processLaunchTime() -> Double {
sysctl(&mib, u_int(mib.count), &kp, &size, nil, 0)
gettimeofday(¤tTime, nil)
let bootTime = kp.kp_proc.p_un.__p_starttime // this is a timeval struct
return toSeconds(time: currentTime) - toSeconds(time: bootTime)
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm having an issue implementing this code. After the
sysctl
call on line 15 it corrupts the stack and upon returning it gives me the following error: "error: memory read failed for 0x0". I stepped through the code and that line is where it happens. Up until that point I can see the stacktrace just fine, but as soon as that line executes it's gone. Even though I get valid values back from callingtoSeconds:
it just crashes the app. Any help you might be able to give me would be greatly appreciated!