merge
authorMario de Sousa <msousa@fe.up.pt>
Wed, 26 Dec 2018 12:02:13 +0000
changeset 1083 fc23bca885f8
parent 1082 903e2782e405 (current diff)
parent 1080 54445dfc28ec (diff)
child 1084 54f72ee52708
merge
stage4/generate_c/generate_c.cc
--- 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;
     }