4

I'm trying to get uptime for iOS. I was using mach_absolute_time - but I found that it paused during sleep.

I found this snippet:

- (time_t)uptime
{
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);
    time_t now;
    time_t uptime = -1;

    (void)time(&now);

    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
    {
        uptime = now - boottime.tv_sec;
    }
    return uptime;
}

It does the trick. BUT, it's returning whole seconds. Any way to get milliseconds out of this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
objectiveccoder001
  • 2,981
  • 10
  • 48
  • 72
  • I am not sure but NSTimeInterval give you in ms `NSTimeInterval timePassed_ms = [date timeIntervalSinceNow] * -1000.0;` and check `NSDate* bootDate = [NSDate dateWithTimeIntervalSince1970: boottime.tv_sec + boottime.tv_usec / 1.e6];` – Anoop Vaidya Apr 14 '13 at 05:06
  • Getting weird values: 1330475899251.326172 2013-04-14 01:08:54.996 app[1486:c07] 1365915981675.174072 2013-04-14 01:08:54.997 app[1486:c07] 1330475899257.684082 2013-04-14 01:08:55.012 app[1486:c07] 1365915981691.614258 – objectiveccoder001 Apr 14 '13 at 05:09
  • that is not weired that in number of seconds elapsed since 1970.... :) – Anoop Vaidya Apr 14 '13 at 05:11
  • But the numbers are changing kinda random actually :P – objectiveccoder001 Apr 14 '13 at 05:12
  • how can time be same? time always change :) – Anoop Vaidya Apr 14 '13 at 05:13
  • Haha, yes, I know. BUT the numbers are repeating back and forth. – objectiveccoder001 Apr 14 '13 at 05:15
  • Like : 07] 1365916351.173829 2013-04-14 01:15:04.581 app[1539:c07] 1330476268.841522 2013-04-14 01:15:04.582 app[1539:c07] 1365916351.176842 2013-04-14 01:15:04.584 app[1539:c07] 1330476268.844556 2013-04-14 01:15:04.585 app[1539:c07] 1365916351.182255 – objectiveccoder001 Apr 14 '13 at 05:15

3 Answers3

3

If you want something pure Objective-C, try

NSTimeInterval uptime = [[NSProcessInfo processInfo] systemUptime];

(NSTimeInterval is a typedef for double, representing seconds.)

Wevah
  • 28,182
  • 7
  • 83
  • 72
3

The kernel does not (apparently) store a higher-resolution timestamp of its boot time.

KERN_BOOTTIME is implemented by the sysctl_boottime function in bsd/kern/kern_sysctl.c. It calls boottime_sec.

boottime_sec is implemented in bsd/kern/kern_time.c. It calls clock_get_boottime_nanotime, which has a promising name.

clock_get_boottime_nanotime is implemented in osfmk/kern/clock.c. It is hard-coded to always return 0 in its nanosecs argument.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
2

I know it's probably too late, but there you go:

+ (NSTimeInterval)uptime {
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);

    struct timeval now;
    struct timezone tz;
    gettimeofday(&now, &tz);

    double uptime = -1;

    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) {
        uptime = now.tv_sec - boottime.tv_sec;
        uptime += (double)(now.tv_usec - boottime.tv_usec) / 1000000.0;
    }
    return uptime;
}