diff options
author | neal <neal> | 2007-12-10 13:51:05 +0000 |
---|---|---|
committer | neal <neal> | 2007-12-10 13:51:05 +0000 |
commit | 2683573d4b629858937baa27512b2ccd190e81b6 (patch) | |
tree | 7dd4cdba361f65e3f31a635740181b16d6d3da54 /viengoos/activity.c | |
parent | b37568eb1c20381542d63986c81b742f9df5eeb3 (diff) |
viengoos/
2007-12-10 Neal H. Walfield <neal@gnu.org>
Properly account memory and folios.
* activity.h (struct activity): Remove field objects. New fields
parent_ptr, active, inactive_clean, inactive_dirty and dying.
(root_activity): New declaration.
(activity_create): Return void. Don't take priority, weight and
storage_quota arguments. Update callers.
(activity_for_each_ancestor): New macro.
(activity_charge): New function.
(activity_for_each_child): New macro.
(activity_dump): New declaration.
(activity_consistency_check_): Likewise.
(activity_consistency_check): New macro.
* activity.c (root_activity): Define.
(activity_create): Return void. Don't take priority, weight and
storage_quota arguments. Remove relevant functionality. Set
CHILD->PARENT_PTR appropriately. Be careful when bootstrapping.
(activity_destroy): Check that VICTIM->DYING is not set. If so,
panic. Otherwise, set it. When recursively destroying an
activity, call object_free, not activity_destroy, to clean up.
Abandon all own frames. Assert that VICTIM->FRAMES and
VICTIM_FOLIO_COUNT are 0. Set PARENT->CHILDREN to
VICTIM->SIBLING_NEXT if VICTIM is the head of the list.
(do_activity_dump): New function.
(activity_dump): New function.
(activity_consistency_check_): New function.
* object.h: Don't include "thread.h".
(struct object_desc): Remove field activity. Rename field alru to
activity_lru. Rename field GLRU to global_lru. New fields dirty,
age and activity.
(LINK_TEMPLATE): New macro. Use it.
(dirty): Remove declaration.
(clean): Likewise.
(global_active): New declaration.
(global_inactive_dirty): Likewise.
(global_inactive_clean): Likewise.
(disowned): Likewise.
(object_desc_disown_simple): New function.
(object_disown_simple): Likewise.
(object_desc_disown_): Likewise.
(object_disown_): Likewise.
(object_desc_disown): New macro.
(object_disown): Likewise.
(object_desc_claim_): New function.
(object_claim_): Likewise.
(object_desc_claim): New macro.
(object_claim): Likewise.
(folio_parent): Remove parameter principal. Update callers.
(object_free): Improve parentheses.
* object.c: Include "thread.h".
(global_active): Define.
(global_inactive_dirty): Likewise.
(global_inactive_clean): Likewise.
(disowned): Likewise.
(object_init): Add asserts.
(memory_object_setup): Rename from this...
(memory_object_alloc): ... to this. Take additional parameters,
the type, oid and version. Also set up the object's descriptor.
Update callers.
(memory_object_destroy): Add asserts. Remove object from the
various linked lists. If OBJECT is an activity, assert that there
are no frames allocated against it.
(object_find_soft): If OBJECT is not accounted or inactive, assign
to ACTIVITY.
(folio_reparent): Rename from this...
(folio_parent): ... to this. Remove the parameter PRINCIPAL. Use
ACTIVITY where PRINCIPAL was previous used. Add asserts.
Correctly add FOLIO to ACTIVITY's folio list.
(folio_alloc): Check if the activity's storage quota allows the
allocation of another folio. Account the allocation of the folio.
(folio_free): Add asserts. Correctly account the folio. Clear
FOLIO->NEXT and FOLIO->PREV. Disown FOLIO's frame.
(folio_object_alloc): Assign OBJECT to ACTIVITY. When creating an
activity, call activity_create.
* cap.h (cap_set): Take additional parameter, a struct activity *.
Pass it to cap copy.
* cap.c Include "thread.h".
(cap_set_object): Remove dead function.
(cap_to_object): Clear CAP->TYPE if object_find returns NULL.
(cap_shootdown): Asser that ACTIVITY is not NULL.
* viengoos.c (root_activity): Don't define here.
* t-as.c (root_activity): Remove static qualifier.
* t-link.c: New file.
* t-activity.c: New file.
* Makefile.am (TESTS): Add t-activity and t-link.
(t_activity_CPPFLAGS): New variable.
(t_activity_SOURCES): Likewise.
(t_activity_LDADD): Likewise.
(t_link_CPPFLAGS): Likewise.
(t_link_SOURCES): Likewise.
* rm.h (RM_as_dump): Define.
(rm_method_id_string): Remove case for RM_activity_create.
(as_dump): New method.
* server.c (server_loop): Add support for method as_dump. Remove
support for method activity_create.
hurd/
2007-12-10 Neal H. Walfield <neal@gnu.org>
* activity.h (RM_activity_create): Don't define.
(activity_create): Remove method.
ruth/
2007-12-10 Neal H. Walfield <neal@gnu.org>
* ruth.c (main): Don't call rm_activity_create.
Diffstat (limited to 'viengoos/activity.c')
-rw-r--r-- | viengoos/activity.c | 166 |
1 files changed, 132 insertions, 34 deletions
diff --git a/viengoos/activity.c b/viengoos/activity.c index a4b5ac0..187fc3f 100644 --- a/viengoos/activity.c +++ b/viengoos/activity.c @@ -25,18 +25,12 @@ #include "activity.h" #include "object.h" -error_t +struct activity *root_activity; + +void activity_create (struct activity *parent, - struct activity *child, - l4_word_t priority, l4_word_t weight, - l4_word_t storage_quota) + struct activity *child) { - struct object_desc *desc = object_to_object_desc ((struct object *) parent); - assert (desc->type == cap_activity_control); - - desc = object_to_object_desc ((struct object *) child); - assert (desc->type == cap_activity_control); - struct object *old_parent = cap_to_object (parent, &child->parent); if (old_parent) /* CHILD is live. Destroy it first. */ @@ -47,7 +41,17 @@ activity_create (struct activity *parent, activity_destroy (parent, child); } + if (! parent) + { + assert (! root_activity); + return; + } + + struct object_desc *child_desc; + child_desc = object_to_object_desc ((struct object *) child); + child->parent = object_to_cap ((struct object *) parent); + child->parent_ptr = parent; child->sibling_next = parent->children; child->sibling_prev.type = cap_void; @@ -56,6 +60,7 @@ activity_create (struct activity *parent, struct object *next = cap_to_object (parent, &child->sibling_next); if (next) { + struct object_desc *desc; desc = object_to_object_desc (next); assert (desc->type == cap_activity_control); @@ -67,27 +72,22 @@ activity_create (struct activity *parent, ((struct activity *) n)->sibling_prev = object_to_cap ((struct object *) child); } - - child->priority = priority; - child->weight = weight; - child->storage_quota = storage_quota; - - return 0; } void activity_destroy (struct activity *activity, struct activity *victim) { - struct object_desc *desc = object_to_object_desc ((struct object *) activity); - assert (desc->type == cap_activity_control); - - desc = object_to_object_desc ((struct object *) victim); - assert (desc->type == cap_activity_control); + assert (object_type ((struct object *) activity) == cap_activity_control); + assert (object_type ((struct object *) victim) == cap_activity_control); /* We should never destroy the root activity. */ - if (victim->parent.type == cap_void) + if (! victim->parent_ptr) panic ("Request to destroy root activity"); + if (victim->dying) + panic ("Recursive destroy!"); + victim->dying = 1; + /* XXX: Rewrite this to avoid recusion!!! */ /* Destroy all folios allocated to this activity. */ @@ -115,15 +115,46 @@ activity_destroy (struct activity *activity, struct activity *victim) struct object_desc *desc = object_to_object_desc (o); assert (desc->type == cap_activity_control); - activity_destroy (activity, (struct activity *) o); + object_free (activity, o); + } + + /* Disown all allocated memory objects. */ + struct object_desc *desc; + int count = 0; + while ((desc = victim->active)) + { + object_desc_disown_simple (desc); + count ++; + } + while ((desc = victim->inactive_clean)) + { + object_desc_disown_simple (desc); + count ++; } + while ((desc = victim->inactive_dirty)) + { + object_desc_disown_simple (desc); + count ++; + } + activity_charge (victim, -count); + + do_debug (1) + if (victim->frames != 0) + { + debug (0, "activity (%llx)->frame = %d", + object_to_object_desc ((struct object *) victim)->oid, + victim->frames); + activity_dump (root_activity); + + struct object_desc *desc; + for (desc = victim->active; desc; desc = desc->activity_lru.next) + debug (0, " %llx: %s", desc->oid, cap_type_string (desc->type)); + } + assert (victim->frames == 0); + assert (victim->folio_count == 0); /* Remove from parent's activity list. */ - struct object *parent_object = cap_to_object (activity, &victim->parent); - assert (parent_object); - struct object_desc *pdesc = object_to_object_desc (parent_object); - assert (pdesc->type == cap_activity_control); - struct activity *parent = (struct activity *) parent_object; + struct activity *parent = victim->parent_ptr; struct object *prev_object = cap_to_object (activity, &victim->sibling_prev); assert (! prev_object @@ -145,13 +176,80 @@ activity_destroy (struct activity *activity, struct activity *victim) assert (parent->children.oid == desc->oid); assert (parent->children.version == desc->version); + + parent->children = victim->sibling_next; } if (next) - { - next->sibling_prev = victim->sibling_prev; - if (! prev) - /* NEXT is new head. */ - parent->children = victim->sibling_next; - } + next->sibling_prev = victim->sibling_prev; +} + +static void +do_activity_dump (struct activity *activity, int indent) +{ + char indent_string[indent + 1]; + memset (indent_string, ' ', indent); + indent_string[indent] = 0; + + int active = 0; + struct object_desc *desc; + for (desc = activity->active; desc; desc = desc->activity_lru.next) + active ++; + + int dirty = 0; + for (desc = activity->inactive_dirty; desc; desc = desc->activity_lru.next) + dirty ++; + + int clean = 0; + for (desc = activity->inactive_clean; desc; desc = desc->activity_lru.next) + clean ++; + + printf ("%s %llx: %d frames (active: %d, dirty: %d, clean: %d)\n", + indent_string, + object_to_object_desc ((struct object *) activity)->oid, + activity->frames, active, dirty, clean); + + struct activity *child; + activity_for_each_child (activity, child, + ({ do_activity_dump (child, indent + 1); })); +} + +void +activity_dump (struct activity *activity) +{ + do_activity_dump (activity, 0); +} + + +void +activity_consistency_check_ (const char *func, int line, + struct activity *activity) +{ + /* The number of objects on the active and inactive lists plus the + objects owned by the descendents must equal activity->frames. */ + + int active = 0; + struct object_desc *d; + for (d = activity->active; d; d = d->activity_lru.next) + active ++; + + int dirty = 0; + for (d = activity->inactive_dirty; d; d = d->activity_lru.next) + dirty ++; + + int clean = 0; + for (d = activity->inactive_clean; d; d = d->activity_lru.next) + clean ++; + + int children = 0; + struct activity *child; + activity_for_each_child (activity, child, + ({ children += child->frames; })); + + if (active + dirty + clean + children != activity->frames) + debug (0, "at %s:%d: frames (%d) " + "!= active (%d) + dirty (%d) + clean (%d) + children (%d)", + func, line, + activity->frames, active, dirty, clean, children); + assert (active + dirty + clean + children == activity->frames); } |