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 |