--- a/stage4/generate_c/generate_c.cc Wed Dec 26 11:56:14 2018 +0000
+++ b/stage4/generate_c/generate_c.cc Wed Dec 26 12:02:13 2018 +0000
@@ -662,8 +662,10 @@
else
return euclide(b, c);
}
-
- void update_ticktime(unsigned long long time) {
+
+ bool update_ticktime(unsigned long long time) {
+ bool overflow = false;
+
if (common_ticktime == 0)
common_ticktime = time;
else if (time > common_ticktime)
@@ -672,10 +674,15 @@
common_ticktime = euclide(common_ticktime, time);
if (least_common_ticktime == 0)
least_common_ticktime = time;
- else
- least_common_ticktime = (least_common_ticktime * time) / common_ticktime;
- }
-
+ else {
+ /* Test overflow on MUL by pre-condition: If (ULL_MAX / a) < b => overflow! */
+ overflow = ((ULL_MAX / least_common_ticktime) < (time / common_ticktime));
+ least_common_ticktime = least_common_ticktime * (time / common_ticktime);
+ }
+ fprintf(stderr, "time=%llu least_common_ticktime=%llu common_ticktime=%llu\n", time, least_common_ticktime, common_ticktime );
+ return !overflow;
+ }
+
unsigned long long get_common_ticktime(void) {
return common_ticktime;
}
@@ -691,9 +698,12 @@
//SYM_REF2(task_configuration_c, task_name, task_initialization)
void *visit(task_initialization_c *symbol) {
if (symbol->interval_data_source != NULL) {
- unsigned long long time = calculate_time(symbol->interval_data_source);
- if (time < 0) ERROR;
- else update_ticktime(time);
+ unsigned long long time = calculate_time(symbol->interval_data_source);
+ if (!update_ticktime(time))
+ /* time is being stored in ns resolution (MILLISECOND #define is set to 1000000) */
+ /* time is being stored in unsigned long long (ISO C99 guarantees at least 64 bits) */
+ /* 2⁶64ns works out to around 584.5 years, assuming 365.25 days per year */
+ STAGE4_ERROR(symbol, symbol, "Internal overflow calculating least common multiple of task intervals (must be < 584 years).");
}
return NULL;
}