stage4/generate_c/generate_c.cc
changeset 1080 54445dfc28ec
parent 1079 585445abc4a2
child 1083 fc23bca885f8
equal deleted inserted replaced
1079:585445abc4a2 1080:54445dfc28ec
   545 /***********************************************************************/
   545 /***********************************************************************/
   546 
   546 
   547 #define MILLISECOND 1000000
   547 #define MILLISECOND 1000000
   548 #define SECOND 1000 * MILLISECOND
   548 #define SECOND 1000 * MILLISECOND
   549 
   549 
       
   550 #define ULL_MAX std::numeric_limits<unsigned long long>::max()
       
   551 
   550 unsigned long long calculate_time(symbol_c *symbol) {
   552 unsigned long long calculate_time(symbol_c *symbol) {
   551   if (NULL == symbol) return 0;
   553   if (NULL == symbol) return 0;
   552   
   554   
   553   interval_c *interval = dynamic_cast<interval_c *>(symbol);
   555   interval_c *interval = dynamic_cast<interval_c *>(symbol);
   554   duration_c *duration = dynamic_cast<duration_c *>(symbol);
   556   duration_c *duration = dynamic_cast<duration_c *>(symbol);
   636       if (c == 0)
   638       if (c == 0)
   637         return b;
   639         return b;
   638       else
   640       else
   639         return euclide(b, c);
   641         return euclide(b, c);
   640     }
   642     }
   641     
   643 
   642     void update_ticktime(unsigned long long time) {
   644     bool update_ticktime(unsigned long long time) {
       
   645       bool overflow = false;
       
   646       
   643       if (common_ticktime == 0)
   647       if (common_ticktime == 0)
   644         common_ticktime = time;
   648         common_ticktime = time;
   645       else if (time > common_ticktime)
   649       else if (time > common_ticktime)
   646         common_ticktime = euclide(time, common_ticktime);
   650         common_ticktime = euclide(time, common_ticktime);
   647       else
   651       else
   648         common_ticktime = euclide(common_ticktime, time);
   652         common_ticktime = euclide(common_ticktime, time);
   649       if (least_common_ticktime == 0)
   653       if (least_common_ticktime == 0)
   650         least_common_ticktime = time;
   654         least_common_ticktime = time;
   651       else
   655       else {
       
   656         /* Test overflow on MUL by pre-condition: If (ULL_MAX / a) < b => overflow! */
       
   657         overflow = ((ULL_MAX / least_common_ticktime) < (time / common_ticktime));
   652         least_common_ticktime = least_common_ticktime * (time / common_ticktime);
   658         least_common_ticktime = least_common_ticktime * (time / common_ticktime);
   653     }
   659       }
   654 
   660       fprintf(stderr, "time=%llu  least_common_ticktime=%llu  common_ticktime=%llu\n", time, least_common_ticktime, common_ticktime );
       
   661       return !overflow;
       
   662     }
       
   663     
   655     unsigned long long get_common_ticktime(void) {
   664     unsigned long long get_common_ticktime(void) {
   656       return common_ticktime;
   665       return common_ticktime;
   657     }
   666     }
   658 
   667 
   659     unsigned long get_greatest_tick_count(void) {
   668     unsigned long get_greatest_tick_count(void) {
   665 
   674 
   666 /*  TASK task_name task_initialization */
   675 /*  TASK task_name task_initialization */
   667 //SYM_REF2(task_configuration_c, task_name, task_initialization)  
   676 //SYM_REF2(task_configuration_c, task_name, task_initialization)  
   668     void *visit(task_initialization_c *symbol) {
   677     void *visit(task_initialization_c *symbol) {
   669       if (symbol->interval_data_source != NULL) {
   678       if (symbol->interval_data_source != NULL) {
   670     	  unsigned long long time = calculate_time(symbol->interval_data_source);
   679         unsigned long long time = calculate_time(symbol->interval_data_source);
   671     	  if (time < 0)  ERROR;
   680         if (!update_ticktime(time))
   672     	  else           update_ticktime(time);
   681           /* time is being stored in ns resolution (MILLISECOND #define is set to 1000000)    */
       
   682           /* time is being stored in unsigned long long (ISO C99 guarantees at least 64 bits) */
       
   683           /* 2⁶64ns works out to around 584.5 years, assuming 365.25 days per year            */
       
   684           STAGE4_ERROR(symbol, symbol, "Internal overflow calculating least common multiple of task intervals (must be < 584 years).");
   673       }
   685       }
   674       return NULL;
   686       return NULL;
   675     }
   687     }
   676 };    
   688 };    
   677 
   689