Towards finishing exchange_registers()

- Added mutex_trylock()
- Implemented most of exchange_registers()
- thread_control() now needs a lock for operations that can modify thread context.
- thread_start() does not initialise scheduler flags, now done in thread_create.

TODO:
- Fork/clone'ed threads should retain their context in tcb, not syscall stack.
- exchange_registers() calls in userspace need cleaning up.
This commit is contained in:
Bahadir Balban
2008-09-13 18:07:00 +03:00
parent 0b3ab05a98
commit 4fb5277123
23 changed files with 460 additions and 98 deletions

View File

@@ -0,0 +1,21 @@
/*
* Generic to arch-specific interface for
* exchange_registers()
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <exregs.h>
void exregs_set_stack(struct exregs_data *s, unsigned long sp)
{
s->context.sp = sp;
s->valid_vect |= 1 << (offsetof(task_context_t, sp) >> 2);
}
void exregs_set_pc(struct exregs_data *s, unsigned long pc)
{
s->context.pc = pc;
s->valid_vect |= 1 << (offsetof(task_context_t, pc) >> 2);
}

View File

@@ -64,7 +64,7 @@ int do_fork(struct tcb *parent)
* Create a new L4 thread with parent's page tables
* kernel stack and kernel-side tcb copied
*/
if (IS_ERR(child = task_create(parent, &ids, THREAD_CREATE_COPYSPC,
if (IS_ERR(child = task_create(parent, &ids, THREAD_COPY_SPACE,
TCB_NO_SHARING))) {
l4_ipc_return((int)child);
return 0;
@@ -121,7 +121,6 @@ int sys_clone(l4id_t sender, void *child_stack, unsigned int flags)
struct task_ids ids;
struct vm_file *utcb_shm;
struct tcb *parent, *child;
unsigned long stack, stack_size;
BUG_ON(!(parent = find_task(sender)));
@@ -129,7 +128,7 @@ int sys_clone(l4id_t sender, void *child_stack, unsigned int flags)
ids.spid = parent->spid;
ids.tgid = parent->tgid;
if (IS_ERR(child = task_create(parent, &ids, THREAD_CREATE_SAMESPC,
if (IS_ERR(child = task_create(parent, &ids, THREAD_SAME_SPACE,
TCB_SHARED_VM | TCB_SHARED_FILES))) {
l4_ipc_return((int)child);
return 0;

View File

@@ -26,6 +26,7 @@
#include <task.h>
#include <shm.h>
#include <mmap.h>
#include <exregs.h>
struct tcb_head {
struct list_head list;
@@ -303,6 +304,7 @@ int task_setup_registers(struct tcb *task, unsigned int pc,
unsigned int sp, l4id_t pager)
{
int err;
struct exregs_data regs;
/* Set up task's registers to default. */
if (!sp)
@@ -313,7 +315,9 @@ int task_setup_registers(struct tcb *task, unsigned int pc,
pager = self_tid();
/* Set up the task's thread details, (pc, sp, pager etc.) */
if ((err = l4_exchange_registers(pc, sp, pager, task->tid) < 0)) {
exregs_set_stack(&regs, sp);
exregs_set_pc(&regs, pc);
if ((err = l4_exchange_registers(&regs, pager, task->tid) < 0)) {
printf("l4_exchange_registers failed with %d.\n", err);
return err;
}
@@ -367,7 +371,7 @@ int task_exec(struct vm_file *f, unsigned long task_region_start,
struct tcb *task;
int err;
if (IS_ERR(task = task_create(0, ids, THREAD_CREATE_NEWSPC,
if (IS_ERR(task = task_create(0, ids, THREAD_NEW_SPACE,
TCB_NO_SHARING)))
return (int)task;