Lots of cosmetic changes to the thread library.

This commit is contained in:
Bora Sahin
2009-11-05 22:09:37 +02:00
parent 1256f1a13a
commit 20f2b2bfdb
3 changed files with 54 additions and 69 deletions

View File

@@ -6,22 +6,12 @@
#ifndef __LIB_THREAD_H__ #ifndef __LIB_THREAD_H__
#define __LIB_THREAD_H__ #define __LIB_THREAD_H__
#define START_ADDR(addr) ((unsigned long)(addr)) int set_stack_params(unsigned long stack_top,
#define END_ADDR(addr) ((unsigned long)((addr) + (sizeof(addr)))) unsigned long stack_bottom,
#define STACK_TOP_ADDR(stack) (START_ADDR(stack))
#define STACK_BOTTOM_ADDR(stack) (END_ADDR(stack))
#define UTCB_START_ADDR(utcb) (START_ADDR(utcb))
#define UTCB_END_ADDR(utcb) (END_ADDR(utcb))
int set_stack_params(unsigned long stack_top_addr,
unsigned long stack_bottom_addr,
unsigned long stack_size); unsigned long stack_size);
int set_utcb_params(unsigned long utcb_start_addr, int set_utcb_params(unsigned long utcb_start, unsigned long utcb_end);
unsigned long utcb_end_addr);
int thread_create(struct task_ids *ids, unsigned int flags, int l4thread_create(struct task_ids *ids, unsigned int flags,
int (*func)(void *), void *arg); int (*func)(void *), void *arg);
#endif /* __LIB_THREAD_H__ */ #endif /* __LIB_THREAD_H__ */

View File

@@ -11,7 +11,6 @@
#include <utcb.h> #include <utcb.h>
/* Symbolic constants and macros */ /* Symbolic constants and macros */
#define STACK_PTR(addr) align((addr - 1), 8)
#define IS_STACK_SETUP() (lib_stack_size) #define IS_STACK_SETUP() (lib_stack_size)
/* Extern declarations */ /* Extern declarations */
@@ -23,19 +22,19 @@ static unsigned long lib_stack_bot_addr;
static unsigned long lib_stack_size; static unsigned long lib_stack_size;
/* Function definitions */ /* Function definitions */
int set_stack_params(unsigned long stack_top_addr, int set_stack_params(unsigned long stack_top,
unsigned long stack_bottom_addr, unsigned long stack_bottom,
unsigned long stack_size) unsigned long stack_size)
{ {
/* Ensure that arguments are valid. */ /* Ensure that arguments are valid. */
if (IS_STACK_SETUP()) { if (IS_STACK_SETUP()) {
printf("libl4thread: You have already called: %s. Simply, " printf("libl4thread: You have already called: %s.\n",
"this will have no effect!\n", __FUNCTION__); __FUNCTION__);
return -EPERM; return -EPERM;
} }
if (!stack_top_addr || !stack_bottom_addr) { if (!stack_top || !stack_bottom) {
printf("libl4thread: stack address range cannot contain " printf("libl4thread: Stack address range cannot contain "
"0x00000000 as a start and/or end address(es)!\n"); "0x0 as a start and/or end address(es).\n");
return -EINVAL; return -EINVAL;
} }
// FIXME: Aligning should be taken into account. // FIXME: Aligning should be taken into account.
@@ -43,32 +42,32 @@ int set_stack_params(unsigned long stack_top_addr,
* Stack grows downward so the top of the stack will have * Stack grows downward so the top of the stack will have
* the lowest numbered address. * the lowest numbered address.
*/ */
if (stack_top_addr >= stack_bottom_addr) { if (stack_top >= stack_bottom) {
printf("libl4thread: Stack bottom address must be bigger " printf("libl4thread: Stack bottom address must be bigger "
"than stack top address!\n"); "than stack top address.\n");
return -EINVAL; return -EINVAL;
} }
if (!stack_size) { if (!stack_size) {
printf("libl4thread: Stack size cannot be zero!\n"); printf("libl4thread: Stack size cannot be zero.\n");
return -EINVAL; return -EINVAL;
} }
/* stack_size at least must be equal to the difference. */ /* stack_size at least must be equal to the difference. */
if ((stack_bottom_addr - stack_top_addr) < stack_size) { if ((stack_bottom - stack_top) < stack_size) {
printf("libl4thread: the given range size is lesser than " printf("libl4thread: The given range size is lesser than "
"the stack size(0x%x)!\n", stack_size); "the stack size(0x%x).\n", stack_size);
return -EINVAL; return -EINVAL;
} }
/* Arguments passed the validity tests. */ /* Arguments passed the validity tests. */
/* Initialize internal variables */ /* Initialize internal variables */
lib_stack_bot_addr = stack_bottom_addr; lib_stack_bot_addr = stack_bottom;
lib_stack_top_addr = stack_top_addr; lib_stack_top_addr = stack_top;
lib_stack_size = stack_size; lib_stack_size = stack_size;
return 0; return 0;
} }
int thread_create(struct task_ids *ids, unsigned int flags, int l4thread_create(struct task_ids *ids, unsigned int flags,
int (*func)(void *), void *arg) int (*func)(void *), void *arg)
{ {
struct exregs_data exregs; struct exregs_data exregs;
@@ -77,30 +76,27 @@ int thread_create(struct task_ids *ids, unsigned int flags,
/* A few controls before granting access to thread creation */ /* A few controls before granting access to thread creation */
if (!IS_STACK_SETUP() || !IS_UTCB_SETUP()) { if (!IS_STACK_SETUP() || !IS_UTCB_SETUP()) {
printf("libl4thread: Stack and/or utcb have not been set up. " printf("libl4thread: Stack and/or utcb have not been "
"Before calling thread_create, set_stack_params " "set up.\n");
"and/or set_utcb_params have to be called with valid "
"arguments!\n");
return -EPERM; return -EPERM;
} }
/* Is there enough stack space for the new thread? */ /* Is there enough stack space for the new thread? */
if (lib_stack_top_addr >= lib_stack_bot_addr) { if (lib_stack_top_addr >= lib_stack_bot_addr) {
printf("libl4thread: no stack space left!\n"); printf("libl4thread: No stack space left.\n");
return -ENOMEM; return -ENOMEM;
} }
if (!(TC_SHARE_SPACE & flags)) { if (!(TC_SHARE_SPACE & flags)) {
printf("libl4thread: SAME address space is supported, which " printf("libl4thread: Only allows shared space thread "
"means the only way to create a thread is with " "creation.\n");
"TC_SHARE_SPACE flag. Other means of creating a "
"thread have not been supported yet!\n");
return -EINVAL; return -EINVAL;
} }
/* Get a utcb addr for this thread */ /* Get a utcb addr for this thread */
if (!(utcb_addr = get_utcb_addr())) { if (!(utcb_addr = get_utcb_addr())) {
printf("libl4thread: No utcb address left!\n"); printf("libl4thread: No utcb address left.\n");
return -ENOMEM; return -ENOMEM;
} }
@@ -110,27 +106,27 @@ int thread_create(struct task_ids *ids, unsigned int flags,
/* Create thread */ /* Create thread */
if ((err = l4_thread_control(THREAD_CREATE | flags, ids)) < 0) { if ((err = l4_thread_control(THREAD_CREATE | flags, ids)) < 0) {
printf("libl4thread: l4_thread_control(THREAD_CREATE) " printf("libl4thread: l4_thread_control(THREAD_CREATE) "
"failed with (%d)!\n", err); "failed with (%d).\n", err);
return err; return err;
} }
/* Setup new thread pc, sp, utcb */ /* Setup new thread pc, sp, utcb */
memset(&exregs, 0, sizeof(exregs)); memset(&exregs, 0, sizeof(exregs));
exregs_set_stack(&exregs, STACK_PTR(lib_stack_bot_addr)); exregs_set_stack(&exregs, align((lib_stack_bot_addr - 1), 8));
exregs_set_pc(&exregs, (unsigned long)setup_new_thread); exregs_set_pc(&exregs, (unsigned long)setup_new_thread);
exregs_set_utcb(&exregs, (unsigned long)utcb_addr); exregs_set_utcb(&exregs, (unsigned long)utcb_addr);
if ((err = l4_exchange_registers(&exregs, ids->tid)) < 0) { if ((err = l4_exchange_registers(&exregs, ids->tid)) < 0) {
printf("libl4thread: l4_exchange_registers failed with " printf("libl4thread: l4_exchange_registers failed with "
"(%d)!\n", err); "(%d).\n", err);
return err; return err;
} }
/* First word of new stack is arg */ /* First word of new stack is arg */
((unsigned long *)STACK_PTR(lib_stack_bot_addr))[0] = ((unsigned long *)align((lib_stack_bot_addr - 1), 8))[0] =
(unsigned long)arg; (unsigned long)arg;
/* Second word of new stack is function address */ /* Second word of new stack is function address */
((unsigned long *)STACK_PTR(lib_stack_bot_addr))[-1] = ((unsigned long *)align((lib_stack_bot_addr - 1), 8))[-1] =
(unsigned long)func; (unsigned long)func;
/* Update the stack address */ /* Update the stack address */
lib_stack_bot_addr -= lib_stack_size; lib_stack_bot_addr -= lib_stack_size;
@@ -138,7 +134,7 @@ int thread_create(struct task_ids *ids, unsigned int flags,
/* Start the new thread */ /* Start the new thread */
if ((err = l4_thread_control(THREAD_RUN, ids)) < 0) { if ((err = l4_thread_control(THREAD_RUN, ids)) < 0) {
printf("libl4thread: l4_thread_control(THREAD_RUN) " printf("libl4thread: l4_thread_control(THREAD_RUN) "
"failed with (%d)!\n", err); "failed with (%d).\n", err);
return err; return err;
} }

View File

@@ -12,7 +12,7 @@
#include <utcb.h> #include <utcb.h>
/* Static variable definitions */ /* Static variable definitions */
static unsigned long utcb_end_max_addr; static unsigned long lib_utcb_end_addr;
/* Function definitions */ /* Function definitions */
unsigned long get_utcb_addr(void) unsigned long get_utcb_addr(void)
@@ -24,7 +24,7 @@ unsigned long get_utcb_addr(void)
utcb_addr = utcb_new_slot(udesc_ptr); utcb_addr = utcb_new_slot(udesc_ptr);
} }
if (utcb_addr >= utcb_end_max_addr) if (utcb_addr >= lib_utcb_end_addr)
return 0; return 0;
return utcb_addr; return utcb_addr;
@@ -47,57 +47,56 @@ static int set_utcb_addr(void)
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0) { if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0) {
printf("libl4thread: l4_exchange_registers failed with " printf("libl4thread: l4_exchange_registers failed with "
"(%d)!\n", err); "(%d).\n", err);
return err; return err;
} }
return 0; return 0;
} }
int set_utcb_params(unsigned long utcb_start_addr, int set_utcb_params(unsigned long utcb_start, unsigned long utcb_end)
unsigned long utcb_end_addr)
{ {
int err; int err;
/* Ensure that arguments are valid. */ /* Ensure that arguments are valid. */
if (IS_UTCB_SETUP()) { if (IS_UTCB_SETUP()) {
printf("libl4thread: You have already called: %s. Simply, " printf("libl4thread: You have already called: %s.\n",
"this will have no effect!\n", __FUNCTION__); __FUNCTION__);
return -EPERM; return -EPERM;
} }
if (!utcb_start_addr || !utcb_end_addr) { if (!utcb_start || !utcb_end) {
printf("libl4thread: utcb address range cannot contain " printf("libl4thread: Utcb address range cannot contain "
"0x00000000 as a start and/or end address(es)!\n"); "0x0 as a start and/or end address(es).\n");
return -EINVAL; return -EINVAL;
} }
/* Check if the start address is aligned on UTCB_SIZE. */ /* Check if the start address is aligned on UTCB_SIZE. */
if (utcb_start_addr & !UTCB_SIZE) { if (utcb_start & !UTCB_SIZE) {
printf("libl4thread: utcb start address must be aligned " printf("libl4thread: Utcb start address must be aligned "
"on UTCB_SIZE(0x%x)\n", UTCB_SIZE); "on UTCB_SIZE(0x%x).\n", UTCB_SIZE);
return -EINVAL; return -EINVAL;
} }
/* The range must be a valid one. */ /* The range must be a valid one. */
if (utcb_start_addr >= utcb_end_addr) { if (utcb_start >= utcb_end) {
printf("libl4thread: utcb end address must be bigger " printf("libl4thread: Utcb end address must be bigger "
"than utcb start address!\n"); "than utcb start address.\n");
return -EINVAL; return -EINVAL;
} }
/* /*
* This check guarantees two things: * This check guarantees two things:
* 1. The range must be multiple of UTCB_SIZE, at least one item. * 1. The range must be multiple of UTCB_SIZE, at least one item.
* 2. utcb_end_addr is aligned on UTCB_SIZE * 2. utcb_end is aligned on UTCB_SIZE
*/ */
if ((utcb_end_addr - utcb_start_addr) % UTCB_SIZE) { if ((utcb_end - utcb_start) % UTCB_SIZE) {
printf("libl4thread: the given range size must be multiple " printf("libl4thread: The given range size must be multiple "
"of the utcb size(%d)!\n", UTCB_SIZE); "of the utcb size(%d).\n", UTCB_SIZE);
return -EINVAL; return -EINVAL;
} }
/* Arguments passed the validity tests. */ /* Arguments passed the validity tests. */
/* Init utcb virtual address pool */ /* Init utcb virtual address pool */
utcb_pool_init(utcb_start_addr, utcb_end_addr); utcb_pool_init(utcb_start, utcb_end);
utcb_end_max_addr = utcb_end_addr; lib_utcb_end_addr = utcb_end;
/* The very first thread's utcb address is assigned. */ /* The very first thread's utcb address is assigned. */
if ((err = set_utcb_addr()) < 0) if ((err = set_utcb_addr()) < 0)