summaryrefslogtreecommitdiff
path: root/viengoos/activity.c
diff options
context:
space:
mode:
authorneal <neal>2007-12-10 13:51:05 +0000
committerneal <neal>2007-12-10 13:51:05 +0000
commit2683573d4b629858937baa27512b2ccd190e81b6 (patch)
tree7dd4cdba361f65e3f31a635740181b16d6d3da54 /viengoos/activity.c
parentb37568eb1c20381542d63986c81b742f9df5eeb3 (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.c166
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);
}