diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-08-16 20:12:14 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-08-16 20:12:14 -0700 |
commit | 88e9989473226492f76cf5dc6b22eeb36fd97e49 (patch) | |
tree | e00ee460e3f5d302b12bf877cd0f08750ed50384 | |
parent | 5db2faebe215e588172bcfe1810416f4c7b909b1 (diff) | |
download | mu-88e9989473226492f76cf5dc6b22eeb36fd97e49.tar.gz |
2023 - give routines time limits
-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; +} |