@@ -568,7 +568,8 @@ std::tuple<bool, unsigned> Program::checkOutputs(ValueMap& checks) const noexcep
568568 return std::tuple (outputs.empty (), total_tests);
569569}
570570
571- void Program::execute (bool verbose, bool debug, ValueFormat& format, bool single_invoc) noexcept (false ) {
571+ void Program::execute (bool verbose, ValueFormat& format, bool debug, bool single_invoc, unsigned timeout) noexcept (false
572+ ) {
572573 Instruction& entry_inst = insts[entry];
573574 DataView& global = data.getGlobal ();
574575
@@ -699,10 +700,45 @@ void Program::execute(bool verbose, bool debug, ValueFormat& format, bool single
699700 new_frame->setPC (pre_pc);
700701 }
701702
703+ class Timer {
704+ std::vector<uint8_t > tens;
705+
706+ public:
707+ Timer (unsigned power_of_ten) {
708+ // 0: off
709+ // 1: 10 -> |10|
710+ // 2: 100 -> |0|1|
711+ // 3: 1000 -> |0|10|
712+ // 4: 10000 -> |0|0|1|
713+ tens.resize (power_of_ten / 2 + 1 , 0 );
714+ tens.back () = power_of_ten % 2 == 0 ? 1 : 10 ;
715+ }
716+
717+ bool tick () {
718+ bool found = false ;
719+ unsigned index = 0 ;
720+ for (; index < tens.size (); ++index) {
721+ if (tens[index] > 0 ) {
722+ found = true ;
723+ tens[index]--;
724+ break ;
725+ }
726+ }
727+ if (!found)
728+ return true ;
729+ for (; index-- > 0 ;)
730+ tens[index] = 99 ;
731+ return false ;
732+ }
733+ } timer (timeout);
734+
702735 // Right now, do something like round robin scheduling. In the future, we will want to give other options
703736 // through the command line
704737 unsigned next_invoc = num_invocations - 1 ;
705738 while (!live_threads.empty ()) {
739+ if (timeout > 0 && timer.tick ())
740+ throw std::runtime_error (" Execution timed out!" );
741+
706742 if (active_threads.empty ()) {
707743 // All active threads have hit a barrier. Unblock all.
708744 for (unsigned live : live_threads)
0 commit comments