Files
codezero/conts/libl4thread/src/utcb-common.c
Bora Sahin 1256f1a13a The second step in creating a thread library.
UTCB support has beed added. It has the same drawback as in the stack support:
the area in question has to be already mapped-in.

There are also some minor fixes for the stack support and the utcb common helper
routines.
2009-11-13 15:21:15 +02:00

90 lines
1.9 KiB
C

/*
* UTCB management in Codezero
*
* Copyright © 2009 B Labs Ltd
*/
#include <stdio.h>
#include <addr.h>
#include <utcb-common.h>
#include <malloc/malloc.h>
/* Globally disjoint utcb virtual region pool */
static struct address_pool utcb_region_pool;
int utcb_pool_init(unsigned long utcb_start, unsigned long utcb_end)
{
int err;
/* Initialise the global utcb virtual address pool */
if ((err = address_pool_init(&utcb_region_pool,
utcb_start, utcb_end,
UTCB_SIZE) < 0)) {
printf("UTCB address pool initialisation failed.\n");
return err;
}
return 0;
}
static inline void *utcb_new_address(int npages)
{
return address_new(&utcb_region_pool, npages);
}
static inline int utcb_delete_address(void *utcb_address, int npages)
{
return address_del(&utcb_region_pool, utcb_address, npages);
}
/* Return an empty utcb slot in this descriptor */
unsigned long utcb_new_slot(struct utcb_desc *desc)
{
int slot;
if ((slot = id_new(desc->slots)) < 0)
return 0;
else
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;
}
struct utcb_desc *utcb_new_desc(void)
{
struct utcb_desc *d;
/* Allocate a new descriptor */
if (!(d = kzalloc(sizeof(*d))))
return 0;
link_init(&d->list);
/* We currently assume UTCB is smaller than PAGE_SIZE */
BUG_ON(UTCB_SIZE > PAGE_SIZE);
/* Initialise utcb slots */
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);
return d;
}
int utcb_delete_desc(struct utcb_desc *desc)
{
/* Return descriptor address */
utcb_delete_address((void *)desc->utcb_base, 1);
/* Free the descriptor */
kfree(desc);
return 0;
}