+// ---------------------------------------------------------
+
+/**
+ * exact_long_multiply_smaller_10e5()
+ *
+ * Same as below but with operands smaller than 10000 which allows
+ * to perform all component multiplications without an overflow risk.
+ **/
+static inline struct timespec exact_long_multiply_smaller_10e5(long t, long k)
+{
+ /* Since operands are smaller than 10e5 we can use 1000 */
+ /* the base without risking to cause overflows in the */
+ /* operations. */
+ /********************************************************/
+ assert(t < 10000);
+ assert(k < 10000);
+
+ struct timespec result;
+
+ long base = 1000;
+
+ long t_high = t / base;
+ long t_low = t % base;
+ long k_high = k / base;
+ long k_low = k % base;
+
+ long thkh = t_high * k_high;
+ long thkl = t_high * k_low;
+ long tlkh = t_low * k_high;
+ long tlkl = t_low * k_low;
+
+ long thkl_high = thkl / base;
+ long tlkh_high = tlkh / base;
+ long thkl_low = thkl % base;
+ long tlkh_low = tlkh % base;
+
+ long c2 = thkh + thkl_high + tlkh_high; // Normalized at 10^6
+ long c1 = thkl_low + tlkh_low; // Normalized at 10^3
+ long c0 = tlkl;
+
+ result.tv_sec = c2/1000 + c1/1000000;
+ result.tv_nsec = (c2 % 1000) * 1000000 + (c1 % 1000000) * 1000 + c0;
+
+ result.tv_sec += (result.tv_nsec / 1000000000);
+ result.tv_nsec %= 1000000000;
+
+ return result;
+}
+
+
+// -------------------------------------------------------------
+
+
+
+/**
+ * exact_long_multiply()
+ *
+ * This function performs an exact long * long operations on operands
+ * lower than 1e9 without using more than 32bit (1e9) arithmetic.
+ *
+ * To achieve this we decompose the operands in high and low:
+ *
+ * num = (num/base) * base + (num % base)
+ * ^^^^^^^^ ^^^^^^^^^^^^
+ * high component low component
+ *
+ * t * k = (th*kh + th*kl/base + tl*kh/base )*base^2
+ * + (th*kl % base)*base + (tl*kh % base) * base + tl*kl
+ *
+ * The problem is that we cannot use an exact base because sqrt(1e9)
+ * is not a multiple of 1e9 (in fact it is not even integer).
+ *
+ * So we use as a base 100000 which means that the last term tl*kl may
+ * need another exact calculation with a lower base (100)
+ **/
+static inline struct timespec exact_long_multiply(long t, long k)
+{
+ struct timespec result;
+
+ long t_high;
+ long t_low;
+ long k_high;
+ long k_low;
+
+ long base = 100000; /* Power of 10 closest to sqrt(1e9) from
+ * above */
+
+ t_high = t / base;
+ t_low = t % base; // Between 0 99999
+ k_high = k / base;
+ k_low = k % base; // Between 0 99999
+
+ /* These numbers are always lower than 1e9 */
+ long thkh = t_high * k_high;
+ long thkl = t_high * k_low;
+ long tlkh = t_low * k_high;
+
+ long thkl_high = thkl / base;
+ long thkl_low = thkl % base;
+ long tlkh_high = tlkh / base;
+ long tlkh_low = tlkh % base;
+
+ /* We can calculate the base^2 term (note however that this is 10
+ * times the tv_sec component because it is multiplied by 10^10 */
+ long c2 = thkh + thkl_high + tlkh_high; // scaled to 10^10
+ long c1 = thkl_low + tlkh_low; // scaled to 10^5
+
+ struct timespec c0;
+
+ /* Now we can write the initial values of result */
+ result.tv_sec = c2*10 + c1/10000;
+ result.tv_nsec = (c1 % 10000) * 100000;
+
+ normalize_timespec(result);
+
+ /* To calculate c0 we must check if there is a risk of overflow */
+ /* Remember operands cannot be larger than 99999 and result */
+ /* larger than 1e9. */
+ /****************************************************************/
+ bool overflow_risk;
+ overflow_risk = false;
+
+ if (
+ ( (t_low > 31622) && (k_low >= 10000) ) ||
+ ( (k_low > 31622) && (t_low >= 10000) )
+ )
+ {
+ overflow_risk = true;
+ }
+
+ if (! overflow_risk)
+ {
+ c0.tv_sec = 0;
+ c0.tv_nsec = t_low * k_low;
+ normalize_timespec(c0);
+ }
+ else
+ {
+ c0 = exact_long_multiply_smaller_10e5(t_low, k_low);
+ }
+ add_timespec(result, result, c0);
+
+ return result;
+}
+
+// -------------------------------------------------------------
+
+
+static inline fosa_rel_time_t fosa_rel_time_times_integer(fosa_rel_time_t time, long multiplier)
+{
+ struct timespec result;
+ struct timespec intermediate;
+
+ result.tv_sec = time.tv_sec * multiplier; // No overflow check here
+ result.tv_nsec = 0;
+
+ intermediate = exact_long_multiply(time.tv_nsec, multiplier);
+
+ add_timespec(result, result, intermediate);
+
+ return result;
+}
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_divided_by_integer(fosa_rel_time_t time, long divider)
+{
+ struct timespec result;
+ long reminder;
+
+
+ result.tv_sec = time.tv_sec / divider;
+ result.tv_nsec = 0;
+
+ /* We iterate until the reminder is lower than 2 (to later fit in
+ * a 32 bit signed integer multiplied by 1e9 */
+
+ reminder = time.tv_sec % divider;
+
+
+ if (reminder == 0)
+ {
+ /* We are lucky no reminder so no need to transfer it to the
+ nsec scale.
+ */
+ result.tv_nsec = time.tv_nsec/divider;
+ return result;
+ }
+
+ long enhacer;
+ long back_enhacer;
+ long next_dividend;
+ int next_numeral; /* Between 0 and 9 */
+ enhacer = 1;
+ do
+ {
+ enhacer *= 10;
+ back_enhacer = 1000000000 / enhacer;
+ next_numeral = (time.tv_nsec / back_enhacer) % 10;
+
+ // Note: a possible overflow may happen here with large denominators
+ if (reminder > 200000000)
+ {
+ /* An overflow is going to be produced */
+ abort();
+ }
+ next_dividend = reminder * 10 + next_numeral;
+
+ result.tv_nsec += (next_dividend / divider) * back_enhacer;
+ reminder = next_dividend % divider;
+ } while (back_enhacer > 1);
+
+
+ return result;
+}
+
+// ---------------------------------------------------------
+