summaryrefslogtreecommitdiff
path: root/viengoos/activity.c
diff options
context:
space:
mode:
authorneal <neal>2007-11-28 20:34:32 +0000
committerneal <neal>2007-11-28 20:34:32 +0000
commit12d97bb06786ed9dececa979e4abb3aad8cc5ff4 (patch)
tree9232b1c74f54f70aa59c639f68f61c9a9de6b80f /viengoos/activity.c
parenta9b17e6236a493d7f5354a7ebc0723ded83bc2bd (diff)
hurd/
2007-11-28 Neal H. Walfield <neal@gnu.org> * Makefile.am (includehurd_HEADERS): Add activity.h. * headers.m4: Create link from ../include/hurd/activity.h to activity.h. * activity.h: New file. viengoos/ 2007-11-28 Neal H. Walfield <neal@gnu.org> * activity.h (activity_allocate): Rename from this... (activity_create): ... to this. Remove arguments caller, folio, indent, activity and control. Add argument child. Update users. * activity.c (activity_allocate): Rename from this... (activity_create): ... to this. Remove arguments caller, folio, indent, activity and control. Add argument child. If CHILD is live, destroy it first. Correctly add CHILD to PARENT's children list. * activity.h (activity_destroy): Remove argument cap. Update callers. * activity.c (activity_destroy): Remove argument cap. Correctly destroy child activities and allocated folios. Correctly unlink from parent. * server.c (CAP_): Remove argument writablep. Add argument require_writable. Fail if REQUIRE_WRITABLE is true, and the object is not writable. (OBJECT_): Likewise. (CAP): Remove argument writablep. Add argument require_writable. Update callers. (OBJECT): Likewise. (server_loop): Add support for the activity_create method. * object.c (folio_free): Also update FOLIO->FOLIO_VERSION. (folio_object_alloc): Check if the object is a cap_activity_control, not a cap_activity. (folio_reparent): Correctly link FOLIO to PARENT. * t-as.c (test): Don't create a cap_activity object but a cap_activity_control object. * viengoos.c (system_task_load): Likewise. * cap.c (cap_to_object): Use cap_types_compatible when asserting that the capability's type and the object's type are identical. * thread.c (thread_exregs): Use cap_types_compatible when checking whether the thread has a valid activity object. * rm.h: Include <hurd/activity.h>. (rm_method_id_string): Handle the RM_activity_create case. ruth/ 2007-11-28 Neal H. Walfield <neal@gnu.org> * ruth.c: Include <hurd/activity.h>. (main): Add test for activity_create.
Diffstat (limited to 'viengoos/activity.c')
-rw-r--r--viengoos/activity.c158
1 files changed, 90 insertions, 68 deletions
diff --git a/viengoos/activity.c b/viengoos/activity.c
index 0f4dfc9..a4b5ac0 100644
--- a/viengoos/activity.c
+++ b/viengoos/activity.c
@@ -26,110 +26,132 @@
#include "object.h"
error_t
-activity_allocate (struct activity *parent,
- struct thread *caller,
- addr_t faddr, l4_word_t index,
- addr_t aaddr, addr_t caddr,
- l4_word_t priority, l4_word_t weight,
- l4_word_t storage_quota)
+activity_create (struct activity *parent,
+ struct activity *child,
+ l4_word_t priority, l4_word_t weight,
+ l4_word_t storage_quota)
{
- if (! (0 <= index && index < FOLIO_OBJECTS))
- return EINVAL;
-
- struct cap folio_cap = object_lookup_rel (parent, &caller->aspace,
- faddr, cap_folio, NULL);
- if (folio_cap.type == cap_void)
- return ENOENT;
- struct object *folio = cap_to_object (parent, &folio_cap);
- if (! folio)
- return ENOENT;
-
- struct cap *acap = slot_lookup_rel (parent, &caller->aspace, aaddr,
- -1, NULL);
- if (! acap)
- return ENOENT;
- struct cap *ccap = slot_lookup_rel (parent, &caller->aspace, caddr,
- -1, NULL);
- if (! ccap)
- return ENOENT;
+ struct object_desc *desc = object_to_object_desc ((struct object *) parent);
+ assert (desc->type == cap_activity_control);
- struct object *o;
- folio_object_alloc (parent, (struct folio *) folio, index,
- cap_activity, &o);
- struct activity *activity = (struct activity *) o;
- *ccap = *acap = object_to_cap (o);
- ccap->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. */
+ {
+ struct object_desc *desc = object_to_object_desc (old_parent);
+ assert (desc->type == cap_activity_control);
+
+ activity_destroy (parent, child);
+ }
+
+ child->parent = object_to_cap ((struct object *) parent);
- activity->priority = priority;
- activity->weight = weight;
- activity->storage_quota = storage_quota;
+ child->sibling_next = parent->children;
+ child->sibling_prev.type = cap_void;
+ parent->children = object_to_cap ((struct object *) child);
+
+ struct object *next = cap_to_object (parent, &child->sibling_next);
+ if (next)
+ {
+ desc = object_to_object_desc (next);
+ assert (desc->type == cap_activity_control);
+
+ struct activity *n = (struct activity *) next;
+
+ struct object *prev = cap_to_object (parent, &n->sibling_prev);
+ assert (! prev);
+
+ ((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 cap *cap, struct activity *target)
+activity_destroy (struct activity *activity, struct activity *victim)
{
- /* XXX: If we implement storage reparenting, we need to be careful
- to avoid a recursive loop as an activity's storage may be stored
- in a folio allocated to itself. */
- assert (! cap || cap->type == cap_activity_control);
+ 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);
/* We should never destroy the root activity. */
- if (target->parent.type == cap_void)
+ if (victim->parent.type == cap_void)
panic ("Request to destroy root activity");
/* XXX: Rewrite this to avoid recusion!!! */
/* Destroy all folios allocated to this activity. */
- while (target->folios.type != cap_void)
+ struct object *o;
+ while ((o = cap_to_object (activity, &victim->folios)))
{
- struct object *f = cap_to_object (activity, &target->folios);
- /* If F was destroyed, it should have been removed from its
+ /* If O was destroyed, it should have been removed from its
respective activity's allocation list. */
- assert (f);
- folio_free (activity, (struct folio *) f);
+ assert (o);
+
+ struct object_desc *desc = object_to_object_desc (o);
+ assert (desc->type == cap_folio);
+
+ folio_free (activity, (struct folio *) o);
}
/* Activity's that are sub-activity's of ACTIVITY are not
necessarily allocated out of storage allocated to ACTIVITY. */
- while (target->children.type != cap_void)
+ while ((o = cap_to_object (activity, &victim->children)))
{
- struct object *a = cap_to_object (activity, &activity->children);
- /* If A was destroyed, it should have been removed from its
+ /* If O was destroyed, it should have been removed from its
respective activity's allocation list. */
- assert (a);
- activity_destroy (target, NULL, (struct activity *) a);
- }
+ assert (o);
- /* Remove from parent's activity list. */
- struct activity *prev = NULL;
- if (target->sibling_prev.type != cap_void)
- prev = (struct activity *) cap_to_object (activity, &target->sibling_prev);
+ struct object_desc *desc = object_to_object_desc (o);
+ assert (desc->type == cap_activity_control);
- struct activity *next = NULL;
- if (target->sibling_next.type != cap_void)
- next = (struct activity *) cap_to_object (activity, &target->sibling_next);
+ activity_destroy (activity, (struct activity *) o);
+ }
- struct activity *p
- = (struct activity *) cap_to_object (activity, &target->parent);
- assert (p);
- struct object_desc *pdesc = object_to_object_desc ((struct object *) p);
+ /* 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 object *prev_object = cap_to_object (activity, &victim->sibling_prev);
+ assert (! prev_object
+ || object_to_object_desc (prev_object)->type == cap_activity_control);
+ struct activity *prev = (struct activity *) prev_object;
+
+ struct object *next_object = cap_to_object (activity, &victim->sibling_next);
+ assert (! next_object
+ || object_to_object_desc (next_object)->type == cap_activity_control);
+ struct activity *next = (struct activity *) next_object;
if (prev)
- prev->sibling_next = target->sibling_next;
+ prev->sibling_next = victim->sibling_next;
else
+ /* VICTIM better be the head of PARENT's child list. */
{
- assert (p->children.oid == pdesc->oid);
- assert (p->children.version == pdesc->version);
+ struct object_desc *desc
+ = object_to_object_desc ((struct object *) victim);
+
+ assert (parent->children.oid == desc->oid);
+ assert (parent->children.version == desc->version);
}
if (next)
{
- next->sibling_prev = target->sibling_prev;
+ next->sibling_prev = victim->sibling_prev;
if (! prev)
/* NEXT is new head. */
- p->children = activity->sibling_next;
+ parent->children = victim->sibling_next;
}
}