Added utcb create/destroy and better reorganized calls to them.

This commit is contained in:
Bahadir Balban
2009-05-01 17:06:24 +03:00
parent 8ca0ca9cfb
commit 260527c0a3
5 changed files with 101 additions and 17 deletions

View File

@@ -14,6 +14,7 @@ struct id_pool *id_pool_new_init(int mapsize);
int id_new(struct id_pool *pool);
int id_del(struct id_pool *pool, int id);
int id_get(struct id_pool *pool, int id);
int id_is_empty(struct id_pool *pool);
int ids_new_contiguous(struct id_pool *pool, int numids);
int ids_del_contiguous(struct id_pool *pool, int first, int numids);

View File

@@ -8,6 +8,7 @@
#include <file.h>
#include <exit.h>
#include <test.h>
#include <utcb.h>
#include <vm_area.h>
#include <syscalls.h>
#include <l4lib/arch/syslib.h>
@@ -92,10 +93,6 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig)
/* Copy shared page */
new->shared_page = orig->shared_page;
/* Copy utcb descriptors and unique utcb */
new->utcb_head = orig->utcb_head;
new->utcb_address = orig->utcb_address;
/* Copy parent relationship */
BUG_ON(new->parent);
new->parent = orig->parent;
@@ -104,6 +101,9 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig)
/* Flush all IO on task's files and close fds */
task_close_files(orig);
/* Destroy task's utcb slot */
task_destroy_utcb(orig);
/* Vfs still knows the thread */
/* Keep the shared page on vfs */
@@ -132,6 +132,9 @@ void do_exit(struct tcb *task, int status)
/* Flush all IO on task's files and close fds */
task_close_files(task);
/* Destroy task's utcb slot */
task_destroy_utcb(task);
/* Tell vfs that task is exiting */
vfs_notify_exit(task, status);

View File

@@ -78,3 +78,11 @@ int id_get(struct id_pool *pool, int id)
return id;
}
int id_is_empty(struct id_pool *pool)
{
for (int i = 0; i < pool->nwords; i++)
if (pool->bitmap[i])
return 0;
return 1;
}

View File

@@ -7,29 +7,32 @@
#include <l4/config.h>
#include <l4/types.h>
#include <l4/lib/list.h>
#include <l4/lib/math.h>
#include <l4/api/thread.h>
#include <l4/api/kip.h>
#include <l4/api/errno.h>
#include INC_GLUE(memory.h)
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/arch/utcb.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/exregs.h>
#include <l4/lib/math.h>
#include <lib/addr.h>
#include <lib/malloc.h>
#include <init.h>
#include <string.h>
#include <vm_area.h>
#include <memory.h>
#include <globals.h>
#include <file.h>
#include <task.h>
#include <exec.h>
#include <shm.h>
#include <mmap.h>
#include <boot.h>
#include <globals.h>
#include <test.h>
#include <utcb.h>
@@ -150,6 +153,17 @@ int task_free_resources(struct tcb *task)
kfree(task->vm_area_head);
}
/*
* Threads may share utcb chain
*/
if (!(--task->utcb_head->tcb_refs)) {
/* UTCBs must have been deleted explicitly */
BUG_ON(!list_empty(&task->utcb_head->list));
/* Free the head */
kfree(task->utcb_head);
}
return 0;
}
@@ -269,9 +283,6 @@ int copy_tcb(struct tcb *to, struct tcb *from, unsigned int flags)
*/
}
/* Set up a new utcb for new thread */
task_setup_utcb(to);
/* Copy all file descriptors */
if (flags & TCB_SHARED_FILES) {
to->files = from->files;
@@ -336,6 +347,10 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids,
if (parent) {
copy_tcb(task, parent, share_flags);
/* Set up a new utcb for new thread */
task_setup_utcb(task);
/* Set up parent-child relationship */
if ((share_flags & TCB_SHARED_PARENT) ||
(share_flags & TCB_SHARED_TGROUP)) {
@@ -557,10 +572,12 @@ int task_mmap_segments(struct tcb *task, struct vm_file *file, struct exec_file_
return err;
}
/* Get a new utcb slot for new task */
task_setup_utcb(task);
/*
* Task already has recycled task's shared page. It will attach to it
* when it starts in userspace. Task also already utilizes recycled
* task's utcb.
* Recycled task's shared page shm still exists. Current task will
* attach to it when it starts in userspace.
*/
//if (IS_ERR(shm = shm_new((key_t)task->utcb, __pfn(DEFAULT_UTCB_SIZE))))
// return (int)shm;

View File

@@ -42,7 +42,7 @@ int utcb_delete_address(void *utcb_address, int npages)
}
/* Return an empty utcb slot in this descriptor */
unsigned long utcb_slot(struct utcb_desc *desc)
unsigned long utcb_new_slot(struct utcb_desc *desc)
{
int slot;
@@ -52,6 +52,13 @@ unsigned long utcb_slot(struct utcb_desc *desc)
return desc->utcb_base + (unsigned long)slot * UTCB_SIZE;
}
int utcb_delete_slot(struct utcb_desc *desc, unsigned long address)
{
BUG_ON(id_del(desc->slots, (address - desc->utcb_base)
/ UTCB_SIZE) < 0);
return 0;
}
unsigned long task_new_utcb_desc(struct tcb *task)
{
struct utcb_desc *d;
@@ -69,13 +76,31 @@ unsigned long task_new_utcb_desc(struct tcb *task)
d->slots = id_pool_new_init(PAGE_SIZE / UTCB_SIZE);
/* Obtain a new and unique utcb base */
/* FIXME: Use variable size than a page */
d->utcb_base = (unsigned long)utcb_new_address(1);
/* Add descriptor to tcb's chain */
list_add(&d->list, &task->utcb_head->list);
/* Obtain and return first slot */
return d->utcb_base + UTCB_SIZE * id_new(d->slots);
return utcb_new_slot(d);
}
int task_delete_utcb_desc(struct tcb *task, struct utcb_desc *d)
{
/* Unlink desc from its list */
list_del_init(&d->list);
/* Unmap the descriptor region */
do_munmap(task, d->utcb_base, 1);
/* Return descriptor address */
utcb_delete_address((void *)d->utcb_base, 1);
/* Free the descriptor */
kfree(d);
return 0;
}
/*
@@ -102,7 +127,7 @@ int task_setup_utcb(struct tcb *task)
/* Search for an empty utcb slot already allocated to this space */
list_for_each_entry(udesc, &task->utcb_head->list, list)
if ((slot = utcb_slot(udesc)))
if ((slot = utcb_new_slot(udesc)))
goto out;
/* Allocate a new utcb memory region and return its base */
@@ -118,12 +143,42 @@ out:
printf("UTCB: mmapping failed with %d\n", err);
return (int)err;
}
} else
printf("UTCB at 0x%x already mapped.\n", slot);
}
/* Assign task's utcb address */
task->utcb_address = slot;
printf("UTCB at 0x%x.\n", slot);
return 0;
}
/*
* Deletes a utcb slot by first deleting the slot entry, the descriptor
* address if emptied, the mapping of the descriptor, and the descriptor itself
*/
int task_destroy_utcb(struct tcb *task)
{
struct utcb_desc *udesc;
printf("UTCB: Destroying 0x%x\n", task->utcb_address);
/* Find the utcb descriptor slot first */
list_for_each_entry(udesc, &task->utcb_head->list, list) {
/* FIXME: Use variable alignment than a page */
/* Detect matching slot */
if (page_align(task->utcb_address) == udesc->utcb_base) {
/* Delete slot from the descriptor */
utcb_delete_slot(udesc, task->utcb_address);
/* Is the desc completely empty now? */
if (id_is_empty(udesc->slots))
/* Delete the descriptor */
task_delete_utcb_desc(task, udesc);
return 0; /* Finished */
}
}
BUG();
}