mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Added utcb create/destroy and better reorganized calls to them.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user