diff options
-rw-r--r-- | 038scheduler.cc | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/038scheduler.cc b/038scheduler.cc index 613491b5..dc4d56f1 100644 --- a/038scheduler.cc +++ b/038scheduler.cc @@ -375,3 +375,66 @@ case _DUMP_ROUTINES: { } break; } + +//: support for stopping routines after some number of cycles + +:(scenario routine_discontinues_past_limit) +% Scheduling_interval = 2; +recipe f1 [ + 1:number/child-id <- start-running f2:recipe + limit-time 1:number/child-id, 1 +] +recipe f2 [ +{ + loop # run forever +} +] +# f2 terminates ++schedule: discontinuing routine 2 + +:(before "End routine States") +DISCONTINUED, +:(before "End Scheduler State Transitions") +if (Current_routine->limit >= 0) { + if (Current_routine->limit <= Scheduling_interval) { + trace("schedule") << "discontinuing routine " << Current_routine->id << end(); + Current_routine->state = DISCONTINUED; + Current_routine->limit = 0; + } + else { + Current_routine->limit -= Scheduling_interval; + } +} + +:(before "End routine Fields") +long long int limit; +:(before "End routine Constructor") +limit = -1; /* no limit */ + +:(before "End Primitive Recipe Declarations") +LIMIT_TIME, +:(before "End Primitive Recipe Numbers") +Recipe_ordinal["limit-time"] = LIMIT_TIME; +:(before "End Primitive Recipe Implementations") +case LIMIT_TIME: { + if (SIZE(ingredients) != 2) { + raise << current_recipe_name() << ": 'limit-time' requires exactly two ingredient, but got " << current_instruction().to_string() << '\n' << end(); + break; + } + if (!scalar(ingredients.at(0))) { + raise << current_recipe_name() << ": first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); + break; + } + if (!scalar(ingredients.at(1))) { + raise << current_recipe_name() << ": second ingredient of 'limit-time' should be a number (of instructions to run for), but got " << current_instruction().ingredients.at(1).original_string << '\n' << end(); + break; + } + long long int id = ingredients.at(0).at(0); + for (long long int i = 0; i < SIZE(Routines); ++i) { + if (Routines.at(i)->id == id) { + Routines.at(i)->limit = ingredients.at(1).at(0); + break; + } + } + break; +} |