diff options
author | neal <neal> | 2008-02-13 15:00:48 +0000 |
---|---|---|
committer | neal <neal> | 2008-02-13 15:00:48 +0000 |
commit | 131af073d55b7e2d3409337610d0fb469a059bd1 (patch) | |
tree | ba6dbb80327c0836181bbfc1b155ca6f8013fc61 /viengoos/activity.c | |
parent | 5f0f3e50ed8c0c9e1164371180ffd92a9bb35b0a (diff) |
2008-02-13 Neal H. Walfield <neal@gnu.org>
* activity.h (activity_policy_update): New declaration.
* activity.c (children_list_insert_after): New function.
(children_list_detach): Likewise.
(activity_prepare): Use the above to insert ACTIVITY onto its
parent's children list. Keep the list is priority sorted order.
(activity_deprepare): Likewise, but to remove ACTIVITY from its
parent's children list.
(activity_policy_update): New function.
* server.c (server_loop): Use activity_policy_update to update an
activity's policy.
Diffstat (limited to 'viengoos/activity.c')
-rw-r--r-- | viengoos/activity.c | 121 |
1 files changed, 110 insertions, 11 deletions
diff --git a/viengoos/activity.c b/viengoos/activity.c index 3c2267c..8013af5 100644 --- a/viengoos/activity.c +++ b/viengoos/activity.c @@ -27,6 +27,50 @@ struct activity *root_activity; +/* Add ACTIVITY to ACTIVITY->PARENT's children list after AFTER. */ +static void +children_list_insert_after (struct activity *activity, struct activity *after) +{ + assert (activity->parent); + + if (! after) + /* Insert at head of list. */ + { + activity->sibling_next = activity->parent->children; + if (activity->parent->children) + activity->parent->children->sibling_prev = activity; + activity->parent->children = activity; + } + else + { + assert (activity->parent == after->parent); + assert (after->policy.sibling_rel.priority + >= activity->policy.sibling_rel.priority); + + activity->sibling_next = after->sibling_next; + activity->sibling_prev = after; + if (activity->sibling_next) + activity->sibling_next->sibling_prev = activity; + after->sibling_next = activity; + } +} + +/* Remove ACTIVITY from ACTIVITY->PARENT's children list. */ +static void +children_list_detach (struct activity *activity) +{ + if (activity->sibling_prev) + activity->sibling_prev->sibling_next = activity->sibling_next; + else + { + assert (activity->parent->children == activity); + activity->parent->children = activity->sibling_next; + } + + if (activity->sibling_next) + activity->sibling_next->sibling_prev = activity->sibling_prev; +} + void activity_create (struct activity *parent, struct activity *child) @@ -284,12 +328,26 @@ activity_prepare (struct activity *principal, struct activity *activity) assert (! activity->parent->children || ! activity->parent->children->sibling_prev); - activity->sibling_next = activity->parent->children; - if (activity->parent->children) - activity->parent->children->sibling_prev = activity; - activity->parent->children = activity; + if (! activity->parent->children + || (activity->policy.sibling_rel.priority + >= activity->parent->children->policy.sibling_rel.priority)) + children_list_insert_after (activity, NULL); + else + { + struct activity *last; + + for (last = activity->parent->children; + last->sibling_next + && (last->sibling_next->policy.sibling_rel.priority + > activity->policy.sibling_rel.priority); + last = last->sibling_next) + ; + + assert (last); + children_list_insert_after (activity, last); + } - /* We have no in-memory children. */ + /* ACTIVITY has no in-memory children. */ activity->children = NULL; } @@ -308,16 +366,57 @@ activity_deprepare (struct activity *principal, struct activity *victim) /* Unlink from parent's children list. */ assert (victim->parent); - if (victim->sibling_prev) - victim->sibling_prev->sibling_next = victim->sibling_next; + children_list_detach (victim); +} + +void +activity_policy_update (struct activity *activity, + struct activity_policy policy) +{ + int priority = policy.sibling_rel.priority; + + if (priority == activity->policy.sibling_rel.priority) + /* Same priority: noop. */ + ; + else if (priority > activity->policy.sibling_rel.priority) + /* Increased priority. Search backwards and find the first + activity that has a priority that is greater than or equal to + PRIORITY. Move ACTIVITY to just after that activity. */ + { + activity->policy.sibling_rel.priority = priority; + + struct activity *prev; + for (prev = activity->sibling_prev; + prev && prev->policy.sibling_rel.priority < priority; + prev = prev->sibling_prev) + ; + + if (prev != activity->sibling_prev) + { + children_list_detach (activity); + children_list_insert_after (activity, prev); + } + } else + /* Decreased priority. */ { - assert (victim->parent->children == victim); - victim->parent->children = victim->sibling_next; + activity->policy.sibling_rel.priority = priority; + + struct activity *next; + for (next = activity; + next->sibling_next + && next->sibling_next->policy.sibling_rel.priority > priority; + next = next->sibling_next) + ; + + if (next != activity) + { + children_list_detach (activity); + children_list_insert_after (activity, next); + } } - if (victim->sibling_next) - victim->sibling_next->sibling_prev = victim->sibling_prev; + activity->policy = policy; } static void |