| 37 | } |
| 38 | |
| 39 | struct timerel time_divide(struct timerel t, unsigned long div) |
| 40 | { |
| 41 | struct timerel res; |
| 42 | uint64_t rem, ns; |
| 43 | |
| 44 | /* Dividing seconds is simple. */ |
| 45 | res.ts.tv_sec = TIMEREL_CHECK(t).ts.tv_sec / div; |
| 46 | rem = t.ts.tv_sec % div; |
| 47 | |
| 48 | /* If we can't fit remainder * 1,000,000,000 in 64 bits? */ |
| 49 | #if 0 /* ilog is great, but we use fp for multiply anyway. */ |
| 50 | bits = ilog64(rem); |
| 51 | if (bits + 30 >= 64) { |
| 52 | /* Reduce accuracy slightly */ |
| 53 | rem >>= (bits - (64 - 30)); |
| 54 | div >>= (bits - (64 - 30)); |
| 55 | } |
| 56 | #endif |
| 57 | if (rem & ~(((uint64_t)1 << 30) - 1)) { |
| 58 | /* FIXME: fp is cheating! */ |
| 59 | double nsec = rem * 1000000000.0 + t.ts.tv_nsec; |
| 60 | res.ts.tv_nsec = nsec / div; |
| 61 | } else { |
| 62 | ns = rem * 1000000000 + t.ts.tv_nsec; |
| 63 | res.ts.tv_nsec = ns / div; |
| 64 | } |
| 65 | return TIMEREL_CHECK(res); |
| 66 | } |
| 67 | |
| 68 | struct timerel time_multiply(struct timerel t, unsigned long mult) |
| 69 | { |