#include #include #include #include #include #include #include #include #include #include #include #include #include struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid) { spin_lock_ctx_t ctxpg; struct proc_resource* resource = NULL; spin_lock (&procgroup->lock, &ctxpg); rbtree_find (struct proc_resource, &procgroup->resource_tree, rid, resource, resource_tree_link, rid); spin_unlock (&procgroup->lock, &ctxpg); return resource; } struct proc_resource* proc_create_resource_mem (struct procgroup* procgroup, int rid, size_t pages, uintptr_t paddr, bool managed) { spin_lock_ctx_t ctxpg; struct proc_resource* resource; if (pages == 0) return NULL; resource = proc_find_resource (procgroup, rid); if (resource != NULL) return resource; resource = malloc (sizeof (*resource)); if (resource == NULL) return NULL; memset (resource, 0, sizeof (*resource)); resource->lock = SPIN_LOCK_INIT; resource->ops.cleanup = &proc_cleanup_resource_mem; resource->rid = rid; resource->type = PR_MEM; resource->u.mem.resource = resource; if (managed) { resource->u.mem.managed = true; } else { paddr = pmm_alloc (pages); if (paddr == PMM_ALLOC_ERR) { free (resource); return NULL; } resource->u.mem.managed = false; } resource->u.mem.paddr = paddr; resource->u.mem.pages = resource->u.mem.alive_pages = pages; resource->refs = 1; spin_lock (&procgroup->lock, &ctxpg); rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, resource_tree_link, rid); spin_unlock (&procgroup->lock, &ctxpg); return resource; } struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup, int rid) { spin_lock_ctx_t ctxpg; struct proc_resource* resource; resource = proc_find_resource (procgroup, rid); if (resource != NULL) return resource; resource = malloc (sizeof (*resource)); if (resource == NULL) return NULL; memset (resource, 0, sizeof (*resource)); resource->lock = SPIN_LOCK_INIT; resource->ops.cleanup = &proc_cleanup_resource_mutex; resource->u.mem.resource = resource; resource->rid = rid; resource->type = PR_MUTEX; resource->refs = 1; spin_lock (&procgroup->lock, &ctxpg); rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, resource_tree_link, rid); spin_unlock (&procgroup->lock, &ctxpg); return resource; } void proc_resource_unlink (struct proc_resource* resource) { if (atomic_fetch_sub (&resource->refs, 1) == 1) { resource->ops.cleanup (resource); free (resource); } }