| 1 | /* Copyright (C) 2012 Matthew Fluet. |
| 2 | * Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh |
| 3 | * Jagannathan, and Stephen Weeks. |
| 4 | * Copyright (C) 1997-2000 NEC Research Institute. |
| 5 | * |
| 6 | * MLton is released under a BSD-style license. |
| 7 | * See the file MLton-LICENSE for details. |
| 8 | */ |
| 9 | |
| 10 | void rusageZero (struct rusage *ru) { |
| 11 | memset (ru, 0, sizeof (*ru)); |
| 12 | } |
| 13 | |
| 14 | void rusagePlusMax (struct rusage *ru1, |
| 15 | struct rusage *ru2, |
| 16 | struct rusage *ru) { |
| 17 | const int million = 1000000; |
| 18 | time_t sec; |
| 19 | suseconds_t usec; |
| 20 | |
| 21 | sec = ru1->ru_utime.tv_sec + ru2->ru_utime.tv_sec; |
| 22 | usec = ru1->ru_utime.tv_usec + ru2->ru_utime.tv_usec; |
| 23 | sec += (usec / million); |
| 24 | usec %= million; |
| 25 | ru->ru_utime.tv_sec = sec; |
| 26 | ru->ru_utime.tv_usec = usec; |
| 27 | |
| 28 | sec = ru1->ru_stime.tv_sec + ru2->ru_stime.tv_sec; |
| 29 | usec = ru1->ru_stime.tv_usec + ru2->ru_stime.tv_usec; |
| 30 | sec += (usec / million); |
| 31 | usec %= million; |
| 32 | ru->ru_stime.tv_sec = sec; |
| 33 | ru->ru_stime.tv_usec = usec; |
| 34 | } |
| 35 | |
| 36 | void rusageMinusMax (struct rusage *ru1, |
| 37 | struct rusage *ru2, |
| 38 | struct rusage *ru) { |
| 39 | const int million = 1000000; |
| 40 | time_t sec; |
| 41 | suseconds_t usec; |
| 42 | |
| 43 | sec = (ru1->ru_utime.tv_sec - ru2->ru_utime.tv_sec) - 1; |
| 44 | usec = ru1->ru_utime.tv_usec + million - ru2->ru_utime.tv_usec; |
| 45 | sec += (usec / million); |
| 46 | usec %= million; |
| 47 | ru->ru_utime.tv_sec = sec; |
| 48 | ru->ru_utime.tv_usec = usec; |
| 49 | |
| 50 | sec = (ru1->ru_stime.tv_sec - ru2->ru_stime.tv_sec) - 1; |
| 51 | usec = ru1->ru_stime.tv_usec + million - ru2->ru_stime.tv_usec; |
| 52 | sec += (usec / million); |
| 53 | usec %= million; |
| 54 | ru->ru_stime.tv_sec = sec; |
| 55 | ru->ru_stime.tv_usec = usec; |
| 56 | } |
| 57 | |
| 58 | uintmax_t rusageTime (struct rusage *ru) { |
| 59 | uintmax_t result; |
| 60 | |
| 61 | result = 0; |
| 62 | result += 1000 * (uintmax_t)ru->ru_utime.tv_sec; |
| 63 | result += 1000 * (uintmax_t)ru->ru_stime.tv_sec; |
| 64 | result += (uintmax_t)ru->ru_utime.tv_usec / 1000; |
| 65 | result += (uintmax_t)ru->ru_stime.tv_usec / 1000; |
| 66 | return result; |
| 67 | } |
| 68 | |
| 69 | void startTiming (struct rusage *ru_start) { |
| 70 | getrusage (RUSAGE_SELF, ru_start); |
| 71 | } |
| 72 | |
| 73 | /* Accumulate and return time as number of milliseconds. */ |
| 74 | uintmax_t stopTiming (struct rusage *ru_start, struct rusage *ru_acc) { |
| 75 | struct rusage ru_finish, ru_total; |
| 76 | |
| 77 | getrusage (RUSAGE_SELF, &ru_finish); |
| 78 | rusageMinusMax (&ru_finish, ru_start, &ru_total); |
| 79 | rusagePlusMax (ru_acc, &ru_total, ru_acc); |
| 80 | return rusageTime (&ru_total); |
| 81 | } |